Stories
Slash Boxes
Comments

News for nerds, stuff that matters

Slashdot Log In

Log In

Create Account  |  Retrieve Password

33-Year-Old Unix Bug Fixed In OpenBSD

Posted by kdawson on Tue Jul 08, 2008 07:10 PM
from the yet-another-stack-overflow dept.
Ste sends along the cheery little story of Otto Moerbeek, one of the OpenBSD developers, who recently found and fixed a 33-year-old buffer overflow bug in Yacc. "But if the stack is at maximum size, this will overflow if an entry on the stack is larger than the 16 bytes leeway my malloc allows. In the case of of C++ it is 24 bytes, so a SEGV occurred. Funny thing is that I traced this back to Sixth Edition UNIX, released in 1975."
+ -
story

Related Stories

[+] IT: The 25-Year-Old BSD Bug 213 comments
sproketboy writes with news that a developer named Marc Balmer has recently fixed a bug in a bit of BSD code which is roughly 25 years old. In addition to the OSnews summary, you can read Balmer's comments and a technical description of the bug. "This code will not work as expected when seeking to the second entry of a block where the first has been deleted: seekdir() calls readdir() which happily skips the first entry (it has inode set to zero), and advance to the second entry. When the user now calls readdir() to read the directory entry to which he just seekdir()ed, he does not get the second entry but the third. Much to my surprise I not only found this problem in all other BSDs or BSD derived systems like Mac OS X, but also in very old BSD versions. I first checked 4.4BSD Lite 2, and Otto confirmed it is also in 4.2BSD. The bug has been around for roughly 25 years or more."
This discussion has been archived. No new comments can be posted.
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More
Loading... please wait.
  • by Anonymous Coward on Tuesday July 08 2008, @07:12PM (#24108651)
    Wouldn't want to let anyone take over your system with yacc. Seriously.
    • by slew (2918) on Tuesday July 08 2008, @07:15PM (#24108701)

      Wouldn't want to let anyone take over your system with yacc. Seriously.

      But ./ is already taken over with yak. Seriously.

    • by Anonymous Coward on Tuesday July 08 2008, @07:28PM (#24108811)

      Who cares about OpenBSD yacc? BSD is dying and Netcraft confirms it. The world has moved to GNU/Linux and Bison.

        • by msuarezalvarez (667058) on Tuesday July 08 2008, @10:07PM (#24110899)
          So you are including bison in your own apps and its `bloatedness' becomes a problem? Maybe you should read the manpage...
        • Re:Time to patch (Score:4, Interesting)

          by setagllib (753300) on Tuesday July 08 2008, @11:43PM (#24111795)

          Who cares? Like GCC versus TinyCC, being bloated means it can produce a more useful output. GNUware can be faulted for being heavy compared to traditional Unix tools, but the functionality and flexibility provided more than makes up for it.

          Except for autotools. What the HELL were they thinking.

        • by setagllib (753300) on Tuesday July 08 2008, @11:47PM (#24111833)

          Ah, but it would be written as a J2EE application. And the input wouldn't be .y, it'd be an XML document. And the output wouldn't be C, it'd be another XML, passing through a terabyte of XSLT. Then you pass this compiled parser XML, only a gigabyte in size, and your language file to a parser web service and it returns even more XML representing the parse tree.

          Ahh, progress.

          • by TapeCutter (624760) * on Wednesday July 09 2008, @04:43AM (#24113985) Journal
            Great post, I'm still laughing as I type.

            Speaking of old bugs the guy who sits next to me at work hooked a 15yo mainfame bug a few months back. His stock comment whenever someone mentions it is: "Three more years and that one would have been old enough to vote!"
  • by Yold (473518) on Tuesday July 08 2008, @07:13PM (#24108669)

    Unix beards were Unix stubble

  • bad omen (Score:5, Funny)

    by spir0 (319821) on Tuesday July 08 2008, @07:17PM (#24108709) Homepage Journal

    a 33 year old bug, plus a 25 year old bug (http://it.slashdot.org/article.pl?sid=08/05/11/1339228)....

    if we keep going backwards, will the world implode? or will daemons start spewing out of cracks in time and space?

    • Re:bad omen (Score:5, Funny)

      by je ne sais quoi (987177) on Tuesday July 08 2008, @07:30PM (#24108835)
      Nah! What this means is that they are fixing bugs faster than they're making new ones. If they weren't, they'd spend all their time chasing the newest ones. :)
      • Re: (Score:3, Insightful)

        Or we're so painfully slow with fixing bugs that we JUST got around to 1975 :P There are always multiple views :P
    • Re:bad omen (Score:5, Funny)

      by exley (221867) on Tuesday July 08 2008, @07:41PM (#24108935) Homepage

      a 33 year old bug, plus a 25 year old bug (http://it.slashdot.org/article.pl?sid=08/05/11/1339228)....

      if we keep going backwards, will the world implode?

      Well since time began only 38.5 years ago we should find out the answer very soon!

    • Re:bad omen (Score:4, Funny)

      by Dunbal (464142) on Tuesday July 08 2008, @09:03PM (#24110003)

      or will daemons start spewing out of cracks in time and space?

            I finally figured out what the UAC were doing on the Mars colony... and it had nothing to do with those artifacts!

            Thank god there's a division of Space Marines there...

    • Re:bad omen (Score:5, Interesting)

      by K. S. Kyosuke (729550) on Tuesday July 08 2008, @09:17PM (#24110199)
      First it was a fourth of a century, then it was a third of a century. The only logical consequence is that the next bug they will find now will be a memory leak in McCarthy's Lisp intepreter from '59 or some strange corner case in the Fortran I compiler. (Oh, and after a careful consideration, I am leaving the *next* bug as an exercise to the reader.)
    • Well since bugs before the epoch [wikipedia.org] were actual insects, judging by past precedent they'll get super powers... like wall-climbing ability or maybe spidey senses ??

    • Re:bad omen (Score:5, Funny)

      by menace3society (768451) on Tuesday July 08 2008, @11:02PM (#24111445)

      The next bug will be in Boolean logic. After that, OpenBSD devs will start fixing structural engineering errors the Tower of Pisa.

  • Great! (Score:5, Interesting)

    by Anonymous Coward on Tuesday July 08 2008, @07:18PM (#24108713)

    Any word on when they're going to fix the even older "Too many arguments" bug?

    Sorry, but any modern system where a command like "ls a*" may or may not work, based exclusively on the number of files in the directory, is broken.

    • I too was devastated to learn that my poor Linux box can only handle 128KB of command line arguments [in-ulm.de]. How can I possibly finish typing in that uncompressed bitmap...
        • Re:Great! (Score:5, Funny)

          by menace3society (768451) on Tuesday July 08 2008, @11:10PM (#24111523)

          Burn the contents of the tar archive onto a CD. Mount the CD over the original directory structure. Use find(1)'s -fstype option to locate all the files that aren't on the CD, copy them to an empty disk image, then eject the CD. Remount the disk image over the original directory, delete all the files in the directory, then unmount the disk image. The files identical in name to those that were on the disk image (which are those that weren't on the CD) won't be deleted thanks to the peculiarities of mount(2).

          You're welcome.

          • You forgot "Er.". All Linux advice must contain "Er." at the beginning of the first sentence in order to signify the fact that the poster should have already known how to do this rather than asking this question.

          • Re:Great! (Score:4, Funny)

            by maztuhblastah (745586) on Wednesday July 09 2008, @09:39AM (#24117427)

            So Saturdays at your house must be a real blast, huh?

        • Re: (Score:3, Informative)

          I only want to delete files I'm sure are in the archive. How would I do that?


          tar tf archive.tar | while read FILENAME ; do
              rm "$FILENAME"
          done

    • Re:Great! (Score:5, Informative)

      by Dadoo (899435) on Tuesday July 08 2008, @08:16PM (#24109285) Journal

      While I'm sure you're trolling, I feel I should point out that, 1) I agree with you, and 2) this has apparently been fixed, on Linux:

              http://agnimidhun.blogspot.com/2007/08/vi-editor-causes-brain-damage-ha-ha-ha.html [blogspot.com]

    • Re:Great! (Score:5, Interesting)

      by Craig Davison (37723) on Tuesday July 08 2008, @09:23PM (#24110285)

      If "ls a*" isn't working, it's because the shell is expanding a* into a command line >100kB in size. That's not the right way to do it.

      Try "find -name 'a*'", or if you want ls -l style output, "find -name 'a*' -exec ls -l {} \;"

      • Re:Great! (Score:5, Informative)

        by Just Some Guy (3352) <kirk+slashdot@strauser.com> on Tuesday July 08 2008, @11:18PM (#24111601) Homepage Journal

        if you want ls -l style output, "find -name 'a*' -exec ls -l {} \;"

        Yeah, because nothing endears you with the greybeards like racing through the process table as fast as possible. Use something more sane like:

        $ find -name 'a*' -print0 | xargs -0 ls -l

        which only spawns a new process every few thousand entries or so.

        • Re: (Score:3, Informative)

          On modern systems, find -name 'a*' -exec ls -l {} +

          Personally, however, I prefer find -name a\* -exec ls -l {} +

          Also, you probably want to add a -type f before the -exec, unless you also want to list directories.

          Either that, or make the command ls -ld to not list the contents of directories.

      • by billstewart (78916) on Wednesday July 09 2008, @01:11AM (#24112601) Journal

        You're correct that's it's not the right way to do it. The problem is *why* it's not the right way to do it. It's not the right way to do it because the arg mechanism chokes on it due to arbitrary limits, and/or because your favorite shell chokes on it first, forcing you to use workarounds. Choking on arbitrary limits is a bad behaviour, leading to buggy results and occasional security holes. That's separate from the question of whether it's more efficient to feed a list of names to xargs or use ugly syntax with find.

        Now, if you were running v7 on a PDP-11, there wasn't really enough memory around to do everything without arbitrary limits, so documenting them and raising error conditions when they get exceeded is excusable, and if you were running on a VAX 11/780 which had per-process memory limits around 6MB for some early operating systems, or small-model Xenix or Venix on a 286, it's similarly excusable to have some well-documented arbitrary limits. But certainly this stuff should have been fixed by around 1990.

        • Soft limits can actually mitigate bugs. If we limit processes by default to 1,024 file descriptors, and one of them hits the limit, that process probably has a bug, and would have brought the system to its knees had it continued to allocate file descriptors. Programs designed to use more descriptors could to increase the limit.

        • Re: (Score:3, Informative)

          Instead of "ls a*"? Seriously? Hopefully, someone will mod you funny.

          Unix has extremely low overhead spawning processes. If you prelink and have a little cache this is plenty fast :P

          Seriously though, this is a serious annoyance in the way Unix does business. Shell globbing is very convenient for programmers, but not so convenient for users in an awful lot of situations.

      • I'll catch myself before someone else does. Everything I said above is true, except that ls isn't complaining. The OS, specifically exec() and friends, is complaining because the command line length when the shell expands the wildcard exceeds ARG_MAX. Increase ARG_MAX if you want to allow more files, or use a variation of find with the -exec option or xargs, etc.
  • Was this a bug when it was originally written, or is it only because of recent developments that it could become exploitable? For instance, the summary mentions stack size. I could imagine that a system written in 1975 would be physically incapable of the process limits we use today, so maybe the program wasn't written to check for them.

    Does your software ensure that it doesn't use more than an exabyte of memory? If it doesn't, would you really call it a bug?

    • by QuantumG (50515) * <qg@biodome.org> on Tuesday July 08 2008, @08:43PM (#24109711) Homepage Journal

      If you overflow a buffer then it's a bug, whether it is exploitable or not.

      • by russlar (1122455) on Tuesday July 08 2008, @09:18PM (#24110217)

        If you overflow a buffer then it's a bug, whether it is exploitable or not.

        If you can overflow an exabyte-sized memory buffer, you deserve a fucking medal.

      • Re: (Score:3, Interesting)

        If you overflow a buffer then it's a bug, whether it is exploitable or not.

        It is today, but my questions is whether it was even overflowable (is that a word?) when it was written. For example, suppose it was written for a 512KB machine and had buffers that could theoretically hold 16MB, then it wasn't really a bug. The OS itself was protecting the process by its inability to manage that much data, and it wouldn't have been considered buggy to not test for provably impossible conditions.

        I'm not saying that's what happened, and maybe it really was just a dumb oversight. However,

    • Re: (Score:3, Informative)

      It would have been a bug, but not necessarily one that would have security implications, though that could be system-dependent. The summary mentions a specific malloc was used to get a segfault. Another malloc library may well not have faulted. That would only matter if it was possible via the buffer overflow to get yacc to do something (such as run your code) with privileges other than those you would ordinarily have had.

      Now, looking at it just as a bug, if the yacc script overflowed the buffer, yacc can

  • Hilarious! (Score:5, Funny)

    by BollocksToThis (595411) on Wednesday July 09 2008, @12:06AM (#24112023) Journal

    Funny thing is that I traced this back to Sixth Edition UNIX, released in 1975

    My sides are completely split! Invite this guy to more parties.

    • I bet you they're not talking about the system stack pointer. Remember, yacc is a parser generator; parsing algorithms always use some sort of stack data structure. So, the "stack pointer" in question is just a plain old pointer, pointing into a stack that yacc's generated code uses.

        • Re: (Score:3, Informative)

          Actually, the [] operator of an STL vector doesn't throw any exceptions, and will happily allow you to reference an index which is out of bounds.

          That's not a bad thing, because it's more efficient when you already know that your index is in rage. But if you don't know that, you're better off using the at() function.

            • Re: (Score:3, Informative)

              Best of all, even if you use assert() (or similar) for really explicit bounds checking, GCC will omit it from code paths where it's deemed to be unused. So if your accesses are being inlined (and if they're not, take a long hard look at your life) then the already-safe paths won't have the check overhead even in a debug build.

              Yes, I've tested it. Yes, it's impressive.

            • From the link you cited:

              By 1971, our miniature computer center was beginning to have users. We all wanted to create interesting software more easily. Using assembler was dreary enough that B, despite its performance problems, had been supplemented by a small library of useful service routines and was being used for more and more new programs. Among the more notable results of this period was Steve Johnson's first version of the yacc parser-generator [Johnson 79a].

              The code for yacc was certainly not originally written in c - c didn't exist at that time.

              In 1978 Brian Kernighan and I published The C Programming Language [Kernighan 78]. Although it did not describe some additions that soon became common, this book served as the language reference until a formal standard was adopted more than ten years later.

              The "archaic behaviour" was never part of that standard - it was a mistake in early implementations while they were still "working out the details" of the language, well before K & R, as Ritchie says:

              After the TMG version of B was working, Thompson rewrote B in itself (a bootstrapping step). During development, he continually struggled against memory limitations: each language addition inflated the compiler so it could barely fit, but each rewrite taking advantage of the feature reduced its size. For example, B introduced generalized assignment operators, using x=+y to add y to x. The notation came from Algol 68 [Wijngaarden 75] via McIlroy, who had incorporated it into his version of TMG. (In B and early C, the operator was spelled =+ instead of += ; this mistake, repaired in 1976, was induced by a seductively easy way of handling the first form in B's lexical analyzer.)

              It wasn't an archaism in c - it was an archaism from b that was removed during the development of what became c. Small difference, and for all practical purposes, it gives the same result - previously-working code that wasn't reviewed as the language evolved towards a standard ended up with "implementation-dependent behaviour" - bugs ... The worst part is that the buggy code is syntactically correct, so no compiler warnings. Of course, if your conforming compiler doesn't give a warning, you assume that the code written with the experimental versions is still valid.