Slashdot Mirror


Homeland Security Uncovers Critical Flaw in X11

Amy's Robot writes "An open-source security audit program funded by the U.S. Department of Homeland Security has flagged a critical vulnerability in the X Window System (X11) which is used in Unix and Linux systems. A missing parentheses in a bit of code is to blame. The error can grant a user root access, and was discovered using an automated code-scanning tool." While serious, the flaw has already been corrected.

22 of 517 comments (clear)

  1. OpenBSD fixed on Jan. 21, 2000 by Anonymous Coward · · Score: 4, Informative

    Check the CVS server. OpenBSD 0wns again!

    1. Re:OpenBSD fixed on Jan. 21, 2000 by LurkerXXX · · Score: 5, Informative

      OpenBSD fixes 'security holes' all the time, without even knowing it. If code looks 'dirty' (hard to read), they will often rewrite it so that it's easier to audit for bugs in the future. Most of the time when they fix a 'hole', they never actually spotted the hole. They were just cleaning up messy looking code. A few years later (like in this case) it will often turn out that there was a security hole hidden in the mess.

      FYI, they do often send the cleaned version back to the codes maintainers, but they can't force them to use the re-arranged code, or port it to other systems. Sorry.

    2. Re:OpenBSD fixed on Jan. 21, 2000 by stoborrobots · · Score: 2, Informative

      It sounds like you're thinking of the Underhanded C Contest... The 2005 results look something like what you're describing... :-)

      HTH. Cheers.

  2. The compiler just does what you ask. by EmbeddedJanitor · · Score: 4, Informative

    if you said a + b * c but you really wanted (a + b) * c the compiler won't bleat.

    --
    Engineering is the art of compromise.
  3. Re:Related news by mattwarden · · Score: 5, Informative

    You're misinterpreting what the problem was. It was a change from this:

    if (getuid() == 0 || geteuid != 0)

    to this:

    if (getuid() == 0 || geteuid() != 0)

  4. Missing *pair* of parentheses by Chirs · · Score: 4, Informative

    The fix was posted before, but the problem was that someone used "geteuid" rather than "geteuid()".

    This results in making use of the function address rather than the return value of the function, which could cause difficulties.

    1. Re:Missing *pair* of parentheses by acoopersmith · · Score: 2, Informative
      Actually, gcc never issued a peep about this code. Try it yourself - compile this with gcc -Wall:
      #include <stdlib.h>
      #include <unistd.h>

      int main()
      {
      if (getuid() == 0 || geteuid != 0) {
      return 1;
      } else {
      return 0;
      }
      }
      gcc 3.4.3 says all is fine. You can make it complain if you change geteuid != 0 to !geteuid - then it points out "warning: the address of `geteuid', will always evaluate as `true'"
  5. Re:Sometimes gentoo is a pain. by Carnildo · · Score: 2, Informative

    If you're running Gentoo stable, then you're safe: you've got Xorg 6.8.2, which is not vulnerable.

    If you're running ~x86, then you've got the vulnerable version. It's a local exploit, one that is trivially simple for an experienced programmer to use.

    --
    "They redundantly repeated themselves over and over again incessantly without end ad infinitum" -- ibid.
  6. Re:OS X? by Carnildo · · Score: 4, Informative

    OSX ships XFree86 4.3.0, which is not vulnerable.

    --
    "They redundantly repeated themselves over and over again incessantly without end ad infinitum" -- ibid.
  7. Re:Sometimes gentoo is a pain. by iabervon · · Score: 2, Informative

    All of the affected versions are masked for testing under Gentoo, so chances are that you're not using an affected version anyway. In any case, it's evidently trivial for a local user starting an xserver to cause it to execute arbitrary code, but there's no way to attack a running server locally or remotely.

  8. Re:Related news by online-shopper · · Score: 2, Informative

    Doh! I missed the euid. please mod the above post to oblivion

  9. Re:Related news by Columcille · · Score: 2, Informative

    Check again, getuid() and geteuid() are not the same, so:

    if (getuid() == 0 || geteuid() != 0)

    means something like if the real user id executing the process is 0 (root), or if the effective user id of the process is not 0 (root), then execute the following code.

    See here and here.

    I'm not quite sure what the difference is between the real and the effective user id, perhaps someone can enlighten us.

    --
    I love my sig.
  10. UIDs by r00t · · Score: 5, Informative

    The effective UID (euid) is changed when you run a setuid app, while the real UID (uid in this case, or ruid) is not.

    The effective UID is normally associated with permission to access files. Well, Linux actually uses the filesystem UID (fsuid or fuid) for that, but that one nearly always tracks the effective UID for compatibility.

    There is also a saved UID (suid or svuid) that is helpful for apps that need to swap UIDs back and forth. It's not used for anything else.

  11. Re:So does this mean? by dotgain · · Score: 2, Informative
    That's why TFA said parentheses , which is the plural of parenthesis.

    Incidentally, that's the word you should have used too.

  12. Re:This is not a remote root vunerability by acoopersmith · · Score: 3, Informative

    The exploit mentioned in this article cannot be exploited by a user who isn't logged into your system - you have to be able to run the Xorg command with certain options. See X.Org's advisory at http://lists.freedesktop.org/archives/xorg/2006-Ma rch/013992.html

  13. nullptr to the rescue by neutralstone · · Score: 2, Informative

    Rumor has it the ISO C++ committee is likely to pass through a proposal for a new keyword, nullptr, which will have a "magic" type "pointer-to-anything" and has the value of the null pointer constant.

    So, E.g.:

    struct A;
    int f( A* ); // #1
    int f( int ); // #2

    int m =  f( 0 ); // # calls #2
    int n =  f( nullptr ); // calls #1

    Of course, that wouldn't help in the aforementioned case.  0 will still be convertible to a pointer type as it is now; it's just that 'nullptr', being a pointer itself,  makes for a "better" conversion to a real pointer type.

    nullptr is supposed to be a non-disruptive pure extension (except for the fact that it breaks code that uses 'nullptr' as an identifier) -- meaning that it should not change the meaning of existing code.

  14. Why? by Junta · · Score: 2, Informative

    A linux terminal server need only the X libraries, not even a single instance of an X server, which generally requires elevated privileges to run. I think I've seen work to correct that, but as it stands at large an X server runs as root and has to arbitrate security, whereas X applications linked to X libraries, displaying to a thin client over the network, the server has no root level code and only the thin client filesystem/system is at any risk.

    --
    XML is like violence. If it doesn't solve the problem, use more.
  15. Re:Related news by w9ofa · · Score: 2, Informative

    You missed the point. The value of NULL is 0, but what is a NULL reference?

    Conventional C programmers (not C++) define NULL as (void *) 0x0.

  16. Double bug half-fixed !!! by wtarreau · · Score: 2, Informative
    Obviously, it is still wrong :
    /* First the options that are only allowed for root */
    - if (getuid() == 0 || geteuid != 0)
    + if (getuid() == 0 || geteuid() != 0)
                        ^^
    This would grant the if statement to root and everybody else. This one
    should be applied next, otherwise the bug is still there :
    @@ -1677,7 +1677,7 @@
      }
      if (!strcmp(argv[i], "-configure"))
      {
    - if (getuid() != 0 || geteuid() == 0) {
    + if (getuid() != 0 && geteuid() == 0) {
    Willy
  17. Re:Related news by Schraegstrichpunkt · · Score: 2, Informative
    That better not be true... Since ANSI C says that NULL is 0.

    I don't know about ANSI, but ISO/IEC 9899:1999(E) (a.k.a. "C99"), under section 7.17 "Common definitions <stddef.h>" states:

    1 The following types and macros are defined in the standard header <stddef.h> . Some are also defined in other headers, as noted in their respective subclauses.

    ...

    3 The macros are

    NULL
    which expands to an implementation-defined null pointer constant;
    Under section 6.3.2.3 "Pointers", the "null pointer constant" is defined as follows:
    3 An integer constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to and object or function.
  18. Re:Caution: Sometimes 0 != NULL by sholden · · Score: 2, Informative

    Then the compiler is not compliant with the standard. Since it defined the constant 0 (and only the constant 0 not for example 1-1) in a pointer context as being converted to the NULL pointer at compile time. The only times 0 isn't correct is as an argument to a function with no prototype (which no one does anymore, right :) and as an argument to a varargs function call - since in both those cases there is no pointer context to trigger the conversion.

    You need a better compiler.