Slashdot Mirror


New Hack Exploits Common Programming Error

buzzardsbay writes "TechTarget's security editor, Dennis Fisher is reporting that researchers at Watchfire Inc. have discovered a reliable method for exploiting a common programming error, which until now had been considered simply a quality problem and not a security vulnerability. According to the article, the researchers stumbled upon the method for remotely exploiting dangling pointers by chance while they were running the company's AppScan software against a Web server. The good folks at Watchfire will detail the technique in a presentation at the Black Hat Briefings in Las Vegas in August, Fisher writes."

255 comments

  1. Well duhhhh. by pushf+popf · · Score: 5, Funny

    Who would have thought that invalid pointers and buffer overruns might be exploitable as a security hole?

    Quick, someone alert Bill Gates!

    1. Re:Well duhhhh. by Anonymous Coward · · Score: 1, Interesting

      well duh yourself... none of the smart minds looking at this, obviously a lot more retarded than you are, thought it was possible to do this for years.

      But I guess you have no clue about programming and what dangling pointers really are, and you're just replying cause it's slashdot..

    2. Re:Well duhhhh. by pushf+popf · · Score: 1, Flamebait
      This just in:
      • The earth isn't flat
      • Fire is hot
      • Poorly written software is exploitable
      I've been writing software since "high level language" meant that the assembler understood named labels. Poorly written software had exploitable pointers back then too.

      This is just as newsworthy as the discovery that bears crap in the woods.
    3. Re:Well duhhhh. by Anonymous Coward · · Score: 1, Informative

      Nobody said it couldn't be exploited before this. It's been known for quite a while that this is an exploitable problem. The point is that it can now be predictably exploited.

      If you actually knew what you were talking about, however, I wouldn't have had to tell you that.

    4. Re:Well duhhhh. by Opportunist · · Score: 0, Flamebait

      Quick, someone alert Bill Gates!

      Could be a good idea. He might be the last IT guy who doesn't know yet, judging from his software...

      --
      We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
    5. Re:Well duhhhh. by abradsn · · Score: 3, Insightful

      Hmm, actually there are entire languages that have built in features to avoid this problem. It is indeed a known problem, and it is indeed very old. Whoever wrote the article saying that this was new as a security issue, is quite misinformed. Actually, since they are writing an article, that makes them an idiot too. Too many journalist idiots out there that don't ask more than 1 person a question before taking it at down as factual. I don't know any programmer that would have said, "Oh, dangling pointers, memory leaks, and bad code... those aren't security problems." Unless of course, they are joking.

    6. Re:Well duhhhh. by Anonymous Coward · · Score: 0

      The comments are full of idiots and sophists. You are one of them. The article does *not* tread new ground. On what basis do you think that we have not been able to reliably exploit broken code before until now?

      Please step aside, can the hyperbole, and let people who know what they're talking about speak. Don't pollute the forum with your garbage.

  2. That's nice and everything but.... by Anonymous Coward · · Score: 1, Interesting
    ...The problem before was, you had to override the exact location that the pointer was pointing to. It was considered impossible. But we discovered a way to do this with generic dangling pointers and run our own shell code."

    OK, you load the code into memory with the dangling pointer, now, how to you get the instruction pointer to go and execute said code?

    1. Re:That's nice and everything but.... by Wavicle · · Score: 5, Insightful

      Presumably what they have here is a dangling pointer to a function, which they can get IIS to then call. They state that this used to be a "denial of service" attack - meaning that if IIS attempted the call before, it would execute garbage and cause a runtime fault. Now, however, they can change the value of the dangling pointer and when IIS does the jump this time, it executes their exploit code instead.

      --
      Education is a better safeguard of liberty than a standing army.
      Edward Everett (1794 - 1865)
    2. Re:That's nice and everything but.... by mark-t · · Score: 4, Insightful

      But wouldn't said exploit code need to reside in a part of memory that the operating system had previously allocated for executable instructions? I mean I can understand how you could potentially make code that was already part of the program execute without the intention of the programmer, but how do you make code that isn't part of the executable in the first place execute? I mean sure you can put the opcodes for particular instructions into data space, but if you try to branch there, why would the OS even allow that unless the area the program uses for data is also marked as an area where executable instructions can be?

    3. Re:That's nice and everything but.... by Anonymous Coward · · Score: 0

      sudo do_bad_things

    4. Re:That's nice and everything but.... by TheRaven64 · · Score: 4, Informative

      The OS has very little to do with it. It's the hardware, specifically the MMU, which will do this checking. If you are using something like OpenBSD, then it will not let a page be both executable and writeable at the same time, but that requires doing some messy things with segments on x86 (unless you have a new chip with page-level execute permissions). On most x86 hardware, if memory is readable, it is executable, and anything you allocate with malloc() and friends will have read/write/execute permissions.

      --
      I am TheRaven on Soylent News
    5. Re:That's nice and everything but.... by jgrahn · · Score: 1

      Presumably what they have here is a dangling pointer to a function, which they can get IIS to then call.

      I doubt it. How the heck do you get a dangling function pointer in C or C++? You never malloc() or operator new() functions, unless you fancy self-modifying code.

      They state that this used to be a "denial of service" attack - meaning that if IIS attempted the call before, it would execute garbage and cause a runtime fault. Now, however, they can change the value of the dangling pointer and when IIS does the jump this time, it executes their exploit code instead.

      "Changing the value of the dangling pointer" doesn't make sense -- the whole point of using the name "dangling pointer" is to imply that the program (a) has a pointer to freed memory (heap or stack) and (b) is buggy, i.e. can be tricked into dereferencing it. If the pointer can be changed by the attacker, it doesn't have to be dangling to be vulnerable.

      One good guess is they're talking about C++ and dangling pointers to objects with vtables -- if you can overwrite that memory with something interesting, you own the program counter.

    6. Re:That's nice and everything but.... by Wavicle · · Score: 2, Insightful

      How the heck do you get a dangling function pointer in C or C++? You never malloc() or operator new() functions, unless you fancy self-modifying code.

      Oh fine, be pedantic about it. Put the pointer in a struct and maintain a dangling pointer to the struct. All pointers within the struct are now dangling as well, including function pointers. An attacker can then (theoretically) change the value of the function pointer. This is the C equivalent of the C++ attack you describe. If someone attempts to call the function based off the dangling struct pointer, the exploit succeeds.

      --
      Education is a better safeguard of liberty than a standing army.
      Edward Everett (1794 - 1865)
    7. Re:That's nice and everything but.... by TropicalCoder · · Score: 4, Informative

      Now, however, they can change the value of the dangling pointer and when IIS does the jump this time, it executes their exploit code instead.

      They are not saying they "change the value of the dangling pointer".

      From the FA: "The problem before was, you had to override the exact location that the pointer was pointing to. It was considered impossible. But we discovered a way... The long and short of it is, if you can determine the value of the pointer, it's game over."

      There are theoretically two ways to exploit a dangling pointer - change the address that it points to (which they don't do), or discover the address it is pointing to, and put some code there (considered impossible). Most likely, it is pointing to memory space within the program that once held valid executable code. They say this "was considered impossible, but we discovered a way". So I suspect they just stuck a jump instruction at the location the pointer was pointing to instead of trying to cram executable code into an unknown sized space. The jump would of course be to some space they allocated, with a known size, big enough to hold their exploit. Determining the value of the dangling pointer would be easy enough - you would get a message when it crashed that the app tried to access invalid memory at addr: 0x????????. Just stick a jump at that location - then get a big warm hug from Microsoft when you show them how you did it.

    8. Re:That's nice and everything but.... by Wavicle · · Score: 1

      Hmmm, interesting. So in this case, they are writing to memory of executable code that has been freed. It's interesting that this exploit requires some sort of dynamically loaded, and freed, executable code. It's too bad they didn't give us more details, I'm now curious about the sequence of actions that must be followed to allow this to happen.

      --
      Education is a better safeguard of liberty than a standing army.
      Edward Everett (1794 - 1865)
    9. Re:That's nice and everything but.... by lgw · · Score: 2, Informative

      Various version of Window support DEP (Data Execution Protection?), and for Server 2003 with the lastest SP, I believe all of Windows itself runs under DEP. You have the option to enforce DEP on all running software, but chances are something you need will break. I don't know if it's possible to enforce DEP on some application and not others.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    10. Re:That's nice and everything but.... by lgw · · Score: 3, Interesting

      I betting it's the C++ vtables exploit suggested by the previous thread. If you have a C++ class with a virtual function, the freed memory has a pointer to a table of pointers to executable code. Changing that vtable pointer to point to a malicious vtable might work.

      I'm not sure why that would work better with dangling pointer than pointers to live code, however - how do you change the memory that the pointer points to without already having access? Presumably that's what these guys discovered: a way to get a buffer allocated and filled with user data at the spot the dangling pointer points.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    11. Re:That's nice and everything but.... by SteveAyre · · Score: 3, Informative

      But that's actually Windows supporting the NX bit on certain recent CPUs. It *needs* hardware support to work properly.

      There is a software substitute which takes effect in case your CPU doesn't support the NX bit, but that only prevents some attacks and *won't* stop execution of code in data pages.

    12. Re:That's nice and everything but.... by SteveAyre · · Score: 2, Informative

      I don't know if it's possible to enforce DEP on some application and not others.

      And the answer is yes, it is possible. Windows runs DEP in either an Always-on, Always-off, Opt-in or Opt-out modes. Opt-out lets you enable DEP by default and then override it for specific programs which break, and Opt-in lets you disable it by default and then enable it for specific programs which'll benefit such as a web server.

    13. Re:That's nice and everything but.... by tricorn · · Score: 3, Informative

      Well, no - a dangling pointer implies two different pointers referencing the same memory area. Since many objects have pointers to other objects, if you can change one object by modifying fields through the other pointer (either the dangling pointer or the memory area doubly referenced), you can change one of those object pointers to point to a location on the stack; then using common buffer overflow techniques, you can put code on the stack and modify a return address to point to that code.

      I wouldn't say such an approach can ALWAYS be used to compromise a machine, but it is much more generic than the (also quite possible) C++ (and similar language) specific method using pointers to vtables and such.

      I've always assumed that if you can get a program to crash, you can probably get it to execute arbitrary code. One way of avoiding such techniques (other than writing correct code) is to use hardware support. The No-Execute page flag is one good start; having separate control-flow and data stacks would be another (where the control-flow stack would only be accessible through special instructions). Randomizing the location of the stack and the heap, and possibly make the memory allocation routine be less optimal and more random would also help a lot. Having a tagged memory architecture would be helpful as well (pointers to code could ONLY be manipulated through special instructions, and trying to load the wrong type of memory would cause a hardware exception).

    14. Re:That's nice and everything but.... by TropicalCoder · · Score: 1

      Well, no - a dangling pointer implies two different pointers referencing the same memory area.

      Well, not according to Wikipedia, who says...

      Dangling pointers arise when an object is deleted or deallocated, without modifying the value of the pointer, so that the pointer still points to the memory location of the deallocated memory. As the system may reallocate the previously freed memory to another process, if the original program then dereferences the (now) dangling pointer, unpredictable behavior may result, as the memory may now contain completely different data. This is especially the case if the program writes data to memory pointed by a dangling pointer, as silent corruption of unrelated data may result, leading to subtle bugs that can be extremely difficult to find, or cause segmentation faults (*NIX) or general protection faults (Windows). If the overwritten data is bookkeeping data used by the system's memory allocator, the corruption can cause system instabilities.

      However, although I and others suggest doing magic things with certain areas of memory without stating how one is supposed to do that, you require not only magic ("if you can change one object by modifying fields through the other pointer"), but also combining the original flaw with a buffer overflow. In the end, I don't think any of us are even close. We just don't have enough information. Perhaps if we experimented with the application, in time we could figure it out. ...but would it be worth the effort?

    15. Re:That's nice and everything but.... by baadger · · Score: 1

      Is it at all possible their attack involves tricking the application into allocating lots of data (by issuing lots of requests, a bit like a carefully planned denial of service) and then relying on the memory allocator to *reallocate* an area of memory previous used for executable code to which a dangling pointer refers?

      I don't know whether the general malloc/platform allocators would do this but an application that gets a big ol chunk of RAM using weak memory protection and implements it's own tuned allocator might do so.

    16. Re:That's nice and everything but.... by Anonymous Coward · · Score: 0

      There are theoretically two ways to exploit a dangling pointer - change the address that it points to (which they don't do),

      If you change the address that it points to, it doesn't matter whether or not the pointer was dangling.
    17. Re:That's nice and everything but.... by jhol13 · · Score: 1

      Even in case you are right (see the other posts), it does not matter so much. Calling existing functions with self made parameters can be very dangerous - think about accessing e.g. a database.

    18. Re:That's nice and everything but.... by Nurf · · Score: 1

      One way of avoiding such techniques (other than writing correct code) is to use hardware support. The No-Execute page flag is one good start; having separate control-flow and data stacks would be another (where the control-flow stack would only be accessible through special instructions). Randomizing the location of the stack and the heap, and possibly make the memory allocation routine be less optimal and more random would also help a lot. Having a tagged memory architecture would be helpful as well (pointers to code could ONLY be manipulated through special instructions, and trying to load the wrong type of memory would cause a hardware exception).

      We've been trying to push some hardware improvements for x86 that would make these kinds of attacks much more difficult. We aren't using a tagged memory architecture. The really hard part is making it backward compatible. Have a look at http://labyrinthcpu.com/ if you are interested, and follow the link to the standard. We are always looking for feedback from knowledgeable people. The idea is to be very open about the implementation and try to get feedback before we make a big push to get it into an x86 CPU (Heh. Wish us luck with that. :-P :-) ).

      --
      ---
    19. Re:That's nice and everything but.... by mgiuca · · Score: 1

      Back in the old days of segmentation, x86 offered the NX bit on segments which let the operating system prevent execution. However all major OSes switched to the paged model ages ago which has no equivalent protection, until recently, newer chips have started having these "DEP" (Data Execution Prevention) features. As far as I can tell this is just the same thing as the NX bit from 20 years ago, but for paging.

      Anyway it isn't in heavy use at the moment, so it's entirely possible to put x86 code in data and have the IP point to it and execute it.

      But that's OK, students don't need to learn assembly these days.

    20. Re:That's nice and everything but.... by tricorn · · Score: 1

      Um, that Wikipedia description is correct. It is also saying the same thing I am. You have one pointer pointing to memory. That memory then gets assigned to another object. Modifying that second object can then modify the object that is supposedly no longer there (pointed to by the dangling pointer) OR modifying the object pointed to by the dangling pointer will change the object that has been allocated on top of it. If you DON'T have two different pointers pointing to the same memory, then the fact that it is a dangling pointer does no harm (note that something may have pointed to it, modified it, then have been deallocated, and the "different pointer" may also be an internal pointer used by the memory allocation routines, but that is not as likely; debugging techniques such as heap scrambling to specifically find such errors can also modify the dangling object).

      I didn't say you have to "combine it with a buffer overflow"; I said that changing an object pointer in one or the other object to be on the stack with a relevant field now mapped onto a return address would allow you to change the return address using techniques similar to buffer overflow attacks - e.g. using a carefully designed string to contain executable code and point the return pointer to jump to that location on the stack. Modifying a pointer to an object that contains a large string so that the object is on top of the stack is one way to do this, then (using the original object that contains the pointer) loading that string with some content you can supply, is one way to do this.

      Changing one object by modifying another object is the very essence of what happens when you have a dangling pointer. Usually it just screws everything up, leading to "impossible" results ("but all references to X are checked to make sure it could never have that value!"), but if you know which two objects are overlapping, you can usually do interesting things with it. And you don't need magic.

    21. Re:That's nice and everything but.... by mark-t · · Score: 1

      I'm not saying it's not possible for the hardware to do it, I'm saying it should be possible for the operating system to tell the hardware to prevent it.

    22. Re:That's nice and everything but.... by bogado · · Score: 1
      Every object has a pointer to the vtable, if you could overwrite the position that a dangling pointer is pointed to you can overwrite the position of the vtable (probably to the same place where you are writing now) and put a pointer to the code you want to be called.

      normal operation :

      [pointer] => [ [vtable] objdata ]
                        ||
                        \/
                  [ vtable data ] => [ Obj. method ]
      hacked :

      [pointer] => [ [new vtable] => [hack vtable] => [ hacked method ] ]
      --
      []'s Victor Bogado da Silva Lins

      ^[:wq

    23. Re:That's nice and everything but.... by lgw · · Score: 1

      Useful information, thanks. I think I'll try the Opt-out setting at home, and see how many of the programs I regularly run will work under DEP.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    24. Re:That's nice and everything but.... by DieNadel · · Score: 1

      This would be very interesting to see. Could you please post back what applications didn't work while executing under DEP W^X?

      --
      Utinam logica falsa tuam philosophiam totam suffodiant!
    25. Re:That's nice and everything but.... by mgiuca · · Score: 1

      But the problem is, it isn't possible for the OS to tell the hardware, unless the hardware has DEP built in.

  3. All the trouble in this world.. by WarwickRyan · · Score: 4, Funny

    ..is down to dangly bits.

    1. Re:All the trouble in this world.. by Herkum01 · · Score: 2, Funny

      That is why I use button fly, much harder for dangling bits to expose themselves.

    2. Re:All the trouble in this world.. by reddburn · · Score: 1

      Not to mention making it harder to catch said dangly bits in a zipper... You may all wince and turn from the screen.

      --
      "Those who believe in telekinetics, raise my hand" - Kurt Vonnegut, Jr.
    3. Re:All the trouble in this world.. by Opportunist · · Score: 2, Funny

      Will people never learn? Security by obscurity doesn't work!

      --
      We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
  4. Has Apache fixed it? by Anonymous Coward · · Score: 1

    Microsoft seems to have fixed it in IIS and pushed the patch out already. I wonder how many of these Apache has exposed...?

    1. Re:Has Apache fixed it? by WhiplashII · · Score: 1

      Since it was previously considered a "quality issue" but not a security one, I would expect that Apache fixed these errors long ago. At Microsoft, a quality issue is an unaddressed issue - crashes were seen as "avoid when convenient" instead of as a failing. To open source programmers, however, their own pay is kudos on clean code - so they fix things that aren't technically even errors, but instead are quality issues...

      --
      while (sig==sig) sig=!sig;
  5. I'm telling my mother! by east+coast · · Score: 4, Funny

    Enough with all of this talk of "dangling pointers" you perverts.

    --
    Dedicated Cthulhu Cultist since 4523 BC.
    1. Re:I'm telling my mother! by fbjon · · Score: 3, Funny

      Does "damp security holes" sound better?

      --
      True confidence comes not from realising you are as good as your peers, but that your peers are as bad as you are.
    2. Re:I'm telling my mother! by Opportunist · · Score: 1

      Dangling pointers and security holes

      Film at 11 (rated NC-17)

      --
      We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
    3. Re:I'm telling my mother! by Anonymous Coward · · Score: 1, Funny

      I'd like to know how to penetrate that box, security must be tight...

    4. Re:I'm telling my mother! by Anonymous Coward · · Score: 0

      No need. Your mother knows all about my exploits.

    5. Re:I'm telling my mother! by Vintermann · · Score: 2, Funny

      Security by obscenity doesn't work!

      --
      xkcd is not in the sudoers file. This incident will be reported.
  6. The cure... by Anonymous Coward · · Score: 5, Funny

    I found that if I stop programming every 15 minutes or so and look up some pr0n, I significantly reduced my chances of having a "dangling pointer."

    1. Re:The cure... by Anonymous Coward · · Score: 0

      xxxxxxxxxxxxxxxxx

      PLEASE STOP

      USING THAT

      TO POINT!

      xxxxxxxxxxxxxxxxx

    2. Re:The cure... by Anonymous Coward · · Score: 0

      I found that if I stop programming every 15 minutes or so and look up some pr0n, I significantly reduced my chances of having a "dangling pointer."
      Sure, but this guarantees a race condition.
  7. Pleasantly surprised! by Gazzonyx · · Score: 1
    I was sure that I'd have to read about why

    char * foo
    is a Bad Idea. The fact that I got to see that forgetting to deallocate memory was uniquely refreshing, like the spring mist in Brooklyn.


    However, I thought that the compiler took care of destroying pointers when variables went out of scope? Aren't destructors implicit clean up calls? I'm fairly sure that Borland 16-bit Turbo C++ did this, back in the day.

    --

    If I mod you up, it doesn't necessarily mean I agree with what you've said, sorry.

    1. Re:Pleasantly surprised! by Wavicle · · Score: 5, Interesting

      Yes and no. The pointer in question may have a lifetime greater than that of the object being pointed to. Example:


      void (*myFuncPtr)() = NULL;

      void cleanUp() {
          item listItem = firstItem;

          while ( listItem != NULL ) {

              myFuncPtr = listItem->fcn;
              myFuncPtr();

              tempItem = listItem->next;
              free(listItem);
              listItem = tempItem;
          }
      } // myFuncPtr is now dangling!


      A little contrived, sure, but it is an example of how a pointer might get left dangling.

      --
      Education is a better safeguard of liberty than a standing army.
      Edward Everett (1794 - 1865)
    2. Re:Pleasantly surprised! by 19thNervousBreakdown · · Score: 1

      Now all you need to do is be a real fool and try to call that dangling pointer.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    3. Re:Pleasantly surprised! by Anonymous Coward · · Score: 1, Interesting

      Destroying a pointer isn't the same as destroying the object-pointed-to.

      C++ gives you a lot of choices, and thus lots of ways to shoot yourself in the foot if you don't understand those choices and make the correct ones.

      The backwards-compatible C-style "dumb" pointers don't do any reference counting, so there's no way for a heap object to know that it's no longer needed. There are other tools to do this job (auto_ptr and others) if that's what you want and need. And you could add GC to your C++ system if you want, though that still leaves you a window of vulnerability between end-of-life and actual cleanup. (Few heap management libraries zero out freed memory, so pointers inside deallocated objects can still be read; they may or may not point to still-valid objects. Even if these internal pointers are not "dangling", they're still a security hole if you hand them to other malicious code in the same address space.)

    4. Re:Pleasantly surprised! by morgan_greywolf · · Score: 1

      However, I thought that the compiler took care of destroying pointers when variables went out of scope? Aren't destructors implicit clean up calls? I'm fairly sure that Borland 16-bit Turbo C++ did this, back in the day.


      Um, no. AFAIK, C++ has no implicit garbage collection. There are plenty of libraries that do garbage collection...most are essentially replacements for malloc.

      But anyway, this is about dangling pointers -- pointers that point to essentially nothing (really, to some 'random' address), either before or after use, not necessarily pointers that haven't been destroyed.

    5. Re:Pleasantly surprised! by TheRaven64 · · Score: 3, Insightful

      And this is where the principle of smallest scope comes into play. myFuncPtr, in your example, has no business being global, it should be declared inside the while loop so it is invalid whenever it contains invalid data. If you need it to be available outside of this block, then you make sure that everything that modifies the pointer also checks that it is valid, and is responsible for ensuring that the lifespan of the pointed object is greater than that of the pointer. Use reference counting if you don't have proper garbage collection.

      --
      I am TheRaven on Soylent News
    6. Re:Pleasantly surprised! by aldousd666 · · Score: 1

      I don't think the poster was implying garbage collection, but rather the implicit calling of destructors, which does happen indeed. But the poster was failing to understand the the issue is with another object referring to the address of one that has been possibly destructed or otherwise become invalid. So you're right, just not addressing the concern of the GP.

      --
      Speak for yourself.
    7. Re:Pleasantly surprised! by quanticle · · Score: 1

      And again, that's a code quality issue, much like validating input was for buffer overflows.

      --
      We all know what to do, but we don't know how to get re-elected once we have done it
    8. Re:Pleasantly surprised! by Anonymous Coward · · Score: 0

      No, it is not. myFuncPtr points to (as the name suggests) _code_ and in the posted example that part of memory, where this code resides, was not released.

    9. Re:Pleasantly surprised! by HTH+NE1 · · Score: 1

      That's part of the premise: they found a dangling pointer by the fact that the code crashed. So they know one exists, and have now found an easy way to exploit it reliably as a class of vulnerabilities.

      --
      Oh, say does that Star-Spangled Banner entwine / The myrtle of Venus with Bacchus's vine?
    10. Re:Pleasantly surprised! by Wavicle · · Score: 1

      You are technically correct. Closer reading of the article (suggested from another thread) reveals though that this may not be too far from what actually happens. It appears they are able to exploit a dangling pointer to dynamically loaded code that has since been freed. So myFuncPtr may yet be exploitable. But the theory of the example was flawed.

      --
      Education is a better safeguard of liberty than a standing army.
      Edward Everett (1794 - 1865)
  8. More push toward VM's by jshriverWVU · · Score: 1
    Allan pointed out that Java-based applications are not vulnerable to this exploit because the language has a built-in mechanism for deallocating memory.

    I can see this as fodder for the argument that it's safer to run software in sandbox like Java's VM.

    1. Re:More push toward VM's by ThinkingInBinary · · Score: 3, Insightful

      I can see this as fodder for the argument that it's safer to run software in sandbox like Java's VM.

      Um, it is fodder for that argument -- environments where memory management is handled automatically mean the programmer has one less thing to screw up. Even if you consider that the VM implementations may have errors, there are far fewer VM implementations than there are pieces of software that can run on them, so it's easier to debug a good memory manager/garbage collector for each VM than to debug the manual memory allocation and freeing in each application.

    2. Re:More push toward VM's by someone1234 · · Score: 1

      Well, this argument is not new. The counter argument is that the garbage collector still lets you eat up memory and causes lots of problems because of delayed destructors. Catching unfreed memory, overruns or uninitialised pointers is easy with Valgrind. (Eww, not on Windows, but well, cross platform development ftw).

      --
      Patents Drive Free Software as Hurricanes Drive Construction Industry
    3. Re:More push toward VM's by 19thNervousBreakdown · · Score: 5, Insightful

      Garbage collected languages is no solution to poor programming. If you can't remember to not call a function pointer that you just freed, you'll probably forget to close /etc/passwd before dropping privs, or something equally stupid.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    4. Re:More push toward VM's by BitchKapoor · · Score: 1

      Garbage collected languages is no solution to poor programming. If you can't remember to not call a function pointer that you just freed, you'll probably forget to close /etc/passwd before dropping privs, or something equally stupid.

      And you could encode that kind of stuff in accessors which follow security policies, rather than directly hard coding the access and the policy every time. For example, this is why we separate code into separate processes owned by different users rather than throwing everything in the kernel. It's not an all-or-nothing thing: the more bugs you can prevent, the better. Even people who know what they're doing make mistakes from time to time. One of the biggest sources of mistakes is when you combine two different pieces of code that seemed to work correctly on their own, but don't quite realize some of the undocumented subtlties in their behaviors, and thus the two interfere and cause an error.

    5. Re:More push toward VM's by 19thNervousBreakdown · · Score: 1

      Well, if you're the type that can think of putting access to /etc/passwd into, say, an object that's destroyed just before dropping root, then you can probably think of a way to prevent yourself from calling dangling pointers too. And if you unit test properly, and avoid side-effects, you'll save a whole lot of trouble when you go to integrate, too.

      It's just people being lazy, hurried, or in some unfortunate cases, stupid.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    6. Re:More push toward VM's by BitchKapoor · · Score: 2, Insightful

      Well, if you're the type that can think of putting access to /etc/passwd into, say, an object that's destroyed just before dropping root, then you can probably think of a way to prevent yourself from calling dangling pointers too. And if you unit test properly, and avoid side-effects, you'll save a whole lot of trouble when you go to integrate, too.

      It's just people being lazy, hurried, or in some unfortunate cases, stupid.

      Yes, which is why your architects and best developers create a platform on which the rest of your developers can relatively easily instantiate individual solutions. There's more than one programmer working on any sizeable project.

    7. Re:More push toward VM's by 19thNervousBreakdown · · Score: 1

      Man. We can dream, anyway.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    8. Re:More push toward VM's by DragonWriter · · Score: 1

      Garbage collected languages is no solution to poor programming.


      Eliminating the possibility of an entire class of bugs reduces the number of things that need to be remembered in putting the code together (and checked once it is coded), and therefore reduce the number of bugs (and exploitable vulnerabilities) that get through to end user code.
    9. Re:More push toward VM's by 19thNervousBreakdown · · Score: 1

      Eliminating a class of bugs is a great thing, but GC doesn't do it. Instead of memory leaks, you have object leaks. People start to trust the GC too much, and it takes away more control than it's worth. That's just a personal preference, of course, and I'll write GC code, but since I don't like it I'll take a 10% lower salary if I don't have to deal with it.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    10. Re:More push toward VM's by MemoryDragon · · Score: 1

      Actually memory issues are not really that much in java, but catching them once being done is hard, you basically have to compare time snapshots of the heap to find out the affecting memory leak area, and this is something which is rather nasty. Of course such errors do not occur very often, but lousy programmers even manage to produce mem leaks in an enviroment which has weak and soft references and well working garbage collectors.

    11. Re:More push toward VM's by The+One+and+Only · · Score: 2, Insightful

      Well, if you're the type that can think of putting access to /etc/passwd into, say, an object that's destroyed just before dropping root, then you can probably think of a way to prevent yourself from calling dangling pointers too.

      Can you do both at the same time, while dealing with dozens of other headaches? Do you really want to? There's something to be said for reducing the programmer's mental workload so he can more efficiently think about the problem he's supposed to solve. Of course, making it more difficult does make it easier for more talented programmers to find work since less talented programmers would be forced out of the profession...

      --
      In Repressive Burma, it's not just your connection that dies. slashdot.org/comments.pl?sid=314547&cid=20819199
    12. Re:More push toward VM's by sfjoe · · Score: 1

      Object leaks? You really don't have any idea what you're talking about do you?

      --
      It's simple: I demand prosecution for torture.
    13. Re:More push toward VM's by 19thNervousBreakdown · · Score: 1

      Waaaait... is this 1967? No? Shit!

      You caught me. I have no idea what I'm talking about. *waves hand*

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    14. Re:More push toward VM's by psmears · · Score: 1

      Object leaks? You really don't have any idea what you're talking about do you? Are you sure?
    15. Re:More push toward VM's by kaffiene · · Score: 1

      I can't believe that you were modded insightful for that.

      Fact: programmers make mistakes.

      Fact: systems that protect against programmer mistakes have less mistakes in them.

    16. Re:More push toward VM's by DragonWriter · · Score: 1

      Eliminating a class of bugs is a great thing, but GC doesn't do it.


      Yes, it does. As you admit in the next sentence.

      Instead of memory leaks, you have object leaks.


      Which is a completely different problem, even if it can be produced by overlooking the same type of things. And while it may create performance problems, it is less likely to create remotely exploitable vulnerabilities.

      People start to trust the GC too much, and it takes away more control than it's worth.


      SUre, anything that makes things easier in most cases can be a source of overreliance that makes the edge cases where it doesn't relieve the need for attention. But most modern GCs don't take away that much control. You may lose control by choosing not to worry and to just trust the GC, but I suspect that most people that do that do so because they work in environments where, overall, it is worth it.
    17. Re:More push toward VM's by HomelessInLaJolla · · Score: 1

      It's just people being lazy, hurried, or in some unfortunate cases, stupid. We have the most fun hurrying people and then spreading the word that they're stupid. Works every time.
      --
      the NPG electrode was replaced with carbon blac
    18. Re:More push toward VM's by Vintermann · · Score: 1

      > Catching unfreed memory, overruns or uninitialised pointers is easy with Valgrind.

      Through the execution paths you follow, yes. But it's in the unusual execution paths (those involving exceptions especially) that the problem really lies.

      --
      xkcd is not in the sudoers file. This incident will be reported.
    19. Re:More push toward VM's by smellotron · · Score: 1

      Well, if you're the type that can think of putting access to /etc/passwd into, say, an object that's destroyed just before dropping root, then you can probably think of a way to prevent yourself from calling dangling pointers too.
      Can you do both at the same time, while dealing with dozens of other headaches? Do you really want to? There's something to be said for reducing the programmer's mental workload so he can more efficiently think about the problem he's supposed to solve.

      The grandparent is referring to the idiom Resource Acquisition Is Initialization, which is common in C++ (and other languages with deterministic destruction) for helping a programmer to manage resources without having to think too hard about it. The cost of RAII is that it takes more time to plan resource management in the first place; in this example, you'd have to create a wrapper class that handles opening and closing /etc/passwd.

      The benefit is that when you go to use that wrapper class, you can think about problem you're supposed to solve, since the resource management is already taken care of. As a programmer, I don't want to be thinking about these low-level details when I'm working with the high-level behavior. I even specifically use a RAII wrapper around glPushMatrix() and glPopMatrix() in OpenGL so I don't have to worry about the low-level details. Even though it sounds like more planning, it's more shallow planning, and it really does help with my mental workload.

    20. Re:More push toward VM's by Anonymous Coward · · Score: 0

      Once again you prove that you don't know what you are talking about.

      Thank you for visiting Slashdot, yet again, to post absolute mind numbing drivel.

      I am convinced that you are not completely worthless. I am also convinced that you have some intellectual ability of your own.

      It has become clear, over the last six months, that you do not like the topics which I choose to reply to. It has also become clear, over the last six months, that you do not like what I have to say about those topics. It has also become clear, over the last six months, that you will never relent in your demonstrated goal to follow up nearly everything which I post and respond with a post filled with arrogance, derision, scorn, disdain, challenge, and vitriol. It is also clear that you have not made a single original post of your own but, rather, you exist only by coattailing on the conspiracies which others have expressed.

      So here's your big chance: Sign up for an job. Then e-mail how your interview went and I will make an honest and sincere effort to demonstrate for you what a constructive, and perhaps even a constructively critical, response would look like. Through a possible miracle it may happen that we could reach some sort of reasonable discourse rather than you simply following every post that I make with more of your challenges, disdain, scorn, derision, and vitriol.

      Wouldn't you like to make the world a better place? I sure would. Here's your chance to demonstrate that you have any capacity at all to express your own thoughts.

  9. Hehe by tttonyyy · · Score: 3, Funny

    ...which is why all my dangling pointers have unfree'd memory at the end of them just in case ;)

    --
    biopowered.co.uk - catalytically cracking triglycerides for home automotive use since 2008. Just say no to big oil!
  10. Finally by dsanfte · · Score: 4, Funny

    Finally, an indisputable reason for choosing Java over C++.

    --
    occultae nullus est respectus musicae - originally a Greek proverb
    1. Re:Finally by hardburn · · Score: 1

      Buffer overflows weren't enough?

      --
      Not a typewriter
    2. Re:Finally by A+beautiful+mind · · Score: 2, Insightful

      That's like choosing to live in a mental asylum instead of a normal home. Yeah, those padded walls are really safe, but man, anyone who exercises a little caution doesn't need that kind of thing.

      (Yes, it is a part flame in reply to another flamebait)

      --
      It takes a man to suffer ignorance and smile
      Be yourself no matter what they say
    3. Re:Finally by Nasarius · · Score: 1

      More like: restating one of the reasons that raw pointers should (almost) never be used. A reason for choosing C++ over C, perhaps.

      --
      LOAD "SIG",8,1
    4. Re:Finally by BitchKapoor · · Score: 3, Insightful

      That's like choosing to live in a mental asylum instead of a normal home. Yeah, those padded walls are really safe, but man, anyone who exercises a little caution doesn't need that kind of thing.

      More like living in a gated community rather than living in the projects (the ghetto). The gated community may cost more, but it's safer than the projects, where you have to be careful not to get shot—though rather insular and not as safe as the people who live there generally think.

    5. Re:Finally by greglist12 · · Score: 1

      I thought learning to program six months ago was a good enough reason to choose Java over C++

    6. Re:Finally by Anonymous Coward · · Score: 1, Informative

      Not to mention that Java isn't exactly perfectly safe, either.

      This really is just another example of why unit testing should be required.

    7. Re:Finally by fatphil · · Score: 1

      I'm not sure I like the way this restatement is being made. For example:
      "The long and short of it is, if you can determine the value of the pointer, it's game over."

      #include <stdio.h>
      #include <stdlib.h>
      int main()
      {
          char buf[100];
          char*p=malloc(10);
          printf("The pointer's value is %p\n", p);
          free(p);
          fgets(buf,sizeof(buf),stdin);
          return (buf[0]=='/') && (buf[1]=='.');
      }

      I'd like to see Thomas Ptacek exploit that - show me the "game over" - or to get on his knees, apologise for being a gobsite, and retract his absurd statement.

      --
      Also FatPhil on SoylentNews, id 863
    8. Re:Finally by Anonymous Coward · · Score: 0

      Finally, an indisputable reason for choosing Java over C++.

      Yep, indisputable that C++ takes too much competence in programming that most if not all Java Java programmers can muster.

    9. Re:Finally by smartr · · Score: 1

      This is true, but you would also be comparing a specific flaw in an end user's security vs. a new generic kind of exploit that effects dedicated servers. I imagine many .NET applications (even ones with C# code running unsafe code such as legacy C++ ) might have vulnerabilities from this type of exploit. End users being suckered into running nasty applets is different than a server listening for anyone in the world to exploit it. I think it might be more comparable to say that not using pointers is kind of like not wearing a bullet proof vest. You might not always need a bullet proof vest, and a bullet proof vest won't save you in all situations. The bullet proof vest might even be a bit cumbersome. However, if you're going to into a war zone - you might want to wear one.

    10. Re:Finally by SurturZ · · Score: 1

      I think you misspelt "Visual Basic.NET" - it has more than four letters.

  11. This is nothing new by erroneus · · Score: 0, Offtopic

    Women have been exploiting dangling pointers for centuries... millennia even! :)

    1. Re:This is nothing new by The+Bod · · Score: 1

      My wife prefers that my pointer not dangle.

  12. a new pickup line... by Anonymous Coward · · Score: 3, Funny

    "Hello security hole, wanna meet my dangling pointer?"

    1. Re:a new pickup line... by thegrassyknowl · · Score: 1

      The problem is that if you put a pointer of any kind near a security hole you can often expose a bug!

      --
      I drink to make other people interesting!
  13. Known since 2005 by drspliff · · Score: 4, Interesting

    "When Watchfire first alerted Microsoft's security response team to what Afek and Sharabani had found, they were met with skepticism, and understandably so, Allan said. The company had known since 2005 about the IIS bug that caused the crash, but it was considered a simple denial-of-service problem and not remotely exploitable."

    Worded a little ambiguously, but I presume it's Microsoft their talking about... How can a bug like this get through the QA process since 2005 and multiple product versions without getting fixed?

    1. Re:Known since 2005 by ed.mps · · Score: 1

      since it's MS stuff, nothing to see here, please move along

      --
      !sig
    2. Re:Known since 2005 by nagora · · Score: 4, Insightful
      How can a bug like this get through the QA process since 2005 and multiple product versions without getting fixed?

      Because people keep buying their buggy shit. If people buy your products regardless of the quality, what incentive do you have to fix anything?

      --
      "Encyclopedia" is to "Wikipedia" what "Library" is to "Some people at a bus stop"
    3. Re:Known since 2005 by jimicus · · Score: 2, Interesting

      Worded a little ambiguously, but I presume it's Microsoft their talking about... How can a bug like this get through the QA process since 2005 and multiple product versions without getting fixed?

      Very easily. Every bug gets a priority assigned to it, and from the sound of things this one was ranked pretty low.

      The sheer number of bugs in any large product means it's not really practical to fix every one before a release so the higher priority ones get concentrated on. Time passes, products are realeased because there are deadlines and business needs and it's quite possible that something could be ranked at such a low priority that it never gets any real attention.

  14. Why are we still dealing with this? by 19thNervousBreakdown · · Score: 4, Insightful

    And this isn't a "use Python" or "use Java" rant, either. I will say, however, UNIT TEST YOUR SHIT! EVERY LINE! Even the little inline function, you need to test it all! Repeat after me: Resource Acquisition Is Initialization. Resource Release Is Destruction. -Wall -Werror, no, warnings aren't OK. No, not even signed vs unsigned comparison warnings, you need to either get your data types straight or wrap that in a partial-specialization template functor that correctly checks that you won't be killed by sign-promotion when you compare int and unsigned long long. strncpy(), not strcpy()! -fprofile-arcs -ftest-coverage! Valgrind!

    I dunno. I manage to write C++ and never overflow a buffer, always release all resources when I'm done with them, and never throw away an error. Why can't the other 95% of the programmers out there do the same thing?

    --
    <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    1. Re:Why are we still dealing with this? by j00r0m4nc3r · · Score: 1

      wrap that in a partial-specialization template functor that correctly checks that you won't be killed by sign-promotion when you compare int and unsigned long long. strncpy(), not strcpy()! -fprofile-arcs -ftest-coverage! Valgrind!

      Whoa there, cowboy. Them's fightin' words.

    2. Re:Why are we still dealing with this? by PetriBORG · · Score: 5, Insightful

      I dunno. I manage to write C++ and never overflow a buffer, always release all resources when I'm done with them, and never throw away an error. Why can't the other 95% of the programmers out there do the same thing?

      They are busy being yelled at by their boss to "just make it work" and to "not worry about getting it perfect" and they are dealing the idiot "build master" over in change-management who doesn't know what "make clean" is or how to read a make file, but thinks that he's some master csh hacker... Everyone wants that just not everyone works in a perfect world.

      Shit, most of us are just happy when we are able to beat clear requirements out of people and get reasonable bug reports.

      --
      Pete/Petri "damn, my chainsaw is clogged with 1's and 0's again." --clyde
    3. Re:Why are we still dealing with this? by BitchKapoor · · Score: 4, Insightful

      I dunno. I manage to write C++ and never overflow a buffer, always release all resources when I'm done with them, and never throw away an error. Why can't the other 95% of the programmers out there do the same thing?

      Because they don't care or they're too busy with other stuff, and even if that's not the case, sometimes people make mistakes. That's why you write tools to check that programs are actually being written correctly (wherever possible) and to make it as easy as possible to create full coverage tests, rather than relying on other programmers to do the right thing. Automation, it's a great thing.

    4. Re:Why are we still dealing with this? by Red+Flayer · · Score: 4, Funny

      I manage to write C++ and never overflow a buffer, always release all resources when I'm done with them, and never throw away an error. Why can't the other 95% of the programmers out there do the same thing?
      So, you're saying you program properly, but the other 19 programmers in existence can't?

      Something tells me that even if your programming is 100% spot-on, your grammar skills are slightly lacking...
      --
      "Trolls they were, but filled with the evil will of their master: a fell race..." -- J.R.R. Tolkien on Olog-hai
    5. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 2, Funny

      Yeah, I just read that again. Guess I got a little carried away...

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    6. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      I'm sorry, you're right, there's way more than 20 of us out there. What I should have said is, why can't the other 1,999,999%?

      No, wait...

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    7. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 1, Insightful

      That's actually a semantic error, not a syntactic one.

      Oops, sorry, must have had -pedantic turned on.

    8. Re:Why are we still dealing with this? by Coward+Anonymous · · Score: 1

      What's the biggest project you've worked on?

    9. Re:Why are we still dealing with this? by 140Mandak262Jamuna · · Score: 4, Informative
      Why can't the other 95% of the programmers out there do the same thing?

      Because the other 95% saw that you take too long to write code and your code executes too slowly and you are going to be fired because of it.

      --
      sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
    10. Re:Why are we still dealing with this? by slackmaster2000 · · Score: 4, Funny

      "I dunno. I manage to write C++ and never overflow a buffer, always release all resources when I'm done with them, and never throw away an error. Why can't the other 95% of the programmers out there do the same thing?"

      Because we're employed.

    11. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      > I dunno. I manage to write C++ and never overflow a buffer,

      As far as you know. If your software was as popular as Linux or MSIE, I'd bet many problems would be found.

    12. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Hospitals.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    13. Re:Why are we still dealing with this? by Red+Flayer · · Score: 3, Informative

      No, it's a syntax error. "The other 95% of programmers" refers to the complete set of programmers, less excluded subset. He defined that subset as himself, instead of himself plus others who can code properly; improper usage of "The other" is what caused his dependent clause to be false.

      Note that I'm using dependency grammar here (to which class algebraic grammar belongs). Followers of looser grammatical theories may find the statement technically correct since his meaning was clear. However,this is predominatly a tech site, it follows that dependency grammars should rule the roost.

      --
      "Trolls they were, but filled with the evil will of their master: a fell race..." -- J.R.R. Tolkien on Olog-hai
    14. Re:Why are we still dealing with this? by RAMMS+EIN · · Score: 1

      ``Why are we still dealing with this?

      And this isn't a "use Python" or "use Java" rant, either. I will say, however, UNIT TEST YOUR SHIT! EVERY LINE!''

      You don't think that writing in a language that just doesn't allow these bugs to be coded would be easier? Not to mention that that would actually guarantee the absence of such bugs, which unit testing doesn't?

      --
      Please correct me if I got my facts wrong.
    15. Re:Why are we still dealing with this? by Chyeld · · Score: 1

      Probably because their not on their 20th nervous breakdown. (it's a joke, but there is a point to it.)

    16. Re:Why are we still dealing with this? by Coward+Anonymous · · Score: 1

      Ok, what part of it? How complex is it? Are we talking about data entry forms, oxygen flow meters, inventory control?

    17. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Yeah, there was a little hyperbole there, but I was trying to make a point. Although, to be fair, I still run all of my code through Valgrind and I've only caught an error like that twice in about 8 years. Once was C++ type demangling to make an error message human-readable, which as I recall was really poorly documented as to whether you or the library freed the memory, and the other was interfacing with getopt_long(), I tried to free argv. Whoops. I do have bugs, but it's extremely rare that it's of that type. I view a programmer making that type of a mistake about the same as a person trying to walk across the room and falling on his face. Which I've done, twice.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    18. Re:Why are we still dealing with this? by Citizen+of+Earth · · Score: 2, Insightful

      strncpy(), not strcpy()

      You do realize that strncpy() is fundamentally broken, right? If the source string is longer than n characters, then the destination string will not get a null terminator. The first operation after that on the destination string will go flying off the end with unpredictable results. strncpy() is also inefficient in that it will fill the dest buffer with unnecessary null characters if the source is short. I use my own strcpy() function that takes the size of the destination-string buffer as a parameter.

    19. Re:Why are we still dealing with this? by Intron · · Score: 1

      strncpy is a frequent cause of code bugs and inefficiency:

      1) It does NOT guarantee that it creates a NULL-terminated string.

      2) It always writes every byte of the destination. Copy 10 characters into a 1000-byte buffer and it writes 1000 bytes, mostly zeros.

      --
      Intron: the portion of DNA which expresses nothing useful.
    20. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      Note to self: Cancel party invitation for Red Flayer.

    21. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Easier, yes. But people still don't develop their software rigorously, so all it does is push these errors into another class. This is something that could be solved just as well with a library in any given language, you don't have to use Python to be sure you aren't hitting these bugs.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    22. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Payroll, insurance submission, medical records, you name it. I worked in a shop where we basically handled every programming task a hospital could want. No, not firmware for dialysis machines, but it was plenty complicated, and it could be your ass if you make a mistake. There was a time, if you so much as walked in the door of a hospital in New York anywhere outside of NYC, and one there, that you were pushing bits through my code. Of course, a huge hospital IT company came in and took every last one of our customers with PowerPoint slides and free lunches, but the pain those people went through with that crap software was more than enough to wash away my angst. Over that particular matter, anyway. I work in a much lower-pressure job these days, and I'm happier, but sometimes I miss praying to sweet Christ that the code I just uploaded doesn't make today the first (and likely last) time I ever lost data.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    23. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Yeah, I remember that now. To be honest I was just trying to come up with an example of checking your buffers, I've only used either function a couple times at best. Should have unit tested that post.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    24. Re:Why are we still dealing with this? by lgw · · Score: 1

      strncpy() doesn't do what most people think it does (there's no guarentee of null termination at the destination). Saying "quick, replace all your strcpy calls with strncpy" is likely to cause more harm than good.

      --
      Socialism: a lie told by totalitarians and believed by fools.
    25. Re:Why are we still dealing with this? by Nevyn · · Score: 2, Informative

      As someone who's written 2 pieces of OSS with 100% code coverage in unit tests, and probably the most secure C http server (comes with over 75% coverage). I have to say: "It's not quite that simple". Testing does not negate design, and designing for security is non-trivial and takes a certain mind-set ... and while a lot of people say they want security, almost none are actually prepared to buy it (with either money, lack of features, whatever).

      Hell, one of the biggest advancements in security in recent years is SELinux, and I see almost nothing but complaints about how it "is less usable, so we just turn it off". Summary: We are still dealing with security problems because that's what the majority of the market wants, welcome to democracy and the free market.

      strncpy(), not strcpy()!

      Actually usage of strncpy() almost certainly guarantees you have bugs, IMNSHO. You need a real managed string API. Assuming the programer can keep track of three distinct pieces of information like "size, length and pointer" is just a losing bet. All of the applications (including mine) that have had security guarantees with money have internally used a real managed string API.

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
    26. Re:Why are we still dealing with this? by DefenderThree · · Score: 1

      That is possibly the most appropriate username/post combination I've seen on /.

    27. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      You still use strncpy()? Use strlcpy(). If you're still using the 1 libc in the world that doesn't have this functionality (glibc), then write a quick implementation. It's a simple function.

    28. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      Yeah, I don't know why I picked that example, I've almost never used either function, and when I did I checked string length/null termination myself before... and after... man, they suck... just the first thing that popped into my head and I was ranting.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    29. Re:Why are we still dealing with this? by cecille · · Score: 1

      Are you sure you NEVER do these things? That your code is spot-on perfect every time? No exploitable bugs anywhere? Because if you really think that then you're living in a dream world.

      Back here in the real world, people aren't so perfect. Code is messy, projects are big and touched by many people, deadlines come quickly and testing isn't foolproof.

      --
      ...no two people are not on fire.
    30. Re:Why are we still dealing with this? by CustomDesigned · · Score: 1

      >> strncpy(), not strcpy()!

      > Actually usage of strncpy() almost certainly guarantees you have bugs,
      > IMNSHO. You need a real managed string API. Assuming the programer can keep
      > track of three distinct pieces of information like "size, length and
      > pointer" is just a losing bet. All of the applications (including mine) that
      > have had security guarantees with money have internally used a real managed
      > string API.

      I use strncpy() quite a bit - for setting null padded fixed length fields in binary config/database records. I can see that it would be problematic if you thought it had something to do with string handling. (I'm sure it seemed like a good name at the time.)

    31. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      No, you're right, I do those things sometimes, even after all my testing. I don't know what I was thinking using hyperbole around 200,000 aspies. The point is, it's exceedingly rare, like two double-frees in 8 years that I can think of and no, not a single buffer overflow (that I know of). As for big projects, if they're managed well it's not that much of an issue. There are coding standards, what you work on is well-defined and had better be documented (edge cases, calling conventions, invariants, etc.) plus you check the input anyway, unless it's real expensive and you're optimizing, and you've made your proposal in front of the team, and then you mark your unsafe function with a u_ or whatever your standard unchecked input marker is. Luckily, I've never worked at one of these big, greasy, code factories where everyone's got sloppy bits up to their elbows and there's a sign over the door that says, "Three (3) days since the last industrial accident (resulted in loss of limb)!" I have walked out in the middle of an interview at a place like that though, I think my head would asplode to work around that, plus it was fun to interrupt Mr. In The Real World Things Are Broken And That's Normal mid-sentence.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    32. Re:Why are we still dealing with this? by psmears · · Score: 2

      No, it's a syntax error. "The other 95% of programmers" refers to the complete set of programmers, less excluded subset. He defined that subset as himself, instead of himself plus others who can code properly; improper usage of "The other" is what caused his dependent clause to be false.

      You can argue all you like, but it's still not a syntax error. It is, I grant you, not strictly speaking the correct choice of words—but since one could make the statement 100% correct by changing the situation (i.e. by systematically killing off programmers in their thousands until only 20 remain in the world[1]), but without changing the phrase, it is most certainly a gramatically correct sentence—even if the semantics are wrong in the given context.

      [1] This would, of course, be taking the phrase "grammar nazi" to a whole new level...

    33. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      *sigh*

      It's hard to convince other people that you're perfect when you forget to close your <i> tags.

      Somebody mod me up to +5 Funny and back down to -1 Overrated.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    34. Re:Why are we still dealing with this? by Red+Flayer · · Score: 1

      Well, I'd guess we'd disagree til the cows come home about what a syntax error is. If improper use of a clause causes an incorrect meaning, that's an error in syntax that led to the incorrect meaning. Note that syntax is the patterned relations of the words used to create the sentence; a misuse of a relation (in this case, "the other") is a syntax error.

      In grammar, incorrect syntax != does not compile. You can't equate a programming syntax error with a language syntax error; in programming, the scope of a syntax error is reduced. A substitution of values in a syntactically correct program may give you an error output, though the syntax is correct -- but as long as some value exists for which the statement is true, then the syntax is OK. Not so in language, where whether or not the syntax is correct depends largely upon the intended meaning -- and therefore the values used.

      --
      "Trolls they were, but filled with the evil will of their master: a fell race..." -- J.R.R. Tolkien on Olog-hai
    35. Re:Why are we still dealing with this? by cecille · · Score: 1

      Don't get me wrong - I do believe very much in testing, and I do think that a lot of problems can be taken care of with proper testing. However, there is not a chance that anyone is writing completely bug free code no matter how careful they are. In fact, sometimes the worst bugs are the ones that you wouldn't have even thought to test for. Not all the time, obviously, but bug sneak into code like its their mission in life. The fact is that a lot of code is complex and coders are imperfect by nature. Unless a project is trivial, it's never going to be bug free, and coders are never going to spit out bug-free code no matter how careful they are.

      --
      ...no two people are not on fire.
    36. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      Think about the security of any program statistically. You have for any class of error, the probability e of making the error and the probability x of it being exploitable.

      So for example in C:

          Pdbl: (0.05)(.3), double-free
          Pdang: (0.1)(.8), dangling pointer
          Pinit: (0.02)(.1), uninitialized data
          Pover: (0.3)(.6), overflow ...

      And then take the chance of it not happening even for just ten possible errors of each kind:

          (1-Pdbl)^10*(1-Pdang)^10*(1-Pinit)^10*(1-Pover)^10 == 0.05 of no vuln

      I just made up the numbers above, but basically in a language like C or C++ you are screwed. You can reduce the probabilities by doing unit testing or valgrind or whatever but the inevitable fact is that a large program written in these languages will have exploitable security flaws in it.

      The nice thing about Java and to some extent .NET/CLR is that instead of trying to lower the probability on these errors it just completely removes them. Probability of a double-free, or dangling pointer, or uninitialized value, or overflow are all zero. There are still other classes of exploitable errors like physical memory corruption or higher-level logic bugs, but to some extent these just can't be helped. The computer can't magically know what you intended it to do, but it doesn't need to intentionally try to misunderstand you like with C/C++.

    37. Re:Why are we still dealing with this? by 19thNervousBreakdown · · Score: 1

      OMG! I like to make up numbers to support something I've already decided too! 98.-6% of mothers agree, we should hook up.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    38. Re:Why are we still dealing with this? by BZ · · Score: 1

      > no, warnings aren't OK.

      Except for the fact that some of the warnings gcc, say, produces, are plainly wrong. It's possible to change the code to prevent those warnings, at the cost of some CPU cycles... but sometimes you can't afford that.

    39. Re:Why are we still dealing with this? by Nevyn · · Score: 1

      Fair enough, I'm not talking about you then :). I'd heard that it was "designed" for using in copying directory names to user space in Unix ... where the name was a fixed size string, that might not be terminated if it used all 15 characters (and you don't want information leaks if it's less than that). So I should probably have said: usage of strncpy(), as a normal string API, almost certainly guarantees you have bugs...

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
    40. Re:Why are we still dealing with this? by DragonWriter · · Score: 1

      No, it's a syntax error. "The other 95% of programmers" refers to the complete set of programmers, less excluded subset. He defined that subset as himself, instead of himself plus others who can code properly; improper usage of "The other" is what caused his dependent clause to be false.


      Its not a syntax error: the sentence is grammatically correct but does not have the intended semantics. Its a "bug": if it were code, it would compile and run, but just produce results other than what was intended.
    41. Re:Why are we still dealing with this? by Mutatis+Mutandis · · Score: 2, Insightful

      Because the other 95% saw that you take too long to write code and your code executes too slowly and you are going to be fired because of it.

      Don't be silly. It is perfectly possible to write robust, efficient C++ code at a decent speed. And it is certainly much more efficient than generating buggy crap and then spending weeks, months and years trying to find the elusive bugs. Not to mention the complete rewriting of large blocks of unintelligible, bad-quality code as 'bug fix'.

      I fully agree with the original author. Buffer overruns? Dangling pointers? I haven't had them in years, and my code is written on time and meets performance targets. Nor am I even that skilled a C++ writer; I do something from time to time to keep in good mental form, and when I need to integrate some fast processing code in Java code or enterprise software. I have no respect for people who allow buffer overruns or dangling pointers to pollute their code, and who leak memory from all their gills. All it takes to prevent such errors is a little care, the adoption of reasonable design patterns, and a bit of mental exertion.

      There are plenty of more-or-less excusable bugs, let's start by learning to avoid to inexcusable ones.

      And I am especially annoyed at the so-called 'safe' versions of standard library functions that MS introduced in Visual C++ to compensate for this kind of libertine amateurism, even deprecating strncpy()... in favor of a version that is best avoided unless you are well aware what it is doing to the rest of your buffer. But then the Microsofty version of C++ has always been a definite example of a language that has gone over to the dark side.

    42. Re:Why are we still dealing with this? by RubberChainsaw · · Score: 1

      My unit tests are my users.

      Narf.

      --
      I welcome our new 99% overlords.
    43. Re:Why are we still dealing with this? by epine · · Score: 1


      Writing clean code is a combination of mindset and habit. Once you aquire the skill, it doesn't take longer, and it can often speed up the process because you end up with fewer perplexing bugs, or unanticipated edge cases.

      One of the major oversights of many programmers is failing to recognize the power of "do nothing". In many of my programs I don't check for a null return from malloc. Instead, I check for null pointers at the beginning of any block or statement that might deref. the pointer. It's less overhead than one might expect. Unfortunately, C/C++ doesn't always cater to this approach. This kind of thing gets old in a hurry when multiple pointers are involved:

      if (p && p->r.foo && p->r.foo->s.bar)
          total += p->r.foo->s.bar->t.count;

      Unfortunately, one can only be certain the statement is valid on local evidence if one writes the cumbersome, fully guarded form.

      Dangling pointers is not instrinsic to the difficulty of the task, it's intrinsic to the accepted culture, which includes coding against libraries so badly designed it isn't possible, either syntactically or conceptually, to guard on validity. Even the best programmer can't code defensively to a worthless API. Failing that, there's no excuse.

    44. Re:Why are we still dealing with this? by epine · · Score: 1


      That string page is interesting, but indulges in unnecessary drama here and there. /* broken example ... fairly common mistake */
      char *s1;
      int X; ...
      sprintf(s1, "%s:%d", s1, X); /* append a number */

      Are you kidding? Despite what the standard says about "undefined" behaviour of overlapping string copies, a platform that manages to break that construct has a deathwish concerning market share. This represents more a failure on the part of the standard to speak to common sense, rather than a failure of coding practice out in the field.

      Incidentally, I would never code such a statement, even if I would hardly blink reading it. I'm mortally afraid of the cases where undefined actually has teeth and too lazy to keep track of the rare cases, such as thing one, where in practical terms, there is nothing but gums.

    45. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      THANK YOU! That footnote made me LOL, which happens nowhere near as frequently as I use that acronym. Truly classic.

    46. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      Thank you Dr. Bernstein. You are so wise and learned. When is qmail 2.0 coming out?

    47. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      Informative?

      Please stop thinking that design and testing slow you down. The vast majority of the lifecycle of most programs is not in development but rather it is in maintenance. If you double the development time to cut 10% of the required maintenance, you'll actually come out ahead for many products.

      If you design and test your code well, you can eliminate a lot of runtime checks meaning it'll actually execute faster than more rapidly designed and coded software.

      I hope for your sake that you never hold a programming job for longer than about 6 months because you'll be so bogged down with bugfixes that you'll never get anything done.

    48. Re:Why are we still dealing with this? by phantomfive · · Score: 1
      If you have your own strncpy() function, you won't need this, but here is the easy way to do it:

      strncpy( dest, src, destSize );
      dest[destSize-1] = 0;
      If the string is NULL terminated, setting the last element of the array to NULL will do no harm, and if it did overflow, this will fix it.
      The designers of strncpy followed the idea that it's better to keep as much data as possible, and that you would be smart enough to handle the case where you don't care.
      --
      Qxe4
    49. Re:Why are we still dealing with this? by Citizen+of+Earth · · Score: 1

      The designers of strncpy followed the idea that it's better to keep as much data as possible

      Your approach is still inefficient and error-prone since one can easily forget the second part.

      It seems to me that strncpy() matches the semantics of fixed-length fields in some 1970's file formats. Some really old versions of Unix stored 14-character filenames according to this semantic (plus a 2-byte inode value) in directories.

    50. Re:Why are we still dealing with this? by Anonymous Coward · · Score: 0

      dumbass log, it doesn't matter what the probability is the fact that you have tens of thousands of independent variables in most any program means it's a virtual certainty that there are security errors in the code -- no matter how small you make the numbers. Unless you make them zero, like in Java and other typesafe languages.

      l2stat

    51. Re:Why are we still dealing with this? by CodeBuster · · Score: 1

      You need a real managed string API

      Or a real managed runtime with virtual machine and a more modern programming language. There are really fewer and fewer excuses every year for most programmers to continue using 1970s vintage languages, such as C, which allow these sorts of mistakes to be made by programmers that almost certainly do not understand the consequences. Is it possible to write a stable and secure program in these languages? Of course, but there are simply too many gotchas in these languages to justify their continued use, especially in new applications, for most developers. If you want to write a business application then do yourself a favor and pick a managed environment such as Java or C# .NET and leave the C code to the kernel and driver programmers. Unless of course you enjoy pain and simply must have that last bit of speed (by which time your competitors would have beaten you to market anyway). It just isn't worth the trouble anymore and I started my programming career with C++ so I know how irritating it can be to track down these pernicious runtime errors.

    52. Re:Why are we still dealing with this? by Mask · · Score: 1
      Because the other 95% saw that you take too long to write code and your code executes too slowly and you are going to be fired because of it.

      Wrong. I have been doing this since 1999, Using these techniques makes me code faster than most others since:
      • No need to waste time thinking about resource destruction.
      • No need to waste time thinking about corner cases. Good tests are more effective in catching corner cases than sitting and thinking.
      • I almost never have to debug complex integration issues -- 99.5% of my bugs are found during unit testing, where debugging is trivial.
      • Maintaining and refactoring is much faster for me than for others. Most of the tests are already there. I don't need to think much while refactoring, if it is wrong, the tests catch it.
      As for speed, my code is faster than that of most of the people I know. People come and ask for advice all the time.
      Many times nice readable code = fast code , because then you can profile it and understand how to improve it. The few critical lines can always be uglified later, once you realize that they are critical and you prove that it does improve speed.
    53. Re:Why are we still dealing with this? by Fastolfe · · Score: 1

      You should write a book. "How to be a perfect programmer that writes code with no bugs in less time than everyone else!" You'd literally revolutionize the software industry. Patent your secret. But get it out there somehow. We need you. Clearly it's not as easy as you suggest, because we have armies of software developers that aren't doing it.

    54. Re:Why are we still dealing with this? by Fastolfe · · Score: 1

      In some (larger) IT shops, the guys doing the development are never going to be around to do the maintenance. Some outsourcing arrangements actually make that part of the contract. ("We'll write it, but you have to support it after the first N months.") What incentive do they have to produce perfect code? Well-written code?

      In my experience, most people in an IT shop that become excellent programmers want to move on to things other than programming. That may not be the case in a company devoted to software development, but an awful lot of software is written by companies that aren't in the business of writing software.

    55. Re:Why are we still dealing with this? by Nevyn · · Score: 1

      Probably although, personally, I wouldn't bet that much on it. I'm pretty sure the above "works" on glibc at least in the normal cases ... but there are a significant number of non-normal cases, and I'd be worried that libc would change the internal copy to a memcpy() and I'd be screwed or that GCC would do something "intelligent" (esp. given that ISO 9899:199 defines sprintf as having a restrict'd pointer for the first two arguments). At the very least I wouldn't be surprised to see GCC complain about it.

      A significant number of people thought C compilers would never care about aliasing, but they do now.

      --
      ustr: Managed string API with ave. 44% overhead over strdup(), for 0-20B
  15. what a headache by circletimessquare · · Score: 2, Informative

    it's one thing to find a major exploit, but a whole new class of exploits?

    welcome back to the days of sql slammer and code red folks. buffer overflows have been analyzed to death, but this is just the beginning

    --
    intellectual property law is philosophically incoherent. it is your moral duty to ignore it or sabotage it
    1. Re:what a headache by 19thNervousBreakdown · · Score: 1

      No, this is very little new. It's the same basic programming error that's been made since day one, "whoops, I forgot." Not to mention, there's absolutely no explanation on how they've managed to put code in what's basically an arbitrary memory location.

      But man, this type of thing should be a 0.01% of software type of bug. What the hell? Isn't software engineering?

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    2. Re:what a headache by Anonymous Coward · · Score: 0

      No it is not engineering because companies like the one I work for hire BCIS and MIS people and have them code. They only programming class they took was VB.net. It gets them a job and then they kiss ass and they become the CS student's boss. It is sad, I tried to tell my boss they have a memory leak in there legacy application and she said "Huh?" Welcome to the world where you just have to know how to make an HTML page in FrontPage and know how to copy and paste some JavaScript and you get a job writing a 20 million dollar application.

    3. Re:what a headache by Anonymous Coward · · Score: 0

      It gets them a job and then they kiss ass and they become the CS student's boss.
      You forgot another archetype. The incompetent CS student. I know a guy like this. CS major for all the wrong reasons. Wants to make money. Gets through a CS program by copying off someone who knows what they're doing. Doesn't care about correctness. Kisses ass in academia as well as in industry. Ends up coming off as a likable guy. Consistent with the archetype that you described above.
  16. FUD! We're important! by kwerle · · Score: 2, Insightful

    This is a story about a company that says they have a story.

    Let's just wait until the actual story next time? (since it doesn't seem likely there will be a real one, here, anyway)

  17. NULL those pointers, folks by steveha · · Score: 3, Interesting

    I have written a bunch of C code, and a little C++ code.  I have made it a habit to set a pointer to NULL after I free the pointer's data.  If I had code that allocates a FOO structure, I would make a function to free the FOO structure; in C, my FreeFoo() function would not take a pointer to a FOO, but a pointer to a pointer to a FOO, and after freeing the FOO it would set the pointer to NULL.  Like so:

    /* C code */

    void
    FreeFoo(PFOO *ppfoo)
    {
        PFOO pfoo;

        assert(NULL != ppfoo);
        if (NULL == ppfoo)
            return;

        pfoo = *ppfoo;

        assert(NULL != pfoo);
        if (NULL == pfoo)
            return;

        free(pfoo);
        *ppfoo = NULL;
    }

    /* typical use:

    PFOO pfoo = PfooNew(args);
    ...do something with FOO object...
    FreeFoo(&pfoo);
    */

    Note that if you acidentally try to double-free the FOO, the above code will not crash; the first free sets the FOO pointer to NULL, and the second one notices that the pointer is already NULL and exits early.  It does assert() when you try to free a NULL pointer, so you can catch the error and see what else you might have messed up.

    For C++ you should be able to write a template that takes a reference to any pointer type and applies the above logic.

    I once had to maintain a legacy code base, a whole bunch of C implementing a fairly complicated application.  The app had a whole bunch of crashing bugs.  I went through and applied the above logic everywhere the app was calling free() and suddenly the app stopped crashing.  I wonder if the previous developers were using a different compiler or something, and the dangling pointers just happened to work for them?

    steveha

    --
    lf(1): it's like ls(1) but sorts filenames by extension, tersely
    1. Re:NULL those pointers, folks by 19thNervousBreakdown · · Score: 1

      Exactly! I'm no fan of C, there's too much I've gotten used to being able to do in C++, but this just goes to show that while you can write crap code in any language, you can write good code too.

      Good on ya for putting your lvals on the right of your comparisons, too.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    2. Re:NULL those pointers, folks by BitchKapoor · · Score: 3, Informative

      Unfortunately, that solution breaks down when you have multiple different pointer variables pointing to the same location. This will happen in any graph-like data structure more advanced than a tree. You can get around it by adding a level of indirection from handles to pointers, and making the handle-pointer mapping nodes reference counted (note that reference count cycles are not possible using this strategy), but that can have a significant performance hit, and requires quite a bit of refactoring.

    3. Re:NULL those pointers, folks by 19thNervousBreakdown · · Score: 1

      Unfortunately, a hammer does you no good when you're omg standing on the surface of the sun! so we should throw away all the hammers.

      I think he was just trying to illustrate a simple point, not post the One True Memory Management pattern :P

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    4. Re:NULL those pointers, folks by cerelib · · Score: 3, Insightful

      Just curious, what is advantage to putting your lvalues on the right of a comparison? Is it an optimization or just a "best practice"? I typically will put the subject of the comparison on the left. Which means between a constant/literal and an lvalue, the lvalue gets the left. Between to lvalues, I pick the one, which there almost always is, that is somehow more important to the logic of the control statement being compared for. I am a professional programmer, but have never heard of any rule or advantage regarding lvalues on the right of a comparison.

    5. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      This protects against mixing up the assignment (=) and the equality test (==). With the lvalue on the right, this mixing up leads to a syntax error. With the lvalue to the left, you still have syntactically correct code (although the compiler will likely emit a warning).

    6. Re:NULL those pointers, folks by 19thNervousBreakdown · · Score: 3, Insightful

      It prevents the common mistake of using the assignment operator "=" when you meant the equality operator "==". I like it better your way too, since it illustrates the object of the comparison better, but if I'm rushing out code that I don't have time to write good unit tests for, I switch over.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
    7. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      7.20.3.2 The free function Synopsis [#1] #include void free(void *ptr); Description [#2] The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined. Returns [#3] The free function returns no value.
      free(NULL); is NOP. The only useful thing your function does is make the pointer that is free'd NULL, but this alone does not prevent a double free. delete is similar:

      The value of the first argument supplied to one of the deallocation functions provided in the standard library may be a null pointer value; if so, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(size_t) or operator new(size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](size_t) or operator new[](size_t, const std::nothrow_t&) in the standard library.
    8. Re:NULL those pointers, folks by steveha · · Score: 3, Informative

      Unfortunately, that solution breaks down when you have multiple different pointer variables pointing to the same location.

      Okay sure, the FreeFoo() logic will not, by itself, take care of the case where you have multiple pointers. Only the pointer you actually use to free the object would be automatically nulled.

      As you note, it is possible to pass around "handles" and make the handles safe, and as you note, there can be a performance hit.

      But if you have a clean code design, you will have an expected lifetime for those extra pointers, and when you are done using a pointer, you can NULL that pointer. When you are done, you should have only one pointer left pointing to the object, and when you call FreePfoo(), you will then have zero pointers left pointing to the now-freed object.

      Another simple trick you can use: at the beginning of your structure, place a member variable called "signature" or something like that, and set it to some unique value. Then, in FreePfoo(), zero out the signature before you call free(). Then start each function that uses a PFOO with an assert() that checks that the signature is sane. Even if you have a dangling pointer, and even if that pointer can still be used to reference your structure after you free() the structure, the assert() will fail. If you like you can put the "signature" member under #ifdef so that you don't even compile it in unless asserts are enabled.

      The last major application I developed, I used the above tricks. The most important data structures each had their own unique signature. Functions that took a PFOO started with a call to AssertValidPfoo(pfoo), which would check the signature and also perform every other sanity check I could think of upon the FOO and the pointer (and which would not be compiled for a release build). Once the compile succeeded with no errors or warnings, I would run a test and immediately get an assert() if I had a code bug. Once I fixed the code to no longer assert(), in general my code Just Worked.

      Asserts are like unit tests that run every time you run your code, and don't cost anything in the final release build. I love asserts.

      Does this sound like more work than a garbage-collected language like Java or Python? Well, it is. C is just plain a lower-level language and you need to do more stuff by hand.

      steveha

      --
      lf(1): it's like ls(1) but sorts filenames by extension, tersely
    9. Re:NULL those pointers, folks by jgrahn · · Score: 2, Insightful

      I have made it a habit to set a pointer to NULL after I free the pointer's data. If I had code that allocates a FOO structure, I would make a function to free the FOO structure; in C, my FreeFoo() function would not take a pointer to a FOO, but a pointer to a pointer to a FOO, and after freeing the FOO it would set the pointer to NULL.

      It's something people often suggest, and I don't like it at all. It doesn't catch the serious case, where you have more than one pointer to the memory. Who is going to null those pointers? A clear design which explicitly takes object lifetimes into account is a much better solution.

      (I also don't like the PFOO typedef in your example. Pointers are important in C; hiding the fact that something is a pointer will only lead to more bugs, at least if someone other than yourself will maintain the code. It will also make it impractical to say "pointer to const FOO", thus hurting type safety.)

    10. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      7.20.3.2  The free function

             Synopsis

             [#1]

                     #include <stdlib.h>
                     void free(void *ptr);

             Description

             [#2] The free function causes the space pointed to by ptr to
             be  deallocated,  that  is,  made  available   for   further
             allocation.   If  ptr  is  a null pointer, no action occurs.
             Otherwise, if the argument does not match a pointer  earlier
             returned  by  the calloc, malloc, or realloc function, or if
             the space has been deallocated by a call to free or realloc,
             the behavior is undefined.

             Returns

             [#3] The free function returns no value.

      and

      -3- The value of the first argument supplied to one of the deallocation functions provided in the standard library may be a null pointer value; if so, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(size_t) or operator new(size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](size_t) or operator new[](size_t, const std::nothrow_t&) in the standard library.

    11. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      The only useful thing [FreeFoo()] does is make the pointer that is free'd NULL, but this alone does not prevent a double free.

      PFOO pfoo = PfooNew(args);
      free(pfoo); /* frees the FOO */
      free(pfoo); /* undefined behavior (probably a crash) */

      PFOO pfoo = PfooNew(args);
      FreeFoo(&pfoo); /* frees the FOO and sets pfoo to NULL */
      FreeFoo(&pfoo); /* does not crash, and asserts to warn you */

      I would claim that FreeFoo() prevented a double-free error in the above code.

      PFOO pfoo = PfooNew(args);
      PFOO pfooTemp = pfoo;

      FreeFoo(&pfoo);
      FreeFoo(&pfooTemp); /* whoops, double free */

      Okay, in this code, FreeFoo() wasn't enough to save the developer from screwing up. That doesn't make the trick useless.

    12. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      It's something people often suggest, and I don't like it at all. It doesn't catch the serious case, where you have more than one pointer to the memory. Who is going to null those pointers?

      By itself, it doesn't solve all your problems. That doesn't mean it's worthless.

      A clear design which explicitly takes object lifetimes into account is a much better solution.

      Clear design is always better than poor design.

      hiding the fact that something is a pointer will only lead to more bugs

      FOO foo;
      PFOO pfoo = &foo;

      You think the above code "hides" the fact that pfoo is a pointer to a FOO? I disagree.

      It will also make it impractical to say "pointer to const FOO", thus hurting type safety

      typedef FOO *PFOO;
      typedef const FOO *PCFOO;

      PCFOO pfoo; /* pointer to a const FOO */

      PFOO and PCFOO are just shortcuts to save typing, and help long function declarations fit on a single line. If used consistently, they are hardly "hiding" anything.

    13. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      Remind me never to code in that horrid, non-garbage-collecting, low-level, way-too-many-LOC, POS language ever again.

      Seriously, you spend man hours on this crap?

    14. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      Remind me never to code in that horrid, non-garbage-collecting, low-level, way-too-many-LOC, POS language ever again. Seriously, you spend man hours on this crap?

      It builds character, so STFU!

    15. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      I tend to just write "assert (ppfoo);" and "if (ppfoo)". (so long as what you're comparing against is 0)

    16. Re:NULL those pointers, folks by Anonymous Coward · · Score: 0

      my FreeFoo() function would not take a pointer to a FOO, but a pointer to a pointer to a FOO, and after freeing the FOO it would set the pointer to NULL.
      That works okay as long as other users of your functions aren't second-guessing your work. Me, I aways take a pointer to a a pointer to a a pointer to a FOO to stay one step ahead.
    17. Re:NULL those pointers, folks by ThosLives · · Score: 1

      An interesting but little known fact is that the C standards specify that all implementations of C(++) are to treat a constant 0 in code as the null pointer, even if the null pointer is not actually implemented as a binary zero.

      That's why you don't really need if (ptr == NULL); you really can just do if (ptr) or if (!ptr) and it should work.

      The "should" is only because having a correct compiler isn't as likely as you might think. You *do* check your compilers for behavior before you use them, right?

      --
      "There are a dozen opinions on a matter until you know the truth. Then there is only one." - CS Lewis (paraprhase)
  18. SOS? by wsanders · · Score: 1

    And this is somehow a newly discovered hitherto unknown class of exploit?

    People have been 'sploiting this kind of thing for years as far as I know.

    Not that there's any thing wrong with that! (Except that maybe there is a kit now for diddling the danglers.)

    --
    Give a man a fish and you have fed him for today. Teach a man to fish, and he'll say "WHERE'S MY FISH, YOU IDIOT?"
    1. Re:SOS? by quanticle · · Score: 2, Informative

      People have been 'sploiting this kind of thing for years as far as I know.

      Perhaps you're confusing dangling pointers with buffer overflows. Buffer overflows occur when you put too much data into a pre-allocated buffer, overwriting the return address of the current function with a return address pointing to your malicious code. Dangling pointers are simply pointers pointing to invalid types. Before, it was thought that dangling pointers were not exploitable, because you had to know the actual type of the destination object, which was thought to be difficult. However, this group has discovered a way to reliably discover the destination type, allowing them to overwrite it with malicious code.

      --
      We all know what to do, but we don't know how to get re-elected once we have done it
  19. Out of curiosity - who uses C/C++ for web by lena_10326 · · Score: 1

    ....programming?

    Let's ignore plugins or modules, because those are frequently C/C++; however, it's been my experience that writing modules is far less common than just implementing code in PHP or Perl. I'm talking about basic application logic, generally form processing and serving HTML content.

    I have implemented barebones C and C++ HTTP servers because high performance was a critical requirement, but the percent gain wasn't really worth the effort. PHP with caching (apc, memcached, db pooling) is almost as fast as a bare C server. Debating 1,000 connections per second versus 10,000 connections per second is a bit moot when your system isn't topping 300 req/second, even at system peak.

    So. Does anyone have a reason for C/C++ web code that's not based on performance? Say, a library wrapper for accessing a legacy data source for which there's no scripted library?

    --
    Camping on quad since 1996.
    1. Re:Out of curiosity - who uses C/C++ for web by six · · Score: 1

      Say, a library wrapper for accessing a legacy data source for which there's no scripted library?

      I think this is what the ffi extension for PHP is all about

    2. Re:Out of curiosity - who uses C/C++ for web by el_womble · · Score: 1

      The interesting thing about web programming is that it's rarely the application itself that is slowing the system down. Disk I/O, network and database speed are far more likely to be the bottleneck than the application. That's why web programmers get away with the likes of Hibernate, Ruby on Rails, J2EE etc and games programmers don't, and if thats not the case, the code is so naturally multi-threaded that app server problems can normally be solved by buying another box far quicker than they can by implementing the server in C (although with data center power costs the way they are, that might not always be the case :p ).

      If the app is slowing you down the chances are that you're doing some thing algorithmically bad, or forcing the app server to do something that should have been done on the database - these problems are unlikely to go away with a platform change.

      --
      Scared of flying, pointy things snce 1979!
    3. Re:Out of curiosity - who uses C/C++ for web by lena_10326 · · Score: 1

      If the app is slowing you down the chances are that you're doing some thing algorithmically bad, or forcing the app server to do something that should have been done on the database - these problems are unlikely to go away with a platform change.
      A web imaging server doesn't work well if it has frequent interaction with a database, particularly when image loading time in the browser is absolutely critical (where 0.5 seconds versus 2 seconds means everything). :) It's also more dependent on CPU speed and amount of RAM. Of course, using C to implement one for the performance gain goes in opposition for my request for non-performance reasons. :) The code I'm referring to was reimplemented in PHP and the performance was fine. It was also substantially more reliable with fewer segfaults, not to mention the code was more condensed and easier to read. The C code was problematic with maintenance and testing.

      --
      Camping on quad since 1996.
    4. Re:Out of curiosity - who uses C/C++ for web by Anonymous Coward · · Score: 0

      So. Does anyone have a reason for C/C++ web code that's not based on performance? Say, a library wrapper for accessing a legacy data source for which there's no scripted library?

      If there's a C/C++ interface to it then there's a scripted interface to it.

  20. What is this? by SloWave · · Score: 1

    You have a pointer.

    You free the the object the pointer is pointing too.

    The bad guy figures out where the pointer is pointing and writes his code at that location. The next time the pointer is called the bad code is executed.

    This is like saying you lock a door and put the key away somewhere. The bad guy finds the key, unlocks the door and takes what he wants.

    Why is this suddenly a major security issue and what am I missing?

    1. Re:What is this? by AP2k · · Score: 1

      Its more like the bad guy figures out which wire lights the lamps in your room when you flip the switch. Bad guy then installs a bomb to go off when you flip the switch.

    2. Re:What is this? by Venerable+Vegetable · · Score: 1

      This is like saying you lock a door and put the key away somewhere. Under the doormat. You know there are a lot of bad guys. The bad guys always look under the doormat. Why don't you see this is a major security issue?

    3. Re:What is this? by quantum+bit · · Score: 1

      The bad guy figures out where the pointer is pointing and writes his code at that location. The next time the pointer is called the bad code is executed. (emphasis mine)

      Why is this suddenly a major security issue and what am I missing? The bad guy typically has no control over where the pointer is pointing (that's determined by the memory management library). The bad guy also cannot write whatever he wants into arbitrary memory locations. If he could, he would already have complete control over the process and wouldn't need to exploit anything.

      That's why this type of problem has typically been considered nearly impossible to exploit. There's too many variables that the attacker can't control (and memory management can be near downright non-deterministic if there's enough allocation / deallocation of various sized blocks going on). I'm very interested to see what they came up with. My guess is that it's something that can only apply in specific circumstances; i.e. a buffer for incoming data is allocated in a spot that used to be occupied by something else, and the design of the program makes it happen consistently.
    4. Re:What is this? by Anonymous Coward · · Score: 0

      Oh boy - it's Fun with Analogies time boys and girls!
      It goes something like this...
        - you install this fancy schmancy security system that you use to lock & unlock your front door.
        - At some point you decide you don't need this fancy schmancy security system any more and you tear the wires out of the wall.
        - The bad guy sees the wiring hanging out of the wall and decides to do some wiring of his own.
        - You go back and activate the security system again - even though you destroyed it. But now it unlocks your doors when you thought it should lock them.
        - Bad guys foooks you

    5. Re:What is this? by mr_mischief · · Score: 2, Informative

      I guess the issue is, since they say "predictably" instead of "always", that there's a decent probability when one takes automation of the exploit into account. Try this enough times, and eventually you get it to work. It only takes the one time to "pwn" the server.

    6. Re:What is this? by SloWave · · Score: 1

      Unless you have a 'key under the doormat' type of programmer writing your target code, how would you exploit the dangling pointer? First you would have to have some idea of where it pointed to. Then you would have to have write access to where it was pointed to be able to write your evil code there. Then you would have to have the application actually do a function call using that pointer. Most modern OS's are not going to let you do all three of the preceding. There may be some merit to allocating a large area of memory, filling it full of NOP's with the 'evil' code at the end. But you still have to get the application to jump or call somewhere in the NOP series, maybe by some sort of lucky jump with a random bad pointer. Does Microsoft still allow this kind of stuff?

  21. Not an Apache issue. by Ayanami+Rei · · Score: 3, Informative

    Apache doesn't really work in a way that leaves dangling pointers to exploit in the first place (resource pools). And since this requires code to be loaded at a specific point in memory, which then must be executed, it's going to be webserver-build and OS-specific, which leaves Apache in a good position since that varies across distributions and versions; the attack will be useless if grsecurity or other address randomization technique is used.

    IIS 5.1 and 6.0 is a smaller target space of possibilities.

    --
    THIS THING CAN TURN ON A DIME, MACROSSZERO STYLE ALSO FUCK BETA, ~NYORON
  22. "Security experts" that aren't by Schraegstrichpunkt · · Score: 4, Insightful

    From the article:

    Dangling pointers are quite common, but security experts and developers have said for years that there is no practical way to exploit them, so they've been considered quality-assurance problems and not security flaws.

    Any security expert with at least half a brain is going to assume that a remotely-triggered crash might be exploitable, unless he can actually prove otherwise.

    That said, I've known plenty "security experts" who weren't.

  23. A big "if" by SkyFalling · · Score: 1

    The article is a bit thin on the details of how the exploit works. Without some kind of explanation, I'm skeptical of the claim that this works for "any application in which there is a dangling pointer." In particular, note the quote that "[t]he long and short of it is, if you can determine the value of the pointer, it's game over." Okay, but I'm not in the habit of exposing pointer values to users, so if a user-visible pointer value is required for the exploit, that significantly reduces the set of apps to which this attack applies. The apparent overstatement degrades the overall credibility of the related claims. Also, I'm really curious why on earth it would matter that the pointer is dangling. A dangling pointer is a pointer that points to a resource that no longer exists -- and, therefore, to garbage memory. I'm assuming the attack involves writing arbitrary code to that garbage memory. The question is, why would such an attack rely on the memory being garbage, as opposed to a valid resource? If we're overwriting it anyway, why does it matter? Perhaps what really happens is that when you crash due to a dangling pointer, the resulting dialogue shows the pointer value, and this tells the attacker which location to overwrite for the next time. If that's the case, it strikes me as being just as obvious as, say, buffer overflow, and that dangling pointers are rather incidental. I guess we'll have to await the details to determine if there really is meat here, a legitimate new class of attacks, or just overstatement of something not at all new an exciting.

  24. AAARGH! by RAMMS+EIN · · Score: 1



    "Common programming error"?

    The foo! Just tell us WHICH error, will ya?!? /me calms down a bit

    Ok, I know a few lines further on they actually did, but the beginning just ticked me off. This is a bloody tech site, I'd think that some people here _would_ know what you're talking about when you say "dangling pointer".

    --
    Please correct me if I got my facts wrong.
  25. Re:What is this? - can we make it jump to code? by DogFacedJo · · Score: 1

    If a dangling pointer is followed into 'random memory' what are the odds it'll hit exploit code? Sometimes very low...
        Oftentimes, however, the original value was off of the heap, so if one can make the app allocate a whole bunch of memory there might be even odds that the pointer will now point into that memory. If that memory consists of a huge header which can be *entered at any point* (eg: big pile of nops) and forwards execution along to the end where one has the exploit code proper... then you have an exploit.

        See some other post about how to get from an ordinary pointer to an executable one (eg: a function pointer)... how rare are function pointers?

  26. how... by hey · · Score: 1

    How do they know its an dangling pointer?
    Could by anyone of a hundred possible bugs.

  27. Wrong terminology by klui · · Score: 1

    Those guys used the wrong term. When I hear dangling pointers, I often think structs that have pointers to other stuff and the struct has been freed before its pointers are freed. What these people say is dangling pointers are merely pointers to stuff that's been freed but the references have not been reset to NULL. Resetting them to NULL is basic C-programming 101.

    1. Re:Wrong terminology by mrseigen · · Score: 1

      The term I always have used (and heard used) for this is "wild pointers".

    2. Re:Wrong terminology by FunkyELF · · Score: 1

      Shouldn't whatever library implements the free() function set it to null?
      Is there any code out there that actually depends on retaining the value of somePointer after doing free(somePointer)?

    3. Re:Wrong terminology by spitzak · · Score: 1

      You and the parent are talking about the trivial-to-detect case.

      Setting the pointer to null does not really help in the real bugs, which are more like this:

          Foo* a = new Foo;
          Foo* b = a;
          delete a;
          a = 0; // as recommended above, big deal; // unfortunately b is still a dangling pointer!

    4. Re:Wrong terminology by SecurityGuy · · Score: 1

      Shouldn't whatever library implements the free() function set it to null?


      You'd have to redefine free(void*) to free(void**) in order to do this. Somehow, I think that would break a LOT of code.

  28. Dangling Pointers alone?? by FunkyELF · · Score: 1

    Is this a problem with Dangling Pointers alone or don't you also need some kind of buffer overflow to fill the place pointed to by the buffer?

    On Linux, I just ran "valgrind ls" and I saw the following...

    ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
    malloc/free: in use at exit: 23,673 bytes in 84 blocks.
    malloc/free: 136 allocs, 52 frees, 57,621 bytes allocated.

    Looks like ls has 84 allocs without free's....is this a problem?

    1. Re:Dangling Pointers alone?? by Chirs · · Score: 2, Interesting

      Nope, because they get freed when it exits.

      In short-running programs with no persistant side effects (sysv shared memory, semas, or msg queues, for instance) there's really nothing wrong with letting the OS clean up after you.

  29. Great... and how do you inject the code? by Mock · · Score: 1

    Great, so you find a dangling pointer. So what?

    Now you have to somehow fill that garbage location with code. How are you going to do that, except with another exploit? And if you've got an exploit to insert your own code into execution memory, why bother with a dangling pointer at all?

    The only way you're going to exploit a dangling pointer is if it happens to point to a memory location whose contents you can overwrite by some other means. That's a highly unlikely scenario.

    1. Re:Great... and how do you inject the code? by FunkyELF · · Score: 1

      Those were my thoughts exactly in the post above.

      Is a dangling pointer a pointer that wasn't free'd, or a pointer that was free'd but you keep the reference around anyway?

      If it is talking about a pointer that wasn't free'd, I didn't think that was a problem and it was common to do. Like I said in my post above, doing a listing in my home directory the ls command left 84 pointers un-free'd.

      If it is talking about a pointer that was free'd but you still keep a reference around, I don't see the problem in that either unless you're dereferencing it. But dereferencing something that is free'd is an error or bug in itself.

    2. Re:Great... and how do you inject the code? by bwcbwc · · Score: 1

      Well it depends where and what the pointer points to. After all, buffer overrun and printf exploits work because the user can use the program itself to place data into specific memory locations that cause the functions to misbehave predictably.

      The issue in this case seems to be that once the memory has been freed, any process can grab that memory via the OS. So if you write a program to grab all available free memory with a given byte pattern, you are guaranteed to place your byte pattern in that location. Then you could manipulate the behavior of the original process by giving it a particular data sequence that forces it to load and/or execute the code at the dangling pointer. It would require some careful coordination between the virtual address spaces of the two programs, and it would leave traces (spike in memory usage), but it's at least theoretically possible.

      Another possibility might be to use the original process to load data into the freed pointer, but this scenario would require the program to write a pointer that according to design would not be valid, without doing a new allocation and address assignment to it. The real flaw in this case wouldn't be the dangling pointer, but the write to unallocated memory.

      --
      We are the 198 proof..
  30. - It doesn't have to be a function pointer. by DogFacedJo · · Score: 5, Interesting

    In OO languages a pointer to an object works almost as well. The object pointed to in many implementations begins with a type field. This is usually a pointer to the class's virtual function table - usually implemented as a table of function pointers.
        That is to say - if the object is referenced through a bad pointer, *and executes* any methods of that object's type - then it could be used to run someone elses code. They'll need to have filled some memory with something that can be interpreted as a virtual function table that points at something that can be interpreted as code. Which is doable.
        If the processor/OS has set an app to able to write to it's executable memory, then it is vulnerable to this class of vulnerability.
        Many OS's and C++, Objective C and *java* implementations default to this.

    Pascal and perl used (maybe they still do) stubby things that required that the *stack* be executable, nevermind just data... *buffer overruns* are much easier when the stack is executable.

        Java is interesting. Modern VMs do a lot of dynamic optimization - this means that they write on code that is actually running. They need OS permission to do so (in decent OSs?) so now you *have* to give the VM's process that permission in order to run Java. Now any dangling pointers in the VM implemention are potentially exploitable. Or if the memory manager has a bug and improperly deallocates an object... Or if the application has to call a library and that library accidentally accesses a reference to an object that was already released by java. Or maybe the app calls the OS - and the OS has a dangling pointer (say to a data structure that the Java VM needed to allocate). If you can fill the Java heap with executable exploit data, then if someone, anyone, jumps into it - they are toast.

      I hope this helps. There is likely an actual paper that they will present. It will document one or several of the myriad ways to exploit dangling pointers - hopefully more efficiently than previously.

    1. Re: - It doesn't have to be a function pointer. by mark-t · · Score: 1

      True, but the code to be executed still has to already be there in the first place... unless the os/hardware combination permits areas of memory to be simultaneously both writeable and executable, which it was my understanding can be relatively easily avoided on most modern hardware.

    2. Re: - It doesn't have to be a function pointer. by DogFacedJo · · Score: 3, Informative

      Sure almost every *chip* is capable of preventing simultaneous write and execute... but it is rare for the OS to be configured that way due to the surprising number of applications that want to write on code. VMs, in particular - Java, flash, .NET, custom library loaders in databases and web-servers, script interpreters in any sufficiently fancy application often optimize by throwing in a little code generation.
          While, in theory, all this stuff can be done by only writing on code when it is created or loaded - and then changing the flags back to execute-only to run it... but big apps frequently want fine-grained control over which code to rewrite, and even the ability to patch instructions that another CPU might be about to execute.
          Why is this needed? Take an example - a VM wants to be able to recompile frequently executed code *after* startup - probably at a function/method level since code all over the place might be calling into any particular class implementation. Having recompiled the subject code - all the code running should be migrated over to the new faster implementation. If you have to *stop* the system every time you do this, a lot of the performance advantages of dynamic recompilation get eaten - and it totally bollixes 'realtime' implementations (so do most of the garbage collecters, but not *all* thankfully).
          So Either - the instructions that are calls to the old code have to actually be indirect off of function-pointers - always even for non-virtual code, and some big virtual function tables merely need to be updated on recompilation, or you allow static invocations - and have rewrite the call instructions underneath the running CPUs.
          Thing is - na indirect (or virtual) function call *is* slower than a direct one - an extra memory access is required, and in big apps it is not reasonably to assume that code will usually be in cache - an extra dependent memory access is *not* the 'one tick' that some theorists claim - it can hit many hundreds of ticks in pathological situations - without even hitting disk.
          So... while they don't *have* to have write on code ... big applications want it for performance reasons.

    3. Re: - It doesn't have to be a function pointer. by VertigoAce · · Score: 1

      DEP allows programs to create and execute code at run time. However, they must be sure to specify that the memory is executable. This is not the default when DEP is turned on for a program, so it'll break applications that assumed all memory is executable.

    4. Re: - It doesn't have to be a function pointer. by EdwinFreed · · Score: 3, Informative

      I'm not enough of a Perl expert to say anything about its implementation requirements, but there's nothing in the either original or Extended Pascal that requires code execute on the stack, at least not on most machines. If this technique is used it is almost always simply an implementation choice, nothing more.

      The place where this sort of trickery is useful in Pascal is when a routine passes a routine at an "inner" lexical scope to another routine. In order for the passed routine to access variables in its outer scope it needs a pointer to the stack frame of the containing (in the lexical sense) routine. This cannot be assumed to have anything to do with the routine that ends up calling the passed routine.

      One way to implement this is to have the code passing the routine to another routine build a stub on the stack that sets up the pointer properly before calling the real routine. The address of this stub is then passed instead of the actual routine's address.

      A much better way in most cases is to pass both the address of the routine and the pointer to the stack frame, either as two separate parameters or else as a pointer to a structure that contains both. (On OpenVMS, for example, such structures were called Bound Procedure Values or BPVs.) The routine that ends up calling the passed routine then uses the pointer in the bound procedure value to set things up for the actual routine before calling it.

      The main problem with this approach is that it is incompatible with how most non-lexically-scoped languages pass references to routines around. It can be done in such a way that things work as long as the passed routine doesn't actually use any variables in the outer scope, which is usually good enough. In any case, the risks of having the compiler always put code on the stack would seem to me to be much greater than this small inconvenience.

      I once wrote a routine (in VAX assembly) that acted as a shim between a Pascal routine passing a procedure or functon paramter to a routine in another language. This code used the BPV to construct a stub on the stack which it then passed along. This let me call, say, an quadrature routine written in FORTRAN with the function being integrated coded in Pascal. I used this trick very sparingly, however.

      As for Java, I'm not sure "interesting" is the right term. I've read through some descriptions of the tricks it uses and they frankly scare me.

    5. Re: - It doesn't have to be a function pointer. by DogFacedJo · · Score: 2, Interesting

      Definitely an implementation choice for Pascal - but it (according to legend) was not a *rare* one - especially on x86 era implementations. 'Trampolines' I heard they called those stubs... didn't recheck this, so feel free to enlighten me.

          BPVs... I had thought Pascal still used something similar, but double checking, it seems those were just a VMS-iness. Pascal's scoping certainly enabled some profound hells in my life ... it is truly amazing what an incompetent developer can do with what was at first glance merely an 'interesting' language feature...

          As for Java - in the context of wild jumps and security vulnerabilities, the crazy VM implementations floating around are _surely_ interesting. ;}

    6. Re: - It doesn't have to be a function pointer. by DogFacedJo · · Score: 1

      Yup - and on platforms where it is viable to allocate simultaneously writable and executable pages large application vendors (ie: big-code apps) are going to want to get permission to do so even where it involves getting admins to change default system-wide settings.

          Windows apps that want to write on code are so common that it is never going to be too hard to set up a legacy app to run with writable code - nevermind forcing the app to request the pages specially. On some platforms (OS-390?) it is never even going to be possible.

          DEP is not a panacea - it helps, but it is surprising how many apps want to do more than generate code only before or after they run it. ;} You can still exploit stack-based buffer-overuns on such platforms (yes, it is much, much harder)

          Personally, I like stacks that grow towards high memory - overruns hit locals, but not the frame... on the downside overruns can instead be used to *read* the contents of the stack and sometimes send them back to a remote attacker - revealing where the app's code got loaded into memory. If you know the app's current address, suddenly the attack that TFA describes gets very useful as you can use relatively common wild object de-references to point back into executable-land, at whatever pre-existing parts of the system you can find that will do something useful for you - and who's exact addresses you now know even though the system tried to be clever by loading both code and data at somewhat random offsets. ;}

    7. Re: - It doesn't have to be a function pointer. by Vintermann · · Score: 2, Informative

      http://gcc.gnu.org/onlinedocs/gccint/Trampolines.h tml

      It usually involves stack execution, but that can apparently be avoided with a little extra cost. It's not language specific, but compiler-specific.

      --
      xkcd is not in the sudoers file. This incident will be reported.
    8. Re: - It doesn't have to be a function pointer. by EdwinFreed · · Score: 1

      Fascinating - I had never heard the term "trampoline" used for these things before. One alternative to putting them on the stack is to put them on the heap, but you're still creating code on the fly, with all that implies.

      Separate data and instruction caches were a nonissue on the original VAXen, but at some point (VAX 8600 maybe? It has been a LONG time since I thought about any of this stuff) VAXes could potentially have problems along these lines. If memory serves, performing an REI instruction after constructing an appropriate PC/PSL on the stack would blow the cache and make this trick safe to use. But it really is better to find another way to get the necessary frame pointer to the inner routine.

      As for BPVs, I believe they were part of the "VAX Procedure Calling Standard", which defined how routine parameters were supposed to be passed around. The fact that all languages used the same calling conventions made writing code in a mixture of languages fairly straightforward. There were, however, various discrepancies, such as the fact that not all languages used BPVs. So things like passing routines as parameters sometimes required some care. For example, in VAX Pascal you could use the [unbound] attribute to tell the compiler not to generate a BPV.

      Then along came the Alpha and all this stuff changed. I never got as involved with Alpha code as I did with the VAX, but I think the way this worked was a trampoline-like preamble was inserted just before each nested routine that got passed as a parameter. A direct call would go to the normal start address for the routine but the passed address would be to this preamble that pulled the frame pointer out of the procedure descriptor and put it in R1.

      And all this even worked in VAX executables translated for use on the Alpha. Neat stuff.

  31. Exploit by Anonymous Coward · · Score: 3, Interesting

    After discussing it with a fellow developer, here's what we thought might be happening:
    1. Application allocates a C++ object, deletes it, but continues to point to it. The exploit code is likely to force this condition. The attacker has to know the type (and size) of the C++ object.
    2. Exploit code sends a packet to the server causing it to allocate memory of exactly the same size as the C++ object that was deleted and store the exploit payload in that memory. For example, in case of a web server it might be an HTTP request of size X or an HTTP request with multiple HTTP headers of size X, depending how the implementation stores whatever it receives on port 80.
    3. The heap allocation algorithm would presumably re-use the space that was deallocated when the C++ object was deleted. The exploit payload is copied over into the allocated buffer, examined and discarded (e.g. the payload is not valid HTTP). This is OK since the dangling pointer is still pointing to the memory area with the exploit payload.
    4. Now the exploit causes the dangling pointer to be used to reference a virtual function and it's game over.

    The exploit payload needs to act like a virtual table. It can reference exploit code in itself or jump somewhere in the running process which would make it exploitable (e.g. "DeinitializeSecurity" function).

    Hopefully the paper is more interesting than this.

  32. This is the real world. by Valdrax · · Score: 1

    I'm guessing you've never worked on a large product that's released to end-users and has release deadlines that should avoid slipping. Bug triage is exceptionally common on such projects. Nobody fixes every last bug before release, and I've had five year old low-priority bugs that were still on my to-do list when I left the last company I worked on that had such a product.

    What you spend your time on is finding and fixing the critical bugs, followed by the high priority bugs, follow by the mediu-- oh, hey wait, someone added new features and there's a host of new bugs to fix. Yay!

    I wish I was wrong, but this is how the real world works most of the time. I'm kind of glad to have spent the past few years on internal-use only applications.

    --
    If it's for-profit but free, you're not the customer -- you're the product (e.g., the Slashdot Beta's "audience").
  33. What multiple versions? by Anonymous Coward · · Score: 0

    IIS 6.0 came out in 2003 (Windows Server 2003, Windows XP Pro x64) (and appears to be unaffected).
    IIS 7.0 was just released in Vista, and the Upcoming Windows Server 2008 (and appears to be unaffected).

    MS released a patch for IIS 5.1, which is only on Windows XP Pro (32Bit) Service Pack 2.

  34. From TFA... by Sebastopol · · Score: 4, Funny

    "This is a bit of a Pandora's box and once we open it, it will be just the tip of the iceberg."

    Did anyone else think:

    "If we hit that bullseye, the rest of the dominoes will fall like a house of cards! Checkmate." - Zapp Brannigan

    --
    https://www.accountkiller.com/removal-requested
    1. Re:From TFA... by Esion+Modnar · · Score: 1

      I had no idea Pandora's box was so big. OK, that sounded wrong. Lost my keys in there and everything. Giggity.

      --

      They say the first thing to go is your penis. Well, it's either that or your brain. I forget which...
    2. Re:From TFA... by userlame · · Score: 1

      SONOFA!

      I tried to mod your post funny, but missed and hit overrated. I'm posting to make that go away. Oops!

  35. Anybody know how this is done? by Jeremi · · Score: 1

    Can anybody hazard a guess as to how this exploit is done? As it says in the article... once you know what the value of the dangling pointer is, how do you (a) get your root-shell code into that address, and (b) get the target computer to start executing code at that address?

    --


    I don't care if it's 90,000 hectares. That lake was not my doing.
    1. Re:Anybody know how this is done? by rewt66 · · Score: 1

      I am completely guessing.

      But from the article, they had to hit IIS with a specially-crafted URL to exploit this. So, let's see, what can we do with a specially-crafted URL? We can do shell code into a buffer. If we know where the dangling pointer points, and where incoming URLs are placed, we might even be able to get our shell code where the dangling pointer points to. Then all we have to do is get the pointer called (assuming it's a function pointer... maybe a bad assumption). This could be done with another, immediately-following request, or it might happen automatically (if we can also make the circumstances that cause the pointer to be called occur with the same URL without messing up the shell code).

      If it's a data pointer, I think it still depends on getting part of the URL into where the data pointer points. Say it points to a structure, and in that structure is a text buffer, and also in it is a function pointer. Now we can call an arbitrary function anywhere in ISS's memory image, with arbitrary data. That's got to be pretty easy to exploit. Once again, though, we also have to get the pointer used.

      So as far as I can see, there are two things that are needed - being able to get the data from the URL into the memory where the dangling pointer points, and getting the pointer to be used. How you have to do those things will be highly application-specific, I would imagine...

    2. Re:Anybody know how this is done? by Dr_Barnowl · · Score: 1

      If the pointer dangles in an area of memory that is now being used as an input buffer, overrun or not, that's step (a). Find an execution path which writes an input buffer to the memory the pointer previously referenced (and still does).

      If there is a dangling pointer bug that is caused by branching execution to that dangling pointer, which normally would cause a crash, then that's your step (b) - find the crash, find an execution path that writes an input buffer over the dangling pointer, then run the crashing code again. The path now goes through your malformed buffer instead of the original code, grabbing control of the process.

  36. Re:wow by Goaway · · Score: 1

    Wow, a slashdotter doesn't understand an article but still feels the need to post about how he's much smarter than everyone else.

  37. I don't follow this at all. by seebs · · Score: 1

    It's not unheard of to not bother zeroing out a pointer if you're never going to look at it again without reinitializing it.

    What I'm not able to conceive of is any possible code path where:
    1. This would be exploitable.
    2. It wouldn't just crash if you'd zeroed out the pointer.

    I don't generally dereference pointers after freeing them. So far as I can tell, you'd have to for this to work.

    --
    My blog: http://www.seebs.net/log/ --- My iPhone/iPad app: http://www.seebs.net/seebsfrac/
  38. O.K, Clark, i think we understood .. by Anonymous Coward · · Score: 0

    > I dunno. I manage to write C++ and never overflow a buffer, always release all resources
    > when I'm done with them, and never throw away an error. Why can't the other 95% of the
    > programmers out there do the same thing?

    Now please go into your phone booth and change back into civilian clothes!

    Thank You!

  39. Not news for Mozilla by jesser · · Score: 4, Informative

    Mozilla has considered dangling pointer use to be "probably exploitable to run arbitrary code" for a long time. I even blogged about that fact, describing what types of dangling point use are most likely to be exploitable. If other software companies refuse to prioritize those bugs until the reporter supplies a demonstration exploit that launches calc.exe or Calculator.app, they've been asking for trouble for years.

    --
    The shareholder is always right.
  40. Re: - What about C# by slickwillie · · Score: 1

    Anyone know how C# works, and if it will also have the problem?

  41. GC does eliminate bugs by Peaker · · Score: 3, Interesting
    Leaks are logical bugs, not memory management bugs, so ofcourse GC does not eliminate them.

    GC does eliminate a few classes of bugs:
    1. A specific kind of memory leak: Of ceasing to hold references to an object, but not freeing it.
    2. Pointer arithmetic and forging is impossible, so objects cannot override each others' memory. This kind of bug creates cryptic problems that are pretty hard to debug, as they are not easily contained in a single component.
    3. In manually-managed languages, leaks can cause crashes, security problems and memory overruns, while GC converts this to an "object leak". Object leaks usually translate to a memory leak (hog problem) and only rarely cause very serious problems (as in your example of leaking /etc/passwd).
    1. Re:GC does eliminate bugs by Vintermann · · Score: 1

      The kind of resource leak where you happen to keep around references for longer than you need, so they don't get GC'ed, is not really a memory leak, is it? I believe it's called a space leak, not a memory leak.

      --
      xkcd is not in the sudoers file. This incident will be reported.
    2. Re:GC does eliminate bugs by JesseMcDonald · · Score: 1

      Pointer arithmetic and forging is impossible, so objects cannot override each others' memory. This kind of bug creates cryptic problems that are pretty hard to debug, as they are not easily contained in a single component.

      This is true of many garbage-collected languages (e.g. Java), but it is not a property of garbage collection per se. For example, there are garbage-collection libraries for C, but they do not prevent you from doing pointer arithmetic or creating pointers to any addresses you wish. The difference is that C has a native pointer type and pointer dereferencing, whereas Java does not -- a language design issue unrelated to garbage collection. It makes Java safer, but less suitable for the sort of precise low-level programming C excels at. A language with only object references and no pointers could be designed to require manual memory management rather than performing GC; it's just very uncommon.

      --
      "The state is that great fiction by which everyone tries to live at the expense of everyone else." - Bastiat
  42. memcpy is the answer by r00t · · Score: 1

    If you forgot the length/size, you can't be safe.

    If you do have the length/size, you have the info needed to use memcpy. This is faster then strcpy, and often much faster than strcat or sprintf.

  43. Re:does anyone know by Anonymous Coward · · Score: 1, Funny

    Given the moderation on your post I'd say it worked quite well...

  44. (ans) Re:I don't follow this at all. by cdn-programmer · · Score: 1

    The reason you don't follow this is because a good programmer will know when the memory is released that the pointer is not going to be used again so its contents become a don't care.

    A bad programmer releases the memory but doesn't really check if the pointer will or will not be used.

    A crash occurs if some function tries to use the pointer when it is not valid to use it. An exploit occurs if you load the proper data via normal load procedures such as asking a web server to say load a jpeg and the jpeg is coded as a jpeg and looks like a jpeg but contains a segment of code in a location which is determined by the particular buggy program in question.

    Once the code is in the machine then the next step is to cause the errant program to execute the improperly coded function which is often an error handler which typically get written and never checked out properly.

    One way around this is trivially simple. Free the memory and set the pointer to null. Of course there can be other pointers which are set. One can have several pointers to a chunk of memory. Sometimes this is the _only_ way to do a task efficiently. A for instance is scanning a list and returning the address of the item found.

    Of course this can easily be handled by prudent programming practices. One needs to understand that a list is an object. As such its FIRST word should be its status. This is ALWAYS the case. If zero then the status is normal. If no-zero then its an error or a warning and its programmer's glory how this is set up.

    Then, Any function that needs to work with the list needs the list address and the address of say an item in the list. Any code using the address of an item must check the list status first.

    A simple way to do this with a dynamic list in say shared memory would be to put an interator on the list which increments each time there is a modification to the list. Then the address of an item which should also be seen as an object would have the list iteration number as part included with the address of the item in question. By doing this any code needing to process the item which was for instance looked up by helper functions will know if the list is valid for the item being referenced.

    Of course. Most programmers I know don't do this. They write buggy code.

    Most people I know go by the idea that if something works its good enough. A serious and professional programmer must change this to the mathematical standard which is we must be able to prove it cannot fail.

    I am a manager and an employer and a businessman. This is probably pretty close to the correct order but the vast majority of businessmen are salesmen and they look for the money first. Any programmer working for one will be constantly under pressure to do it fast and we can fix it later.

    Think of this as brain surgery. Would you want the surgeon to do it fast and suggest it can be fixed later?

  45. A couple mistakes there.. by Anonymous Coward · · Score: 0
    Mistake #1: You're assuming he read the article.
    Mistake #2: AC isn't a slashdotter, he's less than nobody.
    Mistake #3: Arguing on the internet.

    I think that's enough points to prove I'm smarter than everyone else, too! Isn't the Internet fun?

  46. Steady, boy! by Gotebe · · Score: 1

    So... You never had a correct unit test that fail to find a problem in its unit after the change was made in seemingly unrelated piece of code? You program C++ and deal with str(n)cpy? What kind of 80's C++ is that? You only need to deal with type correctness, never with integral overflows? Get off the high horse, man!

    1. Re:Steady, boy! by 19thNervousBreakdown · · Score: 1

      The seemingly unrelated piece of code has its own unit test, which 99% of the time catches behavior changes. No, I haven't used strcpy() since I had to do a small project in C. I have to deal with integral overflows, but the idea is to check for them, and catch them before they happen. Look up SafeInt, I have a custom version of that that actually gets its type information from #include <limits> so even if I'm rushing I can just wrap it in that and get an error during testing because I tried the function with numeric_limits::max() and friends, instead of weird sporadic errors 8 months later. This is walking across the room stuff, friend.

      --
      <xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
  47. C/C++ is responsible for many things by master_p · · Score: 1

    I do not disagree with folks that say that programs are as good as their programmers. It's true, no one can dispute that. But it takes God-like programmers to make a C/C++ application of many thousands of lines of code without errors like buffer overflows and dangling pointers. In other words, only 10% of the programmers out there are capable of producing very good C/C++ programs. With Java, the number rises to maybe 50%, thanks to garbage collection.

  48. Dot Net apps immune? by serutan · · Score: 1

    The article mentions that Java apps are not targets for this exploit because Java has built-in garbage collection. Wouldn't this also be true for .Net apps?

  49. C is "Programming without a net" by garyebickford · · Score: 1

    Too true - for most purposes the programmer should not have to worry about such things. This is a failing of C/C++ which makes it inappropriate for most software development. Using languages more appropriate for typical applications, it is not impossible to go for years without a segfault. There are reasons why so many programmers work in interpreted environments such as Perl, PHP, Ruby, Lisp, Haskell, etc. - beyond each language's particular strengths these languages provide fundamental productivity and security advantages over low-level languages.

    I used to teach a software quality assurance workshop, and in the course of collecting information for the class found substantial research showing that, regardless of programming language (from assembler to 4G languages), given 'good' programming practice (structured design and programming and walkthroughs among other things - this was a while back), on average there was one bug every 200 lines of production, released code. About 70% of these bugs were in the original design. That means 30% were actual coding errors. The research was performed in large scale, corporate, government and military related projects. I've probably still got the book somewhere ...

    At that time it was also found that a team could produce, on average, about one line of production-release code per person-hour (this includes planning, design, testing, documentation, etc.). Actual coding accounted for about 15% of the total number of person-hours IIRC.

    Many modern languages provide much better support for the programmer, and any possible performance advantage of bare-metal programming is no longer very relevant. Today even 'bare-metal' programming usually isn't, because processors now have their own memory management, CPU load management, etc. and the OS and auto-loaded libraries take up 95% of the slack. Much of the original domain of C (described once as "structure PDP-11 Macro assembler", I think by Kernighan or Richie) is now the domain of Intel and AMD processor hardware design teams, and to some extent Linus and friends.

    Embedded processor systems may or may not require this low level access; operating system kernel programming may or may not. There is an arguable case for an OS to be built as a microkernel written close to the hardware, with a userland programming environment based a modern interpreted language - Mach + Java, or Mach + LISP could be exemplars.

    [I am not a LISPer, but I am reminded of the remark that "all languages evolve over time to emulate LISP - badly." (source??) Maybe it's true.]

    Therefore IMHO, C (or C++) is no longer the most appropriate tool for most programming applications. It may be necessary for coding to hardware, but for general applications there is no longer any excuse for using a language that does not prevent such basic problems, and requires so much of the programmer's mindshare for such low-level problem prevention. This link provides some perspective. (I was unable to find the original citation for the phrase "programming without a net".) If I can perform a complete HTTP access of a document and retrieve all the ancillary files using a single function call, then I have saved hundreds of lines of code, each with its bug probability, and saved many hours of coding.

    By way of analogy, at one time it was necessary to adjust the spark gap differently for starting vs. running an automobile engine (Ford Model T). Tire patching was an every-20-miles event. As things advanced, shifting gears no longer required double clutching due to synchromesh, then automatic transmissions took gear management out of the problem space. As automobiles advanced, the number of things that had to be manually dealt with has continually been reduced, or rather moved up the scale of complexity - nowadays we spend more time managing our traffic environment and looking at the moving map GPS display than we spend manag

    --
    It's easier to be a result of the past, but more fun to be a cause of the future! http://www.spacefinancegroup.com/
    1. Re:C is "Programming without a net" by jddunlap · · Score: 1

      This is a failing of C/C++ which makes it inappropriate for most software development.
      That's right. Blame the language for the programmer's ineptitude. That's like saying the Linux bash shell is critically flawed because it doesn't protect them from their own stupidity when they are logged in as root... Do you even realize that the languages you're trumpeting use pointers on some level, just like C++? The only difference is that they are accessed through an abstraction that prevents the programmer from ganking himself. Ironically, the odds are that the implementation of that abstraction was written in C++!!! So you're basically saying that the solution to the problems with C++ is a language that's implemented in C++... What!?!!?

      I've personally written C++ classes for handling associative arrays, large numbers(in the thousands of bits), typeless datatypes, and automatic pointer deallocation. The problem isn't the language. The problem is that no one bothers to learn how to use it.

      If you can't keep track of your pointers write some template classes to do it for you. To lazy to do that? No worries!!! Boost.org has a complete library of smart pointers freely available for download!!!!

      http://boost.org/libs/smart_ptr/smart_ptr.htm

      P.S.
      Please don't respond with something like, "C++ can't to this: " That is a complaint about libraries and not the language itself. Complaining that a platform dependent API is not part of the standard C++ library is little more than ignorance. If you need such an API, go find one and install it.

      Please don't respond with, "It's hard to do stuff with C++!" No it isn't. I get so tired of that one. It's like listening to an 9th grader saying that math is too hard for mere mortals but, when asked, he hasn't done his homework in 2 months.
    2. Re:C is "Programming without a net" by Ciarang · · Score: 1

      You make some good points. However, if your software is intended for mass use, then the answer to "Are there any reasons to forgo the productivity advantage of using a higher level, interpreted language?" is ALWAYS a resounding "Yes" in my mind. (I am ignoring profit of course, which is what has driven everything to the lowest common denominator, but anyway...)

      Unlike your car analogy, where the benefits of making the car easier to drive are multiplied across everyone who drives it, software is completely the other way round. Every performance trade-off made at the development end to save time in coding it well is multiplied exponentially. Not just by the number of users that use it, but the number of times it runs as well. The effects are manifested in:

      a) wasted time - I spend a horrific percentage of my day idling, waiting for Visual Studio .NET to do whatever the hell it's doing, and yes, I see the hypocrisy in that, but it pays the bills
      b) wasted electricity - adds up very fast I reckon, does someone want to calculate the global cost of even an extra 1% CPU usage in a version of Windows multipled over the number of users?
      c) wasted opportunity - What would this incredible machine in front of me be capable of if it wasn't crippled by the monkey-coded bloatware running on it? It can't even keep up with me typing, for crying out loud!

      The vast majority of PCs in the world (think 'office user') aren't being used to achieve ANYTHING that their equivalents 15 years ago weren't doing, and the only obvious difference, eye-candy aside, is that they're now slower and less stable.

      Many are going to scoff at this, but I speak from experience, so I don't care - it is NOT impossible to write a huge application in assembler, never mind C, that can "go for years without a segfault". It's not even hard. It simply takes people who know what they're doing, and who haven't been brainwashed into thinking it can't be done. Mod me insane, but I find the opposite to be true, i.e. the higher level the language, the less basic understanding is required, and the more idiocy is perpetrated with it.

    3. Re:C is "Programming without a net" by jddunlap · · Score: 1

      Many are going to scoff at this, but I speak from experience, so I don't care - it is NOT impossible to write a huge application in assembler, never mind C, that can "go for years without a segfault". It's not even hard. It simply takes people who know what they're doing, and who haven't been brainwashed into thinking it can't be done. Mod me insane, but I find the opposite to be true, i.e. the higher level the language, the less basic understanding is required, and the more idiocy is perpetrated with it. Scoff at it? Quite the opposite. Programmers that never leave their high level environments live a very sheltered existence and never gain even a basic understanding of the underlying hardware. If you ask the average programmer what a stack frame is he'll look at you like you're speaking in Manderine Chinese. Add to that that you're at the complete mercy of the authors of your interpreter and I would venture to say that if you are MORE likely to crash using a high level language than you are with a low level language if only because there are more more things that can and do go wrong.
  50. A.I. by Anonymous Coward · · Score: 0

    heyya, this exploit or feature?
    maybe core A.I. routine can use this?

    you know that "it's on the tip of my tongue, but i can't utter it" feeling?

  51. There's a thing called a destructor. Use it... by jddunlap · · Score: 1
    1. Re:There's a thing called a destructor. Use it... by znx · · Score: 1

      I have never seen that before, it will be making its way into my code in future. This is the sort of library we need, something that manages all the garbage for us less fortunate coders.

      --
      BOO