- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
It must be me, because BY DEFINITION the value of chars[strlen(chars)] is '\0'. That is how it is calculated.
I refer people to K&R 2 page 103 where an example implementation exists.
This is like saying "if (zero == 0) zero = 0;" In other words "why bother".
Admin
I made a Windows-like shell using TI-Basic on the 83+ once. The API could draw windows, buttons, text, and even had a working mouse! (no right-click though). This of course was back when I accepted that a screen refresh would naturally take 3-4 seconds, and moving the cursor took about 1/2 seconds if the screen did not need updating. Screen buffering FTW!
Admin
Admin
Note how even a single NUL byte write into heap can actually be exploitable for local privilege escalation against a suid binary: http://googleprojectzero.blogspot.fi/2014/08/the-poisoned-nul-byte-2014-edition.html
Scary stuff.
Admin
Ah yes, C++, that stellar example of clear syntax that will not, under any circumstances whatsoever, allow you to shoot yourself in the foot.
Other than that, I fail to see how the code in the article could ever overwrite memory it wasn't supposed to access.
Admin
Theoretically, the buffer could end up being next to a read-only page, and the assignment could write to read-only memory. It wouldn't do anything useful for an attacker unless it was a long-running server that didn't automatically start back up or whatever, but it's a problem they should fix. By deleting the code.
Admin
Admin
When I started programming with C++ I was truly afraid (I was 16 or so) that I would destroy my computer or the Palm Pilot. Maybe that's why I moved to VM languages :ferris_wheel:
Admin
Oh yes, and by the way, yesterday I got one of those stupid pink-orange popups from Discurse about posting style. It can fuck off.
Admin
What's that? I never heard of that one and so far I've only seen the multireply and the frequency toasters.
Admin
i'm guessing it was that one....
Admin
Body is invalid; try to be a little more descriptive
:question:
Admin
What
Admin
multi
Admin
reply?
Admin
Oh, that one.
Admin
Fixed.
Admin
Admin
what sort of implement would you like to borrow to help it do so? i have a variety to choose from, fresh from being sterilized in the autoclave.
Admin
My code-excising weapon of choice depends on the environment. On my personal Windows machine, that'd be Visual Studio 2010, while on a *NIX machine, I'd generally put my holy war stake on the side of Emacs.
Admin
i should probably nominate for a woosh...
that's not the sort of impliment that one uses for FXXK nor one that would require sterilization in an autoclave...
want to try again? ;-)
Admin
And because I don't bother reading it properly because it is being self-righteous and pompous.
So it can fuck off.
Admin
Minor whoosh I suppose. Besides, I had no intention of (...)ing it. I merely invited it to go forth and multiply.
Shrug, whatever.
Admin
oooooh. my misunderstanding then.
have fun with the GAU-8
if Ivan asks for COD tell him that you know it was already paid for, but tip him a 750ml beverage anyway (make sure it's at least 90 proof)
Admin
That doesn't make sense. The NUL character is part of the buffer. If you want to store "Hello" in a C string, you need a char array with 6 elements: one for each letter, and one for the NUL.
Admin
My favorite "shoot yourself in the foot" joke is not from programming but in reference to the old Infocom text adventures. ;-) It went something like this:
Admin
The behavior of strlen is not undefined. strlen is a function written in the C programming language, and the C standards define the C programming language, not specific functions written using the C programming language. strlen returns when it encounters a '\0' in the string argument. If there is no '\0' in the string, it will just keep going through memory, which may or may not trigger a segmentation fault.
For example:
int main() { char str[4]; int str_end = 0; char *str_test = "test"; memcpy(str, str_test, 4); printf("strlen(str) = %d\n", strlen(str)); return 0; }
Using gcc to compile (on intel architecture), will correctly return 4 as the string length because even thouigh str is not null terminated, the strlen function hits the first byte of the integer str_end on the stack. Since the first byte of str_end is 0, and ('\0' == 0), strlen returns a value that happens to be the correct length of the string str.
This statement doesn't make sense. Indexing has nothing to do with reading beyond an array's boundary; they are two entirely independent concepts. The worst that could happen is that strlen finds a 0-byte, then overwrites it with a 0. In the example above, the result is that the first byte of str_end, which is 0, will be replaced with the same value, 0:
int main() { char str[4]; int str_end = 0; char str_test = "test"; memcpy(str, str_test, 4); str[strlen(str)] = '\0'; / memory is written outside the bounds of the str array, but it is overwritten with the same value the memory held before being overwritten */ return 0; }
Getting back to the bigger picture, array boundaries in C only exist in the programmer's head. This is an important concept when programming in C.
This sort of article happens when Java programmers attempt to write an article about C, without understanding C. Sorry, you kind of set yourself up for it ;)
Admin
I read that word COMPLETELY wrong
Admin
what did you read it as?
hmm?
Admin
I'd have to respond in the Palm Pilot thread
Admin
:blush: oh.
OOH!
:-D
Admin
This invocation of strlen() causes it to read outside the allocated buffer, which is undefined. If your code example is compiled with optimization, the stack layout may change, and the returned length may not be 4. Segmentation faults may or may not happen.
The following is also undefined:
Admin
Ah.. the 'sex and travel' option...
Admin
http://youtu.be/PmakuC7OgIk?t=26s
Admin
I am not watching that video.
Admin
DO NOT WANT! [image]
Admin
I think the other picture you use more adequately captures the sentiment than this one does.
Admin
which other one? i use a lot.
Admin
The golden shepherd or whatever it is. It's got a much more horrified look.
Admin
I could quote other sections that actually define UB, but I don't have the energy right now.
Or maybe it isn't and your program crashed before then instead. Or produced wrong answers, because different live ranges of a not-address-taken variable got placed at different addresses, so `&x` in one location was `0x1234` and at another was `0x1232`, so your assumption that the value didn't change in the intervening time didn't hold. (I don't know that compilers actually do this, but I wouldn't be remotely surprised -- you'd almost have to specifically arrange to _not_ do that if you're going from SSA form -- but I'm pretty sure it would be totally legal in any case.) They're not the one who set themself up for it.Admin
What Every Programmer Should Know About Undefined Behavior: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html
A Guide To Undefined Behavior in C and C++ http://blog.regehr.org/archives/213 http://blog.regehr.org/archives/226 http://blog.regehr.org/archives/232
Admin
Considering that the hotlinked image is, itself, a thumbnail of the original, it could have been worse.
Admin
No, since you are just modifying the pointer. It would still be perfectly defined if you then did:
You are accessing at a point inside the allocated memory block; that the pointer points somewhere else doesn't matter.
It would matter if you did:
Don't do that unless you like nasal demons.
Admin
C draft standard, 6.5.6(8):
(Emphasis and deemphasis mine.)There are a number of reasons for this; one is that any object could potentially be set at the end of a memory space and that addition could overflow, and they left overflow behavior for pointers undefined (like signed integers but unlike unsigned integers, where overflow behavior is defined). It also makes legal implementations that check for valid pointer operations at the pointer arithmetic step instead of at the dereference step, though I don't know of any that take advantage of this behavior.
Practically speaking of course, the operation in question is quite unlikely to produce any adverse effects.
Admin
Yes, except that the compiler will usually start by optimising the code to (the equivalent of):
Assuming that
p
has no other uses later. ;)Anyone building a compiler where this is not the case in any memory addressing mode will get beaten up by an angry mob of programmers. We're talking true pitchforks-at-dead-of-night territory here.
Admin
I think this has more to do with hardware than compilers. On x86, there is a uniform memory model, in which every bit pattern of the correct width is a potential correct pointer value, and all memory can be seen as one contiguous unit.
On different platforms, different bit patterns may point to different types of memory, or may not be valid at all.
In @dkf's example, on some platform, the +30 may be done as a normal integer addition, and result in a bit pattern pointing to a different section of memory. The subsequent array indexing may use a special array indexing operation, which may use different semantics.
This would be possible on hardware where an array index caluclation only works on the last 8 bits of the pointer value.
Admin
I think that would not be a conforming C implementation. Suppose one had done
p = malloc(275);
instead? All that's changed is an argument to a function. (It's a built-in function, but it's still just a function.) Pointer arithmetic has got to work the way it is defined to, and that permits some fairly strong simplifications.If you're going to say that
malloc
can't allocate buffers that size, we're back to the pitchforks-at-midnight. Watch your back…Admin
Or that malloc would return a different kind of memory. Or the compiler would only use that array indexing instruction if it could verify it was safe in that case - that would not exclude my example because undefined behaviour was in play there.
Admin
malloc(20)
certainly could put the object 20 bytes (well, 21 bytes depend on what assumptions you make) from the last address in its segment. Doesn't mean thatmalloc(275)
couldn't work, it just means that it would have to put that at least 275/276 bytes from the end.