More generally, people don’t participate in communities to have conversations with someone else’s chatbot, and especially not to have to vicariously read someone else’s own conversation with their own chatbot.
Not one of the actual downvoters, but:
Lack of proper indenting means your code as posted doesn't even compile. e.g. I presume there was a `char* p;` that had `*` removed as markdown.
Untested AI slop code is gross. You've got two snippets doing more or less the same thing in two different styles...
First one hand-copies strings character by character, has an incoherent explaination about what `pwbuf` actually is (comment says "root::", code actually has "root:k.:\n", but neither empty nor "k." are likely to be the hash that actually matches a password of 100 spaces plus `pwbuf` itself, which is presumably what `crypt(password)` would try to hash.)
Second one is a little less gross, but the hardcoded `known_hash` is again almost certainly incorrect... and if by some miracle it was accurate, the random unicode embedded would cause source file encoding to suddenly become critical to compiling as intended, plus the `\0`s written to `*p` mean su.c would hit the `return;` here before even attempting to check the hash, assuming you're piping the output of these programs to su:
while((*q = getchar()) != '\n')
if(*q++ == '\0')
return;
A preferrable alternative to random nonsensical system specific hardcoded hashes would be to simply call `crypt` yourself, although you might need a brute force loop as e.g. `crypt(password);` in the original would presumably overflow and need to self-referentially include the `pwbuf` and thus the hash. That gets messy...edit: if hash output length is variable it may be impossible to find a solution and then a side channel timing attack is probably the best option.
An initial analysis of the discovered Unix V4 tape
https://news.ycombinator.com/item?id=46367744
Unix v4 (1973) – Live Terminal
What compiler are you using?
Not the million line codebases we have today. 50-100 lines was the usual program or script.
So likely they would work on the printout:
1,$n
And then input the corrections into ed(1).Pretty advanced terminals were starting to show up too - https://en.wikipedia.org/wiki/VT100
# ... sound of crickets ...
Wanna see me do it again?
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.
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.
+ register int i;
q = password;
- while((*q = getchar()) != '\n')
+ i = 0;
+ while((*q = getchar()) != '\n') {
+ if (++i >= sizeof(password))
+ goto error;
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.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.
I missed the blurb about pointer arithmetic. Would be interesting to go into detail about what "had no effect" means.
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.
ttybuf[2] =& ~010;
Which is another bug.
mgerdts•18h ago
flatline•17h ago
oguz-ismail2•17h ago
formerly_proven•16h ago
Boltgolt•15h ago
jacquesm•12h ago
topspin•15h ago
There may have been a early C without structs (B had none,) but according to Ken Thompson, the addition of structs to C was an important change, and a reason why his third attempt rewrite UNIX from assembly to a portable language finally succeeded. Certainly by the time the recently recovered v4 tape was made, C had structs: