Slashdot Mirror


Zlib Security Flaw Could Cause Widespread Trouble

BlueSharpieOfDoom writes "Whitedust has an interesting article posted about the new zlib buffer overflow. It affects countless software applications, even on Microsoft Windows. Some of the most affected application are those that are able to use the PNG graphic format, as zlib is wildely used in compression of PNG images. Zlib was also in the news in 2002 because of a flaw found in the way it handled memory allocation. The new hole could allow remote attackers to crash the vulnerable program or even the possiblity of executing arbitrary code."

13 of 372 comments (clear)

  1. The patch, and the E-Week article and quote by alanw · · Score: 4, Informative
    Here's the patch to inftrees.c (found on Debian.org):
    $ diff -Naur inftrees.c ../zlib-1.2.2.orig/
    --- inftrees.c 2005-07-10 13:38:37.000000000 +0100
    +++ ../zlib-1.2.2.orig/inftrees.c 2004-09-15 15:30:06.000000000 +0100
    @@ -134,7 +134,7 @@
    left -= count[len];
    if (left < 0) return -1; /* over-subscribed */
    }
    - if (left > 0 && (type == CODES || max != 1))
    + if (left > 0 && (type == CODES || (codes - count[0] != 1)))
    return -1; /* incomplete set */

    /* generate offsets into symbol table for each length for sorting */
    And here's the E-Week article with the quote
    However, Ormandy said, "Zlib is very mature and stable, so development is sporadic, but it's certainly not dead. Mark Adler [a Zlib co-author] responded to my report with a patch and an in-depth investigation and explanation within 24 hours, and I believe he expects to release a new version of Zlib very soon."
    1. Re:The patch, and the E-Week article and quote by Haeleth · · Score: 3, Informative

      I wonder if it'd be possible to create a binary patch for prebuilt binaries ?

      For specific builds of individual programs, trivial. There are dozens of good, fast, and robust binary patching systems available - xdelta, bsdiff, and jojodiff are three F/OSS options. Of course, bandwidth is cheap enough these days that most people who use binaries can just download the new version in its entirety.

      A general-purpose fix that could be applied to any application using a statically-linked zlib would be much harder, possibly even impossible. This is one of the major advantages of dynamic linking - that a security update to the library in question can automatically benefit any application that uses the library.

  2. Already patched by Anonymous Coward · · Score: 4, Informative

    Both Debian and Ubuntu released the patch for this problem 2 days ago. I assume the other big names in the Linux world have or will follow suit shortly.

  3. Glad I'm running Linux. by yog · · Score: 3, Informative

    I'm running RHN alert notification on Fedora Core 3, and my version of zlib has already been updated with a patch for CAN-2005-2096, the zlib overflow bug.

    It's interesting to read about these as they occur, but it's a nice feeling that my operating system is so well taken care of. Too bad that all personal computers aren't set up for this kind of timely response. I wonder about those millions of library computers, home PCs, small business computers, and other institutional setups where no one even understands the concept of an update, let alone regularly runs the Windows "security" update program.

    Another reason to use Linux!

    --
    it's = "it is"; its = possessive. E.g., it's flapping its wings.
  4. Perspective of non-C Programmers by putko · · Score: 4, Informative

    It is really something that this flaw impacts so many applications.

    This situation is unnecessary; the problem is that C is not a type-safe language, like ML, CAML, Haskell, Common Lisp, Scheme, Java, etc.

    You could write that code in SML/CAML/Common Lisp and likely get it to run as fast or faster than the original (particularly if you did some space/time tradeoffs ala partial evaluation). Integration with the applications in the form of a library would be the tough part.

    Here's a provocative bit from Paul Graham (Lisp expert entrepreneur) on buffer overflows.

    --
    http://www.thebricktestament.com/the_law/when_to_s tone_your_children/dt21_18a.html
    1. Re:Perspective of non-C Programmers by Florian+Weimer · · Score: 4, Informative

      Common Lisp (the language) is not completely safe, it permits unsafe constructs which can even lead to classic buffer overflows. Most implementations omit bounds checks which are not mandated by the standard when optimizing, so these problems can occur in practice.

    2. Re:Perspective of non-C Programmers by Anonymous Coward · · Score: 4, Informative

      the problem is that C is not a type-safe language

      Please. This is a very boring misconception about types. It's not a type error. It's a pointer arithmetic error. Nothing a type system à la ML, Java, CL, whatever would have corrected.

      However, mandatory bound checking on arrays, at runtime, in those languages would have caught the problem.

      There exist type systems that can catch these kind of errors, but they are very cumbersome, and not very practical.

    3. Re:Perspective of non-C Programmers by po8 · · Score: 4, Informative

      Why does this topic bring the, uh, technically challenged out of the woodwork?

      I'm a Ph.D. computer science professor with 20 years of experience in design and implementation of programming languages, and the co-author of a C-like programming language featuring static and dynamic typing and runtime operand checking. The parent poster is confused.

      Static type checking involves automatically recognizing type-unsafe operations at compile time. In many programming languages, including C, if you write"s" - 1 the + operation is ill-defined, because the left-hand operand is of the wrong type: i.e., there is no string that is a legal operation to the - operator. The compiler can detect this at compile time and refuse to compile the program.

      Dynamic type checking involves automatically recognizing type-unsafe operations at run time. In many programming languages, such as Python, if you write"s" - 1 inside a function definition, the compiler will not detect the problem, because the general problem of detecting this kind of error is unsolvable unless one restricts what programmers can write. Instead, the execution engine can detect the problem at runtime when the - is evaluated and refuse to continue executing the program.

      Runtime operand checking involves automatically recognizing at runtime that an operation has an operand that, while of a type that might be legal for the operation being performed, is nonetheless illegal for that operation. In many languages, including Python, if you write 1 / 0 no error will be reported at compile time, because detecting such errors is in general impossible. Instead, the execution engine can detect the problem at runtime, and prevent execution from continuing.

      (Of course, there also is such a thing as static operand checking, which bears the same relation to runtime operand checking that static type checking does to runtime type checking. This is a hot research topic right now.)

      C's problem is that it (a) does not have a "safe" static type system, (b) does not have any dynamic type checking, and (c) has no operand checking. This combination of misfeatures is incredibly and obviously error-prone; offhand, I can think of no other popular language (not derived from C) that is broken in this fashion. Fixing (a) and/or (b) is not sufficient---(c) also needs to be fixed. Java, for example, has shown that this can be done in a C-like compiled language without noticeable loss of efficiency. (This was shown for PL/I more than 30 years ago, so it's no surprise.)

      The parent post gives an example in which the index argument to an array dereference is of the correct type and has correct operands. If x[2] was evaluated, this would be an operand error, since the combination of arguments x and 2 is not a legal operand combination for the array dereference operator. With the statement as given in the parent post, I'm not sure what principle it was trying to illustrate. I think, though, that it doesn't much matter.

  5. Re:Modularised code will always have this problem. by Richard+W.M.+Jones · · Score: 4, Informative

    Automatic buffer overflow protection only covers the straightforward buffer overflow problems, i.e. array index overflows. In the case of more complex pointer arithmetic, where most of these problems occur, automatic protection is not possible (at least not without losing the option of pointer arithmetic).

    Actually, automatic checking is very much possible, and has been for years. For example, Bounds checking gcc (that website is down right now, so try my page on the subject). That was written in 1994, and there are newer systems available now which don't have such a serious performance penalty.

    The real solution is to stop writing critical code in C. Other languages provide bounds checking, and are faster and safer than C: for example OCaml which I prefer nowadays.

    Rich.

  6. Re:Modularised code will always have this problem. by Anonymous Coward · · Score: 4, Informative

    Actually, x86 already does, but nobody uses these features. When they fixed segmentation with the 386, segments were now accessed through selectors and offsets. The selectors pointed to one of two tables (GDT - global descriptor table or LDT - local descriptor table). Whenever a memory access was made using a selector, the CPU would look up the descriptor corresponding to the selector. It would check whether the current program had necessary access rights and privilege. If not, then a GPF would be thrown. Segments can be marked as read-only, read-write, executable and maybe a few more combos. Although the GDT and LDT each have only room for 8192 entries, that's still probably more than most programs would need. Each segment could correspond to a single object or array of primitive objects. There would be no buffer overflows because the CPU catches attempts to go beyond the limit of a segment. Stack data couldn't be executed inadvertently because the stack segment would properly be marked as non-executable.

    There are a few reasons, though, why we don't use this system. One is that loading descriptors is slow because it was never optimized in the CPU with the equivalent of a TLB as for paging. The other is that using segmentation requires 48-bit pointers rather than 32-bit pointers, or it requires loading segmentation registers and doing a dance with those. I suppose using longer pointers was a problem back in the days when memory was scarce, but it's hardly a problem now (check out 64-bit). Intel *could have* made segment descriptor access checks and loading fast, but I guess there wasn't a demand for it once paging was available.

  7. BSD Status by emidln · · Score: 5, Informative

    For the undead crowd out there:

    OpenBSD is affected, and was patched on the 6th of June
    FreeBSD is affected, and was patched on the 6th of June
    NetBSD base system is not affected, but a zlib from pkgsrc is, and was patched on the 8th of June

  8. Re:despite being OSS... by djmurdoch · · Score: 3, Informative

    ...there has been no security audit that found this flaw. ...everybody's computers won't be automatically updated just because there is a patch that all total geeks love. ...the source haven't been read by all who uses it, and the flaw wasn't found.

    In fact, this flaw was found by a security audit of an open source project, not by any of the closed source projects (like Microsoft Office) that make use of it.

  9. Re:Modularised code will always have this problem. by Dun+Malg · · Score: 4, Informative
    Stop bitching. Audit your goddamn code already.

    Oh please. When are we going to get past, "I know! Let's just write perfect software all the time!"

    There will always be some subset of people who refuse to accept the impossibility of absolute perfection. I believe their thinking goes like this:

    "Anyone can easily write a single line of bug-free code. If you can write twenty of those lines, you can write a bug free function. Write a dozen such bug-free functions and you've got a bug-free class. Write a half dozen or so bug-free classes and you have a bug free library. Using a collection of such bug free libraries you can write a few more bug-free classes held together by some bug-free lines of code and you've got a bug-free application. You're not so stupid that you can't write a single line of bug-free code, are you? There's no excuse for bugs. Just don't make mistakes. It's a choice, really."

    (I never had to work for anyone who said the above, but my brother in law, a coder for a large trucking company, had to put up with a "quality consultant" whose entire theory was essentially the above, punctuated with shouts of "attention to detail, people!" in between such lectures. A similar consultant is documented in an email in "The Dilbert Principle". Sadly, it's probably not the same guy.)

    --
    If a job's not worth doing, it's not worth doing right.