Hacker News new | ask | show | jobs
by zlynx 1865 days ago
I like to nitpick and point out gets() can be used safely, as a stunt.

Memory map a read/write page and after that memory map a no-permissions guard page. Now you can safely use gets() to read a page size string without allowing a buffer overflow.

3 comments

Does gets() guarantee that it will write its output in order? If not it could in theory write after your guard page before touching the guard page itself. Of course I don't know if either the kernel or glibc would ever do this.

I think the only safe way to use gets() is with trusted input.

Why does the order matter? It'll only write to the guard page if the input string is long enough to necessitate it, in which case it was going to fault anyway regardless of which page it touched first.

Edit: I guess you're considering "used safely" to include reading a truncated string, in which case writing in order would allow the program to be written such that it recovers from the fault and reads the valid page-worth of string.

I think the parent meant that if your string was longer than the size of the read/write page plus the size of the guard page, and if gets() is allowed to, say, write the string from the end to the beginning (I think this is unlikely, but let's say it could), then it would try to write the last character (first) all the way out beyond your guard page, possibly scribbling on some memory that the application had allocated for something else.
If it can write past the guard page, even if your program faults afterwards, it could have already compromised the larger system. Not claiming that it can, just entertaining the what-if.
You could hypothetically have a situation where libc has an arbitrarily large internal FILE* buffer (instead of reading a block, looking for a newline, and copying everything over immediately), and then copies in reverse, corrupting data after the guard page before it hits the guard page.

If there are other threads accessing data that happens to be placed after the guard page, bad things could happen, but this seems rather unlikely to be a real problem.

Ah, right. >2 pages-worth of input would break the scheme.
Or if you own both sides of stdin...
If we're nitpicking, doesn't this technically not still allow a buffer overflow, just negate the consequences of it?