You don't actually need i here. i is the same as (q - password). It would be idiomatic C to simply rewrite the loop condition as: while (q < password+sizeof(password) && (*q = getchar()) != '\n'). To preserve your "goto error;" part, maybe you could do the overflow check when null terminating outside the loop.
Isn't sizeof only standardised in C89? Wouldn't shock me if this form needs to be an rvalue.
The author did try pointer arithmetic:
> I initially attempted a fix using pointer arithmetic, but the 1973 C compiler didn’t like it, while it didn’t refuse the syntax, the code had no effect.
The article specifically mentions this optimization as not working with the compiler at that time, hence the need for the separate index variable.
> We will edit su.c to prevent the overflow by maintaining a counter, i, and verifying it against the buffer size during the read loop. I initially attempted a fix using pointer arithmetic, but the 1973 C compiler didn’t like it, while it didn’t refuse the syntax, the code had no effect. I settled on a simpler index-based check instead.
I had to use ed once in a very limited recovery situation. I don't remember the details but even vi was not an option. It's not terrible if you just need to change a few lines. Using it on a teletype to write code all day would get tedious quickly. Full-screen editors had to have been an amazing productivity boost.
I think ed is still a great editor for specific tasks. As a plan 9/9front user, when you get yourself into trouble, it's sometimes the only editor you've got left (like when graphics doesn't initialize, which I've not seen on 9front — ever?)
It's really not bad, and you can use it for scripting like sed, but it's clunkier.
I had to use it when I installed 9front on a computer that has no graphics card just a serial port (APU2C2). I had only a serial device at 9600bps and the other text editors (sam, acme) didn't worked. I wanted to turn it into a CPU server so I can use drawterm to access it remotely and that requires editing a few files.
I’m guessing v4 C didn’t have structs yet (v6 C does, but struct members are actually in the global namespace and are basically just sugar for offset and a type cast; member access even worked on literals. That’s why structs from early unix APIs have prefixed member names, like st_mode.
Back in the 80s, when I was writing a C compiler, C compilers typically had a maximum size for string literals. The behavior was to detect overflow, issue an error message, and fail compilation.
I took a different tack. The buffer was allocated with malloc. When a string was larger, it was realloced to a larger size. This worked until memory was exhausted, and then the program quit.
It was actually less code to implement than having a fixed size buffer.
Ditto for the other compilation limits, such as length of a line. The only limit was running out of memory.
so, is there already somebody that wrote the exploit for it? are there any special things to consider exploiting such architecture back in the day or do the same basic principles apply?
The password and pwbuf arrays are declared one right after the other. Will they appear consecutive in memory, i.e. will you overwrite pwbuf when writing past password?
If so, could you type the same password that’s exactly 100 bytes twice and then hit enter to gain root? With only clobbering one additional byte, of ttybuf?
Edit: no, silly, password is overwritten with its hash before the comparison.
> will you overwrite pwbuf when writing past password?
Right.
> If so, could you type the same password that’s exactly 100 bytes twice and then hit enter to gain root? With only clobbering one additional byte, of ttybuf?
Almost. You need to type crypt(password) in the part that overflows to pwbuf.
ChrisArchitect|1 month ago
An initial analysis of the discovered Unix V4 tape
https://news.ycombinator.com/item?id=46367744
Unix v4 (1973) – Live Terminal
https://news.ycombinator.com/item?id=46468283
asveikau|1 month ago
shakna|1 month ago
The author did try pointer arithmetic:
> I initially attempted a fix using pointer arithmetic, but the 1973 C compiler didn’t like it, while it didn’t refuse the syntax, the code had no effect.
VonTum|1 month ago
> We will edit su.c to prevent the overflow by maintaining a counter, i, and verifying it against the buffer size during the read loop. I initially attempted a fix using pointer arithmetic, but the 1973 C compiler didn’t like it, while it didn’t refuse the syntax, the code had no effect. I settled on a simpler index-based check instead.
SoftTalker|1 month ago
fooker|1 month ago
Not the million line codebases we have today. 50-100 lines was the usual program or script.
b00ty4breakfast|1 month ago
unknown|1 month ago
[deleted]
butterisgood|1 month ago
It's really not bad, and you can use it for scripting like sed, but it's clunkier.
irusensei|1 month ago
mgerdts|1 month ago
oguz-ismail2|1 month ago
formerly_proven|1 month ago
flatline|1 month ago
WalterBright|1 month ago
I took a different tack. The buffer was allocated with malloc. When a string was larger, it was realloced to a larger size. This worked until memory was exhausted, and then the program quit.
It was actually less code to implement than having a fixed size buffer.
Ditto for the other compilation limits, such as length of a line. The only limit was running out of memory.
b-kuiper|1 month ago
MajesticHobo2|1 month ago
b-kuiper|1 month ago
w-m|1 month ago
If so, could you type the same password that’s exactly 100 bytes twice and then hit enter to gain root? With only clobbering one additional byte, of ttybuf?
Edit: no, silly, password is overwritten with its hash before the comparison.
loeg|1 month ago
Right.
> If so, could you type the same password that’s exactly 100 bytes twice and then hit enter to gain root? With only clobbering one additional byte, of ttybuf?
Almost. You need to type crypt(password) in the part that overflows to pwbuf.
nineteen999|1 month ago
retrac|1 month ago
What compiler are you using?
nullpoint420|1 month ago
WalterBright|1 month ago
serpent|1 month ago
unknown|1 month ago
[deleted]
emilfihlman|1 month ago
ttybuf[2] =& ~010;
Which is another bug.
messe|1 month ago
kazinator|1 month ago
# ... sound of crickets ...
Wanna see me do it again?
nineteen999|1 month ago