Slashdot Mirror


New Linux Kernel Flaw Allows Null Pointer Exploits

Trailrunner7 writes "A new flaw in the latest release of the Linux kernel gives attackers the ability to exploit NULL pointer dereferences and bypass the protections of SELinux, AppArmor and the Linux Security Module. Brad Spengler discovered the vulnerability and found a reliable way to exploit it, giving him complete control of the remote machine. This is somewhat similar to the magic that Mark Dowd performed last year to exploit Adobe Flash. Threatpost.com reports: 'The vulnerability is in the 2.6.30 release of the Linux kernel, and in a message to the Daily Dave mailing list Spengler said that he was able to exploit the flaw, which at first glance seemed unexploitable. He said that he was able to defeat the protection against exploiting NULL pointer dereferences on systems running SELinux and those running typical Linux implementations.'"

391 comments

  1. Fast! leave the sinking Ship! by Anonymous Coward · · Score: 0, Funny

    Fast! leave the sinking Ship before its too late!

  2. Re:Linux More Secure than Windows? by BPPG · · Score: 1

    It's okay, I've got auto-update disabled.

    --
    What's the value of information that you don't know?
  3. Double standards by Anonymous Coward · · Score: 1, Insightful

    If this had been Windows, the article would have been tagged defectivebydesign.

    1. Re:Double standards by Anonymous Coward · · Score: 4, Informative

      Thats because with Windows, no one would be able to marvel at how un-obvious the flaw is. According to The Register, the kernel actually has gaurds in place against just this type of valnerability, but the complier optimized them out during compiling. IMHO this makes this flaw a very good case study, even with security in place, you cannot really trust the compiler. (actually, this flaw apparently only occurs if security is in place... or if you use PulseAudio (in which case, you deserve it!)).

    2. Re:Double standards by Anonymous Coward · · Score: 2, Insightful

      If this had been Windows we'd find out 9 months later after the guy who discovered it informed Microsoft, they stick their fingers up their butt for 3 months. Microsoft would then spend 3 months finding that the code they used to fix the problem (which was copied from a dll they wrote in 2005) causes problems in newer versions of Excel because it uses null pointers to calculate file bloat or something. Then they threaten him with lawsuits for a few months if he releases the information. In a rush to release a fix MS uses a newer bit of code that breaks all versions of Excel because they really dont need another reason for people not to upgrade.

      The end result of which is that MS releases a fix mere days after the flaw is "announced".

      The Excel bug goes unfixed for 4 years because its a low priority and nobody has found a way to exploit it yet.

    3. Re:Double standards by Anonymous Coward · · Score: 0, Insightful

      Your post will get modded insightful pretty quick even though it's just a dirty trick similar to "oh gosh, I know I'll get mod down for this but".
      Look at the number of positive comments regarding the latest build of windows 7 and compare them to the latest linux kernel. They just don't stack up.
      Either slashdotters don't run linux anymore, or windows actually grown to a nice product. Either way, stop living in the past.

    4. Re:Double standards by Shinobi · · Score: 3, Insightful

      And yet comp sci trash wonder why some of us actually learn assembler, and don't blindly trust compilers and libraries.

    5. Re:Double standards by Anonymous Coward · · Score: 0, Flamebait

      The language is called Assembly. An assembler assembles assembly code into machine code.

    6. Re:Double standards by infolation · · Score: 5, Funny

      This language is called Pedantry. A pedant pedantically peddles english into pedanticism.

    7. Re:Double standards by calmofthestorm · · Score: 1

      Blind trust is not necessary for this to be an issue. NO ONE has time to write all their code in assembly, not even for the kernel. This is arguably more of an issue in the compiler than in the kernel, and if you honestly claim you can write a C compiler without learning assembly...yeah.

      Better retort: Which dialect?

      --
      93rd rule of Slashdot: No matter how obvious my sarcasm is, my comment will be taken seriously by someone.
    8. Re:Double standards by Anonymous Coward · · Score: 0

      You know....you're absolutely correct. Somebody mod this AC up.

    9. Re:Double standards by Dunbal · · Score: 0, Troll

      Either slashdotters don't run linux anymore, or windows actually grown to a nice product.

      OR, Microsoft has a team of paid shills with several slashdot accounts each to "adjust" moderation in their favor and flame anyone who dares say anything about THAT PIECE OF SHIT SOFTWARE COMPANY we call Microsoft.

      --
      Seven puppies were harmed during the making of this post.
    10. Re:Double standards by mortonda · · Score: 5, Informative

      This is arguably more of an issue in the compiler than in the kernel,

      Not completely... from the SANS Storm Center, the code was as follows:


      struct sock *sk = tun->sk; // initialize sk with tun->sk

      if (!tun)
              return POLLERR; // if tun is NULL return error

      The error was that the compiler optimized away the if statement, assuming that tun had already been initialized. The check should have been placed before the sock variable referenced it. Not entirely obvious maybe, but then again, it should have been checked before the assignment.

    11. Re:Double standards by Anonymous Coward · · Score: 0

      In the server market? Thanks for playing.

    12. Re:Double standards by gilgongo · · Score: 1

      If this had been Windows, the article would have been tagged defectivebydesign.

      What are you talking about? How is a Linux kernel exploit related to the architecture of DRM??

      --
      "And the meaning of words; when they cease to function; when will it start worrying you?"
    13. Re:Double standards by gilgongo · · Score: 3, Insightful

      For such a piece of shit company, they sure do have a lot more marketshare than the computing godOS known as Linux.

      Microsoft's current market share has nothing to do with quality, and everything to do with monopoly. It doesn't matter whether their product is any good or not, because not only do the vast majority of computer users not even know what Windows is, they wouldn't have the first clue what an alternative to Windows or MS Office would be like.

      Time to learn about basic economic theory I think.

      --
      "And the meaning of words; when they cease to function; when will it start worrying you?"
    14. Re:Double standards by ivucica · · Score: 2, Funny

      gcc -pedantic $@

    15. Re:Double standards by alnjmshntr · · Score: 4, Funny

      Right... Because Microsoft are really losing sleep over the negative comments posted on slashdot, so they have assembled a crack team of slashdotters to game the moderation system in their favour.

      You have to be kidding me.

      --
      If I had created the world I wouldn't have messed about with butterflies and daffodils. I would have started with lasers
    16. Re:Double standards by Fweeky · · Score: 1

      In my tests, gcc only optimizes out null checks at -O3 or above, which is already known to make potentially unsafe optimizations. Maybe if -Wunreachable-code were part of -Wall it would have been easier to spot.

    17. Re:Double standards by Vintermann · · Score: 1

      Yeah right, I'm sure you macho-hacker trash can write hand-crafted assembly that is safer than GCC. And I'm sure the guy who found out about this doesn't have a comp sci background at all. Everyone knows it's the hackers that find the real stuff!

      --
      xkcd is not in the sudoers file. This incident will be reported.
    18. Re:Double standards by bschorr · · Score: 1, Insightful

      How stereotypically /. is this? We have a story about a security flaw in Linux and it somehow turns into a Microsoft-bashing session.

      --
      -B-
    19. Re:Double standards by Pvt_Ryan · · Score: 2, Insightful

      To be fair if it was windows we'd never know which bit of the code was exploitable or why just that there was an exploit after all we cant SEE their source.

      Good news is that this will be fixed in 2.30.2 in the next month instead of left to be fixed in windows 2012 if ever...

    20. Re:Double standards by Pvt_Ryan · · Score: 1

      What amazes me, is you think they wouldn't.. Credit where credit is due, one thing MS are good at if nothing else is marketing.

    21. Re:Double standards by ld+a,b · · Score: 1

      GCC "optimizations" are one of the main reasons OpenBSD specifically is looking forward to replace it with PCC.
      When optimizations keep you from knowing what a program will do, they have gone too far.

      --
      10 little-endian boys went out to dine, a big-endian carp ate one, and then there were -246.
    22. Re:Double standards by Shinobi · · Score: 3, Insightful

      I never said anything about writing everything in it. But many of us with proficiency in it tend to check what the compiler actually outputs, because we know that the compiler is not smarter than the human who wrote it is. (A behaviour further reinforced by the two smelly piles of fecal matter that are MSVC and GCC). This is also why many of us don't blindly trust optimizations to the compiler either, and always double-check. A disassembler is also useful for tearing through critical pieces of code to see if the compiler has built it in the way you intended.

      I've removed quite a few obscure but potentially very nasty bugs in my software by doing that. Then again, I'm a freelancer, I live by my reputation for solid, fault-free code.

    23. Re:Double standards by awpoopy · · Score: 1, Interesting

      Somebody mod this AC up.

      I would love to however, it appears that only people running MS has mod points these days. I spoke unkindly of MS and my karma turned to "bad" AND I haven't seen mod points in three months. Only the shills are being able to use slashdot effectively it seems. That's just my opinion, however I could be wrong.

      --
      I say things which affects my Karma negatively. (and I don't care) For instance; All religion is false.
    24. Re:Double standards by Shinobi · · Score: 4, Interesting

      Sure. My last entire project has been specifically about that. Been working on a piece of software to go onto an embedded device with deterministic behaviour, with the hardware specs being 32kiBiByte RAM, no cache, 8MHz processor.

      Most people I am forced to work with who have a comp sci degree are unable to work under such conditions. On the other hand, EE's and comp.eng graduates tend to be very nice to work with on such projects.

    25. Re:Double standards by Shamenaught · · Score: 2, Insightful

      Well, Microsoft got that market share by providing cheap software, specifically DOS. It was arguably of low quality, but who cares that much about the quality if it's cheap, right?

      I don't know if it was originally the plan, but at some point along the way Microsoft realized they had a monopoly. They leveraged their share by putting up prices and using FUD tactics to discourage people from switching. The main issue I have is that although the prices went up, the comparative quality of software didn't. Sure, It looks a lot better than DOS, but that's because modern computers are practically supercomputers compared to what DOS ran on. So you see, having a large market share doesn't mean the company isn't a piece of shit, it just means they can be a piece of shit and get away with it.

      Sure, you can argue that a bug in the latest Linux kernel is a sign that there are bugs in lots of OSes. The difference is that with Linux it'll be fixed in a couple of days. Very few people will be using the latest kernel, AFAIK none of the big distros released with it yet, and although some users may have downloaded and compiled the source themselves (I did so myself, as it offered some driver compatibility for new hardware) the architecture is versatile enough that you can simply switch between different kernels, even without fully rebooting, although not completely without disruption.

      --
      mysql> SELECT * FROM `places` WHERE `place` LIKE 'home`; Empty set (0.00 sec)
    26. Re:Double standards by Anonymous Coward · · Score: 0

      By that logic, China must produce the highest quality products since everything is made there. Bulk sale is not an indication of quality.

    27. Re:Double standards by jelle · · Score: 1, Informative

      The check is not placed wrong, it should be safe as long as *sk isn't used before the check. The *sk assignment does not dereference to a memory location, it does nothing more than adding an offset to the other pointer: ((int)sk - (int)tun) is the offset of sk in 'struct sock'.

      The compiler is wrong in assuming tun is always non-NULL at that point in the code.

      It's certainly a compiler bug, it's the same as optimizing the 'if (!tun)' out of this code:


      const int sk_off = 123;
      int func(int tun)
      {
          int sk = tun + sk_off;

          if (!tun) return -1;
          return sk;
      }

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    28. Re:Double standards by Anonymous Coward · · Score: 0

      It's not related. It's just that the Windows lovers of the world are not capable of understanding the derogatory labels we put on them. They only understand that they should be insulted and upset about something related to the products they are fans of.

    29. Re:Double standards by QuoteMstr · · Score: 4, Informative

      No. You are wrong.

      The code is grabbing the value of the sk field of the tun struct, not its address. Did you misread the code, or do you not actually know C? Or are you perhaps just on the sauce?

      You're claiming the code reads struct sock **sk = &tun->sk when in reality, it reads struct sock* sk = tun->sk, which is completely different.

    30. Re:Double standards by Anonymous Coward · · Score: 0


      if (!tun)
          return POLLERR; // if tun is NULL return error

      Code and comment don't match. Besides that, it would be far more interesting to see this gcc bug verified.

    31. Re:Double standards by Anonymous Coward · · Score: 0

      thats because this is an authentic, rare mistake not one caused by chronic intentional disreguard hellbent on marketing interests

    32. Re:Double standards by iYk6 · · Score: 1

      Your explanation makes a lot of sense. However, it does not match up with my observations. For example, this code segfaults at line 10:

      struct sock
      {
      struct sock * sk;
      };

      struct sock * tun = 0;

      int main(int argc, char ** argv)
      {
      struct sock *sk = tun->sk; // initialize sk with tun->sk
      }

      Using gcc 4.3.2-2 from Debian repos.

    33. Re:Double standards by dna_(c)(tm)(r) · · Score: 3, Informative

      Oh please, it's a response to

      If this had been Windows, the article would have been tagged defectivebydesign.

      You're not supposed to read the article, but at least the post you're criticizing.

    34. Re:Double standards by kestasjk · · Score: 4, Insightful

      So you can disassemble compiled code, way to go.. Have fun disassembling a huge binary that's far too large to economically analyze in assembly.

      What's that? You don't fully disassemble and analyze large binaries but only critical paths or small binaries? How unique and sought-after your services must be. I'm sure analysis of compiled kernels is the best way to tackle this bug..

      --
      // MD_Update(&m,buf,j);
    35. Re:Double standards by Imagix · · Score: 1

      Not entirely obvious to who? That code invokes Undefined Behaviour. By dereferencing a NULL pointer value, that C code can do anytthing.

    36. Re:Double standards by Shinobi · · Score: 1

      Actually, code/design verification is one of the services I offer, which is a heavy mix of mathematics and low-level code snooping.

    37. Re:Double standards by icannotthinkofaname · · Score: 1

      I had mod points almost a week ago, and I run Ubuntu.

      Maybe you're just unlucky or something....

      --
      Let q be a radix > 1. I am in ur base-q, killing 10 d00ds.
    38. Re:Double standards by QuoteMstr · · Score: 2, Insightful

      NO ONE has time to write all their code in assembly, not even for the kernel

      To be fair, the OP wasn't suggesting that programs actually be written in assembly, but rather that programmers learn assembly and know how to debug libraries. That's a sentiment I'll second: of course you don't write programs using machine code operations, but when something breaks, it's quite useful to be able to drop down to assembly in a debugger and see what's actually going on, especially when debugging optimized code.

      As for compiler bugs: once in a while, they really do happen. Of course, one's first, second, and even third reaction shouldn't be to blame the compiler, but when all other options are exhausted, the possibility is there.

    39. Re:Double standards by thenextstevejobs · · Score: 1

      If this had been Windows, the article would have been tagged defectivebydesign.

      Well, that's because Windows is--undebatably--defective by design. Not to say that the Linux kernel release model doesn't have its issues. But come on, we all know that the design underlying Windows has been bogus since the start.

      --
      Long live the BSD license
    40. Re:Double standards by QuoteMstr · · Score: 2, Insightful

      For the sake of argument, let's suppose you're right. (I think it'll be a cold day in hell when the BSDs move away from GCC.) Increasing performance demands will lead to the inclusion of more optimizations in PCC, and these optimizations will lead people like you to make the same complaints about PCC that people make about GCC today.

      Really, what you're opposed to isn't GCC, but the notion of an optimizing compiler. Sorry, but history has spoken: the gain of optimization far outweighs the minor cost of forcing people like you to actually learn what's guaranteed by the language and what is not.

    41. Re:Double standards by thenextstevejobs · · Score: 1

      This is arguably more of an issue in the compiler than in the kernel,

      Not completely... from the SANS Storm Center, the code was as follows:

      struct sock *sk = tun->sk; // initialize sk with tun->sk

      if (!tun) return POLLERR; // if tun is NULL return error

      The error was that the compiler optimized away the if statement, assuming that tun had already been initialized. The check should have been placed before the sock variable referenced it. Not entirely obvious maybe, but then again, it should have been checked before the assignment.

      The check should have been placed before the sock variable referenced it. Not entirely obvious maybe, but then again, it should have been checked before the assignment.

      Well, had the check been done first that would be a more reasonable program. But whose to say there isnt a line directly above this that assigns, invariably, a known memory access. Then, say this is a multi-threaded application, and there is a possibility that memory area has been deleted, and if so, you want to take a certain action.

      I don't see how this isn't absolutely a compiler issue. There is no way that an if statement that does an error check should be optimized out in this situation, if any.

      As previously mentioned, the right behavior would be to warn about this. And to leave the if statement in.

      --
      Long live the BSD license
    42. Re:Double standards by TheSunborn · · Score: 2, Interesting

      The compiler is allowed to assume that no other code(Including no other thread, running the same code) change the value of a variable behind its back(As long as the variable it not volatile(Volatile got it's own can of worms)), so the optimization is safe.

      so in the code

      int *data=myFunc();
      val=*data;
      printf("%d\n",val);
      val=*data; // The compiler is allowed to optimize this call out.
      printf("%d\n",val);

      And the compiler is allowed to turn this into nothing:

      int *val=myFunc(); // Returns a valid pointer to an int.
      *val=10;
      if(*val==11) {
          *val=42; // The compiler may remove anything in here.
      }

      If multi-threaded code were allowed to do what you describe, then it would be impossible to do most of the optimizations that good c compilers do.

    43. Re:Double standards by incripshin · · Score: 1

      I don't really know what's going on, and the people at SANS don't seem to know, either. My best guess is that the code they showed was somewhere in the kernel (?) and address NULL is okay to use there (?).

      The segmentation fault you're seeing is not because you dereferenced NULL, but because NULL wasn't in any of the pages. If NULL were in any of the pages, and sk were at offset 8, then tun->sk would resolve to (NULL + 8). The kernel has a different view of memory than user space; I'm just not sure what that is.

    44. Re:Double standards by Anonymous Coward · · Score: 0

      Hmm, wonder if there was a way to break a program into individual pieces that can be compiled and debugged independently... Nah, never work.

    45. Re:Double standards by incripshin · · Score: 1

      whoops: *(NULL + 8)

    46. Re:Double standards by NormalVisual · · Score: 3, Informative

      And frankly, it's not particularly difficult to work under those constraints. There are a lot of us that were writing code 25-30 years ago, when that level of hardware represented a state-of-the-art microcomputer, except for the 8 MHz CPU - most CPUs then ran only a fraction of that speed. I still marvel at the fact that the tiny BlackBerry that I hold in my hand is *in every way* a faster and more capable computer than what I worked on back in the Dark Ages.

      Assembly of any sort isn't that difficult once you get some experience with it, and with the proper macros and defines set up, it can actually be fairly quick to code in. Some chips are easier than others (the 68K was *awesome* to code for), but it just requires some attention to detail and a good understanding of how the machine works.

      --
      Please stand clear of the doors, por favor mantenganse alejado de las puertas
    47. Re:Double standards by BitZtream · · Score: 2, Informative

      A bug exists with or without the optimization if the code you pasted is the actual code. tun being null makes the tun->sk reference invalid. You should end up with a panic at this point.

      If the compiler optimized away the tun check without there being a previous tun check, there is also a compiler bug. The compiler shouldn't have assumed that tun was initialized just because it was read from, which is all a dereference is, a read and an add.

      --
      Persistent Volume manager for Kubernetes - https://github.com/dwimsey/openshift-pvmanager
    48. Re:Double standards by BitZtream · · Score: 3, Informative

      Yes, but the rest of us have written about 1000 times more code than you because we didn't spend our time checking a ton of assembly because we presume the compiler is flawed.

      There are times when this sort of checking is acceptable if not required. The kernel is a good place to do it.

      You aren't going to do this for KDE or Gnome however.

      --
      Persistent Volume manager for Kubernetes - https://github.com/dwimsey/openshift-pvmanager
    49. Re:Double standards by Shinobi · · Score: 1

      I know, but I meet lots of people churned out by colleges and universities from all over Europe and from North America who do have trouble with it. Because in school they never did any work on a computer with less than 512MiB RAM for example. Another pet peeve of mine is all the people who whine about the Cell being hard to work with. Then you bring it to people who got to learn on DSP's in college/university, or who have worked with it in the field, and they just LOVE the thing and feel instantly at home with it.

    50. Re:Double standards by Anonymous Coward · · Score: 0

      Any chance you know the meaning of "->" in the context of the C programming language?

    51. Re:Double standards by denominateur · · Score: 2, Informative

      The exploit maps 0x00000000 to userspace using pulseaudio, this prevents the segfault.

    52. Re:Double standards by Shinobi · · Score: 1

      And how much of that presumed 1000 times more code is in reality just retyping the code to fix a bug, because you couldn't be arsed/were incapable of doing the job correctly in the first place?

      And, if you had bothered to actually read properly, you would have noticed that I said it was applicable for critical pieces.

    53. Re:Double standards by Anonymous Coward · · Score: 2, Informative

      (I think it'll be a cold day in hell when the BSDs move away from GCC.)

      Oh, really! Time to buy me a new coat.

    54. Re:Double standards by Anonymous Coward · · Score: 0

      It's a pointer dereferencer.

    55. Re:Double standards by K.+S.+Kyosuke · · Score: 2, Insightful

      There *is* a sane way to develop for such environments, *without* C, with predictable results, with deterministic behaviour, in short time, interactively, iteratively, on a reasonably high level and without getting mad. It's called Forth. Why is that such a big deal suddenly, when it was no problem for decades?

      --
      Ezekiel 23:20
    56. Re:Double standards by ToasterMonkey · · Score: 2, Informative

      There aren't any important services that run setuid is there?

      Oh...

    57. Re:Double standards by Anonymous Coward · · Score: 0

      And what exactly is bogus about the NT kernel?

    58. Re:Double standards by jelle · · Score: 2, Funny

      but, erm...

      You're right...

      I should have had that coffee first...

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    59. Re:Double standards by rtfa-troll · · Score: 2, Insightful

      The error was that the compiler optimized away the if statement,

      Being more specific, based on reading the code in the SANS report after getting the suggestion from a user comment in the Register, the error was that the compiler was in an optimising mode which told it to optimise away such checks where the Null pointer had already been dereferenced. -O2 was active and that clearly means that -fdelete-null-pointer-checks is turned on.

      Two groups are at fault here:

      The optimisation was sufficiently clearly documented (it's listed in gcc under -O2 and when you look at the documentation of that option it does say that some checks may be optimised away and that in some environments this may be dangerous). Thus the Linux Kernel team has some blame.

      In the GCC optimisation options under -O2 it does not explicitly mention that the optimisations may have security implications. There should be, in my opinion, a clear statement that below some optimisation level GCC will try not to change the meaning of code under any circumstances.

      From one point of view, I guess this shows the strength of the Linux model of development where release early/release often means such bugs can be found before the public starts to actually use the software.

      From another point of view, however, I wish that the Linux kernel developers could come up with a more mature attitude to security people, however immature. Yes, it's true that the "security bugs" are, in a sense, just more bugs that could cause loss of data. However, a) that's not an excuse and b) if those bugs did turn up on a real production system in an important application they could cause real problems; exploitable security bugs are much more dangerous than other data loss bugs precisely because they only trigger when someone wants them to trigger.

      Linux kernel people who want their kernel to be broadly userd have to make a clear security statement which says why bugs don't matter. It's not good enough to just say "don't use Linux for high security applications" but it should be enough to say "before you use Linux in a configuration where security might be important, ensure you have done a) a source code audit; b) the functional tests according to XYZ etc...".

      --
      =~ s,(.*),<sarcasm>$1</sarcasm>,g if any_point_you_wish();
    60. Re:Double standards by rtfa-troll · · Score: 1

      It's not a compiler "bug" since it's clearly documented behaviour (for the -fdelete-null-pointer-checks optimisation which is active at this point and which can be turned on or off) which is appropriate in the environments where the documentation states it is. In so far as there's a gcc bug, it's a documentation bug for the -O2 optimisation since it -O2 doesn't clearly warn that code meaning modification may take place and state explicitly which -f flags to examine to be sure that all the modifications are okay.

      --
      =~ s,(.*),<sarcasm>$1</sarcasm>,g if any_point_you_wish();
    61. Re:Double standards by iggymanz · · Score: 1

      and you assembly wussies wonder why anyone would bother to learn numeric opcodes, processor modes and microcodes; and not blindly trust assemblers.

      ok, that what just a joke.

    62. Re:Double standards by locofungus · · Score: 2, Interesting


      int *data=myFunc();
      val=*data;
      printf("%d\n",val);
      val=*data; // The compiler is allowed to optimize this call out.
      printf("%d\n",val);

      Actually, the compiler isn't allowed to optimize that second assignment to val out unless it can see the source for printf and can prove that there are not other aliases to the memory that data points to that might be changing it.

      Even if you assume the default printf(), myFunc might be returning a pointer to one of the buffers used for IO.

      This is one of the reasons that C99 introduced the __restrict keyword; to allow the compiler the make the sort of optimization you are suggesting here.

      Tim.

      --
      God said, "div D = rho, div B = 0, curl E = -@B/@t, curl H = J + @D/@t," and there was light.
    63. Re:Double standards by RightSaidFred99 · · Score: 1, Insightful

      Oh nonsense. You have no idea of the root cause of most Windows exploits. In fact, it would be interesting if you would get in your Way Back machine and point out the last time windows had an F'ING KERNEL exploit. Jesus.

      At the OS level, anyone with half a brain can guess that Linux is probably less secure than Windows. It's all the shit that runs on Windows that has the issue. Yet you apologists all come on and act like any kind of Linux flaw is just some odd anomaly and easily explained away.

      What's worse, how long will this exploit live in the wild? You'll all foam at the mouth how quickly it will be patch. OK. That's nice and all, but how long until it's disseminated on say 90% of Linux machines exhibiting the flaw? And I'm sure, being Linux, this won't take a reboot right? (I'm joking on that last one - of course it will).

      Double standard indeed.

    64. Re:Double standards by RightSaidFred99 · · Score: 1

      This is not a GCC bug.

    65. Re:Double standards by RightSaidFred99 · · Score: 2, Insightful

      C does not support threading. If this code breaks because of threading it is not the compiler's fault. This is not a compiler bug, and the correct behavior includes optimizing this away. It would be _nice_ if it warned.

    66. Re:Double standards by sjames · · Score: 1

      Actually, the error is that de-referencing a NULL pointer in the assignment doesn't OOPS because it is possible to map actual memory to the zero page. The compiler optimizes the if away because it "knows" that the conditional code is unreachable. Either tun is not NULL or an exception will already have happened.

      Unfortunately, that expectation is violated by allowing memory to be mapped at address 0.

      Arguably, the bug is that the compiler makes an assumption that cannot be rigorously proven.

      Of course, it can also be argued that the code above depends on a fundamentally insane environment and/or fails to properly check for error conditions (that is, the assignment should only happen after the pointer is validated) and so is also wrong.

      In this case, two wrongs make a much bigger wrong.

    67. Re:Double standards by RightSaidFred99 · · Score: 0, Flamebait

      Bullshit. MS puts a high priority on any security issue. In addition, Windows has a built in patch distribution process that works very well. It will be ages and ages before a majority of Linux machines running this kernel version are updated.

    68. Re:Double standards by RightSaidFred99 · · Score: 0, Flamebait

      Yes. In the server market. You people who think "server market" means "Internet web servers run by some Joe Schmoe".

      Microsoft dominates in the corporate server environment, you clueless git.

    69. Re:Double standards by RightSaidFred99 · · Score: 1

      You're like those neo-con retards and Christians. They like to pretend they are suffering from some kind of persecution when the facts clearly point out they are not. Indeed, Christians are a majority in this country but if you ask them they'll swear they're persecuted by the "librul eleet" [sic].

      Any idiot can spend 2 minutes on Slashdot and see that it's dominated by old Linux nerds who resent, fear, and don't understand Windows.

    70. Re:Double standards by slyn · · Score: 1

      Mod parent up, FreeBSD switched to using LLVM as their main compiler back in march.

    71. Re:Double standards by zippthorne · · Score: 1

      Good call, because one thing you shouldn't ever expect from programmers is to be vigilant about syntax and spelling; using the proper word in the proper place.

      --
      Can you be Even More Awesome?!
    72. Re:Double standards by Cyberax · · Score: 2, Informative

      Nope. PulseAudio is NOT necessary to trigger this flaw. Read the exploit source code.

      PS: I hate PulseAudio bashing.

    73. Re:Double standards by kdemetter · · Score: 3, Funny

      i compiled my kernel using that flag , and now it boots Windows instead.

    74. Re:Double standards by Sir_Lewk · · Score: 1

      That flag makes GCC throw warnings for nonstandard code. Not really relevant here, besides its name.

      --
      "linux is just DOS with a UNIX like syntax" -- Galactic Dominator (944134)
    75. Re:Double standards by Anonymous Coward · · Score: 0

      He didn't say more constrained code, he said safer. How tight is the security tested. Also, if it so great, do you post on slashdot from it?

    76. Re:Double standards by bonch · · Score: 0

      You're an idiot. Study after study proves that the media leans left and selectively bashes Christians. I'm agnostic, and even I notice it. Just because they're a majority doesn't mean the media doesn't persecute them. It's because they're a majority that the media thinks it's okay.

    77. Re:Double standards by Tenebrousedge · · Score: 1, Funny

      In contrast programmers for Windows write perfect code every time. They've heard of the concept of 'debugging' but don't see a real need for it. This, and the unwavering efforts of Mr. Ballmer, have had great success in preserving the legacy handed down from Bill Gates: a bug-free OS. Viruses and exploits affect only lesser systems, those unfortunate enough to run some variant of unix.

      Sometimes, when I contemplate the beauty of the Windows source code, my speech centers shut down. I think that if I were ever to meet a Windows dev, blargle blerk grop lorem ipsum bleeble warble whelk!

      'Tis truly a paradise we live in.

      --
      Those who advocate genocide deserve every protection afforded by law, and none afforded by common human decency.
    78. Re:Double standards by Anonymous Coward · · Score: 1, Informative

      This kernel was released fifteen days ago. It is not present in any mainstream distro yet. Linux has a built in patch distribution system that works a hell of a lot better than Windows Update.

      "MS puts a high priority on any security issue" What is that supposed to mean? That problems *don't* go unfixed for months or years? What planet do you come from?

      Why don't you go take a look at how many people are using Win XP, IE 6, or any old version of any Microsoft software. The number of windows environments that are running completely patched, up to date software is a tiny minority.

    79. Re:Double standards by Anonymous Coward · · Score: 0

      s. (A behaviour further reinforced by the two smelly piles of fecal matter that are MSVC and GCC).

      You should write your own then, since you seem so proficient in coding. Because, you know, as the OP has shown, it's really easy to write a compiler that works safely.

    80. Re:Double standards by Anonymous Coward · · Score: 0

      Thats a fucking lie, most all distributes have update managers that work with their package manager. Even the people who download the newest kernel and compile it...will continue to do that and are the type of people who read about kernel exploits. How many precious windows machines actively get updated. Well lets minus all the botnetted machines and spam gateways huh? Also you don't know for sure what Microsoft does with a security issue since you have no time frame to tell when the exploit was found to when it was fixed. You have to take Microsoft's dev and security team's word for it and the company's ass will usually get covered (not a bad thing, just an obvious thing). Stop spewing bullshit.

    81. Re:Double standards by Nikker · · Score: 1

      Steve is that you? What are you doing with that chair in your hand?

      --
      A loop, by its nature, continues. If that didn't make sense, start reading this sentence again.
    82. Re:Double standards by HiThere · · Score: 1

      Unfortunately, I've learned assembler 5 times. And they were all completely different. After the 3rd time my learning got to be a bit skimpy, and by the time the 386 came out, I'd given up. Well, that one's lasted a lot longer than any of the others, but I'm not sanguine on it's not being replaced the day I decide I've achieved a minimal proficiency. Or more probably a month before.

      I can understand the advantages of knowing assembler, but I'm no longer willing to spend my time that way.

      --

      I think we've pushed this "anyone can grow up to be president" thing too far.
    83. Re:Double standards by RightSaidFred99 · · Score: 1

      Whatever. Most of you dorks have a box or two at home, and some of you have some small number of Linux machines at work. I work in a corporation with several thousand Linux machines and an intricate set of dependencies which means we can't just go out and install Linux patches at a whim.

      So quit pretending everything is all rosy. Most of you are Linux hobbyists with no idea how things work in the real world.

    84. Re:Double standards by ivucica · · Score: 1

      ...whoosh? See #28740071.

    85. Re:Double standards by DaleGlass · · Score: 1

      I got modpoints, and decided that maybe some sort of injustice had been committed.

      Then I looked at your posts and found nothing worth modding up.

      Mind that I'm a Linux user, and use Windows extremely infrequently from VMs.

    86. Re:Double standards by LingNoi · · Score: 1

      Why can't you do that exactly? Learn how to build packages, control your own repository and stop bitching. If you think this stuff is difficult you're obviously an amateur.

    87. Re:Double standards by LingNoi · · Score: 0, Offtopic
    88. Re:Double standards by drsmithy · · Score: 1

      Well, that's because Windows is--undebatably--defective by design. Not to say that the Linux kernel release model doesn't have its issues. But come on, we all know that the design underlying Windows has been bogus since the start.

      How so ?

    89. Re:Double standards by poopdeville · · Score: 1

      And how much of that presumed 1000 times more code is in reality just retyping the code to fix a bug, because you couldn't be arsed/were incapable of doing the job correctly in the first place?

      Very little, thanks for asking.

      --
      After all, I am strangely colored.
    90. Re:Double standards by metaforest · · Score: 1

      Forth has one big problem. It's overly terse, making it a write-only language. If you come back later to try and figure out how the code works.... good luck...

    91. Re:Double standards by RightSaidFred99 · · Score: 1

      God you people are clueless. Do you think that list has anything to do with corporate computing?

    92. Re:Double standards by Anonymous Coward · · Score: 0

      Listen, retard. In the real world companies run commercial software on Linux. This software has to be "qualified" to run on particular OS configurations. In the real world companies use commercial distributions, they don't download it off the Internet like most of you dorks.

    93. Re:Double standards by Shinobi · · Score: 1

      It's not an internet enabled device. It will, however, after having passed formal verification by an independent third party, help rescue crews and similar test for certain specific toxins and similar in air and water.

      There's more to safe and secure code than just "Oooh, it can't be rooted on the internet".

    94. Re:Double standards by Haley's+Comet · · Score: 1

      Microsoft dominates in the corporate server environment, you clueless git.

      And do you know why that is, or is the pot calling the kettle black for stupidity? Compatibility and the stupid useless "got me an ejumukashun" IT Dept. It is a more and more rare occasion that a business can't convert (yes Photoshop is a valid reason not to, Exchange server no). The bean counters need to be pacified too, by the slow snowballing of small additional prices (crunching many, many, many small numbers makes them happier than far fewer but larger numbers - that's why they count the beans, CEO's count bushels).

      Have you heard of Ernie Ball guitar strings? No M$ at that company (admittedly for legal reasons) and now they save mad cash. Apperently, they got over the "to cheap to retrain once" BS idea and now laugh all the way to the bank. I have owned and operated both Windows servers and Linux servers. Windows servers (and the owners pocketbook) get raped (IME) no matter what they have on them or how well you have them configured.

      --
      The Illuminati would kill me, but I'm not rich enough to take notice of.
    95. Re:Double standards by Nutria · · Score: 1

      What's worse, how long will this exploit live in the wild?

      Not long. People running cutting-edge kernels tend to update their kernels rather frequently.

      You'll all foam at the mouth how quickly it will be patch. OK. That's nice and all,

      Yes, it is.

      but how long until it's disseminated on say 90% of Linux machines exhibiting the flaw?

      Seeing as how most desktop Linux users run the "stable" versions of big-name distros, all of which currently ship with kernel 2.6.29 or older, and the server distros like RHEL and SLES use kernels even older than that, I'd say that the flawed kernel will never be disseminated to 90% of Linux machines.

      And I'm sure, being Linux, this won't take a reboot right? (I'm joking on that last one - of course it will).

      I don't know how well this works, but this is supposed to to let you update your kernel without rebooting.

      Double standard indeed.

      Yeah, but Windows earned that double standard.

      --
      "I don't know, therefore Aliens" Wafflebox1
    96. Re:Double standards by x2A · · Score: 1

      "And I'm sure, being Linux, this won't take a reboot right? (I'm joking on that last one - of course it will)"

      Not heard of ksplice? :-p

      "all foam at the mouth how quickly it will be patch. OK. That's nice and all, but how long until it's disseminated on say 90% of Linux machines exhibiting the flaw?"

      I'd say fairly quickly. Anyone running a 2.6.30 kernel is someone who's updating the kernel themselves rather than relying on distro updates, as I doubt 2.6.30 is too common amongst distros at the moment, and that being so, it should be rare that the bug ever really gets out amongst the masses. Someone who's keeping their kernel that updated will probably continue doing so.

      It's still not good, sure, but I doubt it's really going to be devastating.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    97. Re:Double standards by x2A · · Score: 1

      Argument doesn't hold... China's products are cheap, whereas Microsoft definitely aren't beating Linux on price.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    98. Re:Double standards by x2A · · Score: 1

      Recognising delusions of grandure really isn't that amazing. Google "this isn't slashdot" to see what people outside this site think of the unreasonable emotional reactionists that flood this site. This really isn't a site that anyone would use to try and change the hearts and minds of the public, the signal to noise ratio would just make it futile. You may as well walk out into a field and yell "switch to windows!" amongst cattle for all the good it would do.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    99. Re:Double standards by x2A · · Score: 1

      "It's because they're a majority that the media thinks it's okay"

      No it's not. It's because it actually is okay... even deserved :-p

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    100. Re:Double standards by x2A · · Score: 1

      "it appears that only people running MS has mod points these days"

      Try recompiling your kernel without the CONFIG_MS_PARANOIA option set.

      "however I could be wrong"

      Abuse of term "could be", go straight to jail, do not pass go, do not collect 100 karma points.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    101. Re:Double standards by reiisi · · Score: 1

      undefined behavior is often not obvious?

      --
      Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
    102. Re:Double standards by reiisi · · Score: 1

      I think the compiler should have an "evil compiler flag combination" warning that would be triggered by attempts to optimize out null pointer checks when warnings against using a pointer before checking it are turned off.

      --
      Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
    103. Re:Double standards by Khyber · · Score: 1

      "NO ONE has time to write all their code in assembly, not even for the kernel."

      I see someone hasn't played with MenuetOS. The entire OS is written in assembly.

      --
      Still waiting on Serviscope_minor to wake up to fucking reality and realize that Jessica Price isn't going to fuck him.
    104. Re:Double standards by DavidTC · · Score: 1

      That is poor design, not defective. And Windows stopped having a poor design a while back. (It still has a poor implementation, though.)

      Defective by design is a specific term used to refer to DRM, which is, indeed, impossible to actually work. The design is defective. You cannot present information to the end user without it being copyable.

      DRM is like attempting to build a perpetual motion machine...fools sit down and design complicated weights and counterweights, each time thinking they're going to get it if they could just get rid of one flaw. No, the flaw is that it's theoretically impossible to do what they're attempting to do, but it's very very possible to almost do what they're attempting to do, so fools will keep trying.

      The person who said this article would be tagged defectivebydesign if it about Windows was full of crap.

      --
      If corporations are people, aren't stockholders guilty of slavery?
    105. Re:Double standards by HitoGuy · · Score: 1

      I'll stop bashing Pulse Audio when it works.

      --
      I am beginning to think that maybe Darl McBride was attacked viciously by a penguin as a child.
    106. Re:Double standards by Anonymous Coward · · Score: 0

      I'll stop bashing Pulse Audio when it works. As it happens, that garbage just likes to break sound on just about every system I've seen it implemented on.

      And don't feed me "its the distros fault for not implementing it" bullshit. If that were true it wouldn't break on EVERY distribution I've seen it run on, because it is so ready for production deployment.

      I'll stick with ALSA or OSSv4, thanks, they're actually quality sound systems.

    107. Re:Double standards by Cyberax · · Score: 1

      It works.

      And right now it's the only project that tries to make sense out of the complete f***ing mess with sound APIs on Linux.

    108. Re:Double standards by HitoGuy · · Score: 1

      Unless you're using a bleeding-edge, rolling-release distribution like Arch or you're running around like a chicken with your head cut off compiling the latest kernel, you're not even using the relevant kernel version, and chances are this exploit will be gone by 2.6.30.2, and most certainly by 2.6.31. Chances are you're not even running a kernel newer than 2.6.29 on those "thousands" of systems you maintain, and thus this exploit is of no concern.

      Just in case you're just an amateur who's trying to impress the /. crowd by saying you maintain "thousands of Linux system," I'm going to tell you about a command called "uname" that can telly ou exactly what kernel is being run.

      I'm not pretending things are rosy. In fact, I'm mildly concerned since I am actually an Arch user running the kernel version in question. On the other hand, I doubt I'm really at risk being a home user who knows how to secure his system. It's rosy for the vast majority of Linux users because they're not even using this version of the kernel to begin with. And chances are, when they get a new version of their Linux distro it'll be 2.6.31 or beyond.

      --
      I am beginning to think that maybe Darl McBride was attacked viciously by a penguin as a child.
    109. Re:Double standards by HitoGuy · · Score: 1

      If it works, how come it breaks sound and (Pick one: ESD, OSSv4, ALSA, Phonon) doesn't?

      Every time I used it it was a crap shoot. sometimes it'd work, then BAM! lag, huge latency, or sometimes it just completely kills my sound. If they were making sense of Linux sound APis, it wouldn't be doing that shit.

      --
      I am beginning to think that maybe Darl McBride was attacked viciously by a penguin as a child.
    110. Re:Double standards by Yfrwlf · · Score: 1

      The difference being one can be fixed by anyone, and the other cannot. One gives you freedom, the other does not. Thus, flaws found in open source can be quickly addressed by the community.

      --
      Promote true freedom - support standards and interoperability.
    111. Re:Double standards by Cyberax · · Score: 1

      Newsflash: ESD, OSSv4 (on Linux?) and ALSA break sound too!

      Even worse, ALSA is a complete mess when it comes to simple volume control. Never mind advanced features like 3D sound positioning. How about integration with Bluetooth? Forget it, it's not gonna work with plain ALSA.

      If PulseAudio doesn't work for you, then file bugs. PulseAudio is not ideal, of course.

    112. Re:Double standards by HitoGuy · · Score: 1

      People file bugs all the time. All the developer does is spout bullshit and blame OTHER projects for why Pulse Audio is such a fuck up.

      --
      I am beginning to think that maybe Darl McBride was attacked viciously by a penguin as a child.
    113. Re:Double standards by Cyberax · · Score: 1

      And Lennart is usually right. He uncovered and helped to fix a horde of bugs in ALSA, which were long unnoticed since people accepted that sound in Linux "just doesn't work"(tm).

      PulseAudio works just fine for me - I can plug in my bluetooth handset in the middle of a call and transfer sound to it, for example. Try that in ALSO or OSS.

    114. Re:Double standards by Anonymous Coward · · Score: 0

      Pulse Audio does nothing but fuck up for me. And it DOES have bugs of its own. ALSA never failed me once. Nor did OSSv4. Whereas inevitably Pulse Audio always, *always* breaks everything. And, sadly, I'm far from alone.

      If sound "doesn't Just Work" under ALSA, how come it fuckign does in EVERY case I've seen. I've NEVER seen it where sound never worked thanks to ALSA.

      Sorry, Pulse Audio DOESN'T work until it can work CONSISTENTLY across most systems. As it happens, it's broken on most systems. Don't believe me? Google it.Most sites bitch about Pulse Audio, not praise it.

    115. Re:Double standards by QuietObserver · · Score: 1

      Besides, if you're dealing with your own programming, why wouldn't you check each individual section of your code independently? As you stated in earlier posts, checking your code after its compiled provides you with information about what the processor's actually doing vs. what you wrote. I only wish we had desktop machines that ran on a better architecture than x86 (by which I mean more organized and less frustrating).

    116. Re:Double standards by QuietObserver · · Score: 1

      Well stated. I've always laughed inside when I've read someone claiming that Microsoft couldn't have achieved their monopoly without producing quality code. It's nice to see others who understand these basic economic principles.

    117. Re:Double standards by Cyberax · · Score: 1

      "I've NEVER seen it where sound never worked thanks to ALSA."

      I've seen it. For example, ALSA continuously tries to turn off sound output for the front panel of my desktop. ALSA can't autodetect my Bluetooth headset, etc.

    118. Re:Double standards by rtfa-troll · · Score: 1

      I don't think the compiler has any way to be sure. The check against that in the i386 architecture is to make sure that the page at address 0 isn't mapped in to process / kernel memory. However, that mapping could be changed at run time, so the warning could be there or not during program run for the same code at compile time.

      --
      =~ s,(.*),<sarcasm>$1</sarcasm>,g if any_point_you_wish();
    119. Re:Double standards by reiisi · · Score: 1

      You're confusing run-time checks with compile-time checks.

      Go look at the code. The code contained one of those errors where the programer gets a pointer to a structure from a function, loads a field from the structure, and then after loading the field, checks whether the pointer was valid, in this case, non-NULL.

      The compiler had aggressive optimizations on, saw the field being loaded, and assumed that meant the pointer must be valid, and assumed valid meant non-NULL, and deduced that the conditional code must therefore be dead.

      And, yes, while the compiler can't see for NULL pointers at compile-time, it can see what happens to a pointer between the time it's set and the time it is tested. (And make, as in this case, potentially bad assumptions. Or, rather, follow the potentially bad assumptions the compiler writers made.)

      --
      Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
    120. Re:Double standards by 0ld_d0g · · Score: 0

      Is that why Vista adoption has been so awesome?

      I wonder who was buying MS software when there were at 0% market share and as you say they don't produce quality code.

      Alright later, back to the real world...

  4. Good find by Anonymous Coward · · Score: 0, Flamebait

    After all the crap Brad had to put up with from the SELinux faction, it's good to see technical ability once more scoring points over politics.

    (I understand the irony that this comment, is, in itself, purely political)

  5. Just don't use that version by BPPG · · Score: 3, Insightful

    It's important to note that there is almost never any "preferred" or "special" release of Linux to use. And obviously this flaw doesn't affect people that don't use any security modules.

    This is not good news, but it's important news. The kernel's not likely to have a "fixed" re-release for this version, although there probably will be patches for it as well. And when in doubt, just don't upgrade. Not very many machines can take advantage of all of the cool bleeding-edge features that come with each release, anyways. Lots of older versions get "adopted" by someone who will continue to maintain that single kernel release.

    --
    What's the value of information that you don't know?
    1. Re:Just don't use that version by Kjella · · Score: 3, Insightful

      It's important to note that there is almost never any "preferred" or "special" release of Linux to use. (...) And when in doubt, just don't upgrade. Not very many machines can take advantage of all of the cool bleeding-edge features that come with each release, anyways. Lots of older versions get "adopted" by someone who will continue to maintain that single kernel release.

      As a guess pulled out of my nethers 99% use their distro's default shipping kernel, which means there's maybe a dozen kernels in widespread use with a long tail. Unless you're living on the bleeding edge that's what you want to do, otherwise you have to keep up with and patch stuff like this yourself. I'd much rather trust that than not upgrading or picking some random kernel version and hope it's adopted by someone.

      --
      Live today, because you never know what tomorrow brings
    2. Re:Just don't use that version by INT_QRK · · Score: 1

      I'm just curious about 2.6.30 version. In just ran a > to recheck my version and I'm using 2.6.28-13. I ran update just to make sure, and this is the current version for my distribution. So, can anyone tell me whether 2.6.30 is a stable version in widespread use, or is it a bleeding-edge version under development and test. Finding flaws in DT is what's supposed to happen. Unfortunately the takeaway headline for some will be "see? told you Linux is just as vulnerable as Windows!" Well maintained distributions like Ubuntu and its parent distribution Debian take extraordinary care to not only ensure the most stable functioning software base, but seldom have I read of a major flaw for which I haven't seen the update precede announcement of the bug. In those few cases, I read of the bug, and was able to download the fix in very short order. Neither Windows nor Apple have matched their record of response in my experience.

    3. Re:Just don't use that version by INT_QRK · · Score: 2, Funny

      don't know why but "uname -a" was replaced by ">" in my above post...something I did

    4. Re:Just don't use that version by Tanktalus · · Score: 1

      I would expect most distributions to take the fix from .31 and apply it to .30. Most distributions are pretty good at watching for CVEs and other high-importance bug reports and backfitting them. For example, I would expect the fix to show up in the ebuild for Gentoo Real Soon Now .

    5. Re:Just don't use that version by PReDiToR · · Score: 2, Informative

      Your distro (lets say Fedora for this example) has to get the sources for a new kernel, apply their own patches, test that the kernel works, package it and then put it out to beta testers to see if it breaks any one of the many configurations of Fedora that are out there.

      Sound familiar?

      Then they have to upload it to their package management servers and put the fix out there for you to use.

      This might not sound like a lot of work, but who needs a new kernel when they are busy with a whole truck full of other packages that people would notice an upgrade in (OpenOffice.org, KDE, Gnome etc.)?

      If they keep to a kernel version for as long as possible they don't have to rewrite their own patches for a new version, they don't have to wonder if a new problem that comes through is due to the new kernel and they don't have to expend resources on a fairly back-of-the-store package that people (who use stock kernels) don't care about much.

      Contrast that with other users (like myself) who eschew the patches that a distro puts into their kernels and download the latest vanilla sources from kernel.org (usually the same day it comes out), go through the config to make sure nothing major needs tweaking and compile a kernel that will only run at full potential (if I configured everything right ... ) on a very small number of computers, not the whole gamut of x86 based machines (usually) that the Fedora stock kernel is designed for.
      Even on my Arch Linux system that is very good at using up to date sources I prefer to roll my own. If you (and others like you) would prefer to run a newer kernel, read up on it (Scroogle Is Your Friend) and don't be afraid to try. The worst that can happen (if you keep your original kernel in the boot menu, and the modules to support it) is that your new shiny kernel sits there and tells you that there is no way on earth it can boot the system and it is having a bit of a panic with itself. Fixed by booting into your stock kernel and trying again.

      Good luck with it if you choose to go that direction, and remember to read the changelogs for the newer kernels to see what has been improved and fixed. The latest stable kernel is 2.6.30.1, not 2.6.30. It isn't bleeding edge, it is the latest stable. Bleeding edge kernels have -xxn appended (where xxn is letters and numbers depending on what type of kernel or patches are added).

      --

      Do not meddle in the affairs of geeks for they are subtle and quick to anger
    6. Re:Just don't use that version by SEWilco · · Score: 1

      It's simpler than not using that version. It's a version of the kernel which has only been distributed in one specialized Red Hat distribution. So it's hard to find a vulnerable machine in the wild. The other vulnerable group are bleeding-edge developers who compiled that kernel, and they'll upgrade as soon as one of them fixes it.

    7. Re:Just don't use that version by thejynxed · · Score: 1

      It is already fixed in 2.6.31-rc3-git3, I believe back on Thursday. This exploit was made generally known on Friday. Now you just get to wait for the distro maintainers to actually implement the patched kernel.

      BTW, this issue has been found in -some- kernel versions going back to 2.6.18 or so. Apparently it's not been in every single kernel release, but keeps appearing now and again.

      This can happen anywhere in the kernel or relative code that has similar structures, and allows the exploiter to A) cause overruns B) totally trash memory C) access userspace memory data from kernel-land and vice versa, as the kernel thinks it is accessing kernel memory space when it is in fact accessing userland memory space at address 0 (which shouldn't have been able to be mapped by Pulseaudio or any similar program/subsystem).

      This particular structure should have never been written like this to begin with. Obvious error, and I am not even a day-to-day programmer.

      --
      @Mindless Drivel: 100% of Twitter posts ever Tweeted.
    8. Re:Just don't use that version by Shamenaught · · Score: 1, Informative

      It is stable, but it will take a little while for the packages to find their way into the network for your particular distribution.

      Generally any release with an even number at the end will be a stable release. The kernel development cycle is basically: add functionality (odd releases), make stable (even releases).

      As for whether 2.6.30 is really bleeding edge, I wouldn't have said so. It's not yet in wide use, as not that many new distros have been released since it came out. See: Distros are often built on top of a kernel, so changing the kernel just before it's about to be released can rock the boat a little even if the kernel itself is stable. I personally wouldn't bother upgrading unless there's a feature in the kernel that you needed. 2.6.31 could be considered bleeding edge, however, as that's an unstable release that they'll be shoving a lot of new functionality or completing stuff that wasn't ready for 2.6.30.

      That said, there were features that I wanted to check-out in the 2.6.30.1 kernel and so I did download and compile it (but only put it on the machine that needed it).

      --
      mysql> SELECT * FROM `places` WHERE `place` LIKE 'home`; Empty set (0.00 sec)
    9. Re:Just don't use that version by RiotingPacifist · · Score: 1

      2.6.30 is the latest stable vanilla kernel, I doubt its in widespread use as no distro (or no major/security conscious distro) ships with it (atm i think the latest kernel in a major distro is 2.6.29.5(-191) in fedora 11. It may have got into some rolling release distros (debian sid, maybe even squeeze, arch) but the impact of a bug in 2.6.30 is minimal, what really matters is if it affects earlier kernels. This is why its very hard to compare linux security to anything else, even when vulnerabilities get into the vanilla kernel unless they go unspotted for several versions (1/2 for desktop distros, 3/4 for server distros) they never make it to distros.

      --
      IranAir Flight 655 never forget!
    10. Re:Just don't use that version by RiotingPacifist · · Score: 1

      Thats nice in theory but vulnerabilities like this are less likely to get into debian/RHEL or even ubuntu/fedora kernels because they are tested for months after the kernel is released and benefit from reports like this.

      The worst that can happen (if you keep your original kernel in the boot menu, and the modules to support it) is that your new shiny kernel sits there and tells you that there is no way on earth it can boot the system and it is having a bit of a panic with itself.

      No the worst that can happen is that you miss a kernel patch announcement or are too busy actually using your systems to update (even a well optimised kernel is still going to take a while to recompile) and you sit there running a vulnerable/faulty kernel for months. Sure distros might take a couple of days to patch, test, release, but
      1) apt-get/yum update, will be a lot easier, quicker and can be automated
      2) Is pretty unlikely (if you chose a good distro) to give you any headaches
      There are plenty of reasons to use your own kernel but security isn't one.

      It isn't bleeding edge, it is the latest stable. Bleeding edge kernels have -xxn appended

      I'm not a kernel developer but afaik:
      2.6.30.x is pretty close to bleeding edge, only 2.6.31-rcx (and perhaps 2.6.31-next) more on the edge for users, (technically there is -mm but that is more for developers), all other -xxn will be kernels patched for particular purposes and its hard to really call them bleeding edge (in many stacks they may be behind -mm or even -next)

      --
      IranAir Flight 655 never forget!
    11. Re:Just don't use that version by mvdwege · · Score: 4, Informative

      I'm very sorry, but you are wrong.

      There is no longer an unstable/stable kernel branch difference. Essentially all new kernels are development versions. It is specifically up to the distribution vendors to pick stable kernels out of this continuous release stream.

      Mart

      --
      "I know I will be modded down for this": where's the option '-1, Asking for it'?
    12. Re:Just don't use that version by budgenator · · Score: 1

      [paul@localhost ~]$ uname -a
      Linux localhost 2.6.30-ARCH #1 SMP PREEMPT Sat Jul 4 11:13:08 UTC 2009 i686 AMD Athlon(tm) 64 X2 Dual Core Processor 6000+ AuthenticAMD GNU/Linux

      Well Arch Linux considers it stable, but I think it went into stable from testing yesterday LOL. Arch stays more leading and even bleeding edge than other distro's.

      --
      Apocalypse Cancelled, Sorry, No Ticket Refunds
    13. Re:Just don't use that version by Shamenaught · · Score: 1

      Really? Oops. Checking facts...

      Okay: It seems that I was wrong in a couple of ways. The second number (eg, 2.5) was the number that denoted unstable. See here (big page, so Cntrl-F 'unstable') and mvdwege is correct that presently every there's no 'unstable' branch (as 2.3 and 2.5 were) linky here.

      --
      mysql> SELECT * FROM `places` WHERE `place` LIKE 'home`; Empty set (0.00 sec)
    14. Re:Just don't use that version by eparis · · Score: 1

      "And obviously this flaw doesn't affect people that don't use any security modules."

      Wow, you couldn't be more wrong. The flaw is in the network tunnelling code. Nothing was wrong with the LSMs, spender was just able to get around SELinux protections (by running his code in a domain that wasn't being confined by SELinux, wow, impressive.) Running his exploit in a confined SELinux domain would have prevented any damages. Any other LSM (SMACK/TOMOYO/AppArmour) doesn't even to try to protect against this class of kernel bugs.

      "The kernel's not likely to have a "fixed" re-release for this version"

      Again, you couldn't be more ignorant. Greg kh has stable releases. He has stable releases for 2.6.30. Magic. A 'fixed' re-release.

      To fix some other incorrect statement in these comments. Linux allowed the mapping of page 0. It always has, mainly for msdos compatability. WINE makes use of mapping the zero page, as does the vm86 emulation used by DOSEMU, and a number of programmers have made use of mapping the NULL page as expected behaviour in their programs. I call it bad style, but it works.

      When I wrote the Linux kernel patches to prevent the mapping of the NULL page and we specifically wrote it to allow certain programs to do this. As we find and fix those programs we are tightening the restrictions. See how in the 2.6.31 code (long before the exploit was known) we moved the mmap NULL page protections out of the LSM and into the generic security subsystem, thus they could help people who build without any LSM.

      The linux kernel (in response to this exploit) has decided to start building with -fno-delete-null-pointer-checks. There is a performance trade off, but it does harden the kernel again future bugs like this one. Normally this would have been a NULL pointer OOPS (and that's how the vulnerability was found and fixed before spender wrote his exploit) when it should have been a fine situation with a safe return code. (I think the argument that the gcc optimization is generally a bug have been sufficiently debunked, it's busted tunneling code, no ifs ands or buts)

      I'm working with the gcc team to come up with a way to find these situations but as many have pointed out, considering inline functions and macros it's not uncommon to know that a given branch is impossible to take. Maybe we can use this work to make it faster to find these bugs in the future, but generally, optimizing out branches that are known to be impossible to take is the right thing to do.....

    15. Re:Just don't use that version by Antique+Geekmeister · · Score: 1

      Oh, I _wish_ bleeding edge developers would keep such tools up-to-date. It's inherently unstable, though: developments in one package may conflict with those of other packages, in ways that can be nightmarish to resolve. Take a look at Perl's changes in what modules are part of the core Perl tarball, and what are add-ons, to see what such an upgrade can destabilize. So many developers upgrade only those individual components they need, when they need them.

      I like to keep a system near the bleeding edge myself, so that I can run into the problem before the developers do and hand them a solution, preferably by sending the bug report upstream and getting it patched in the source itself. But it's a huge timesink.

    16. Re:Just don't use that version by DavidTC · · Score: 1

      This is why distros come out with kernels that aren't the newest one. I'm willing to bet that no distro is ever going to come with this kernel.

      --
      If corporations are people, aren't stockholders guilty of slavery?
    17. Re:Just don't use that version by Anonymous Coward · · Score: 0

      It also affects people who have pulseaudio installed.

  6. DRM is defective by design. by BPPG · · Score: 4, Informative

    I think that tag is mostly reserved for DRM related news...

    And I have seen news about linux DRM modules also tagged that.

    --
    What's the value of information that you don't know?
    1. Re:DRM is defective by design. by calmofthestorm · · Score: 1, Offtopic

      ...you mean the direct rendering module or proprietary modules that some evil vender installs? I don't know of any digital restrictions management kernel modules but wouldn't be that surprised if they existed.

      I remember freaking out the first time I noticed the DRM module loading when I came over the Tux's loving embrace years ago.

      --
      93rd rule of Slashdot: No matter how obvious my sarcasm is, my comment will be taken seriously by someone.
    2. Re:DRM is defective by design. by BPPG · · Score: 1

      ha ha, yeah, I meant the digital restrictions management, usually aimed at vendor installs and special Linux boxen.

      --
      What's the value of information that you don't know?
  7. I always disable those by brunes69 · · Score: 2, Interesting

    I always disable those security modules as they always end up to incompatibilities and other erratic behavior in software.

    Exactly what do they do anyway?

    1. Re:I always disable those by 140Mandak262Jamuna · · Score: 4, Funny

      They create vulnerabilities by allowing remote code to overload error handlers and thus pwn your system?

      --
      sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
    2. Re:I always disable those by Antique+Geekmeister · · Score: 2, Interesting

      They ruin otherwise working code that was written in slightly different environments, and for which the very arcane behavior of SELinux has not been tuned. They're also often difficult to write test suites for, especially the unpredictability of SELinux changes, since they affect behavior due to factors entirely outside the control of the particular program author: they affect behavior based on where the package installs the code and what SELinux policies are in place.

      It's gotten better: Linux operating system authors have gotten more capable with it, and the software authors have learned not to stuff everything wherevery they feel like (with the exception of Dan Bernstein, but he's loosened his licenses, so we can fix that now).

    3. Re:I always disable those by Anonymous Coward · · Score: 0

      Well the exploit seems to also works without the security modules. http://www.youtube.com/watch?v=UdkpJ13e6Z0&fmt=35

      Security modules are just way to create more fine-tuned restriction policies but that's no silver bullet if you have no idea of how it works.

    4. Re:I always disable those by wytcld · · Score: 1

      They create the illusion of security, while preventing different applications from working smoothly together in the *nix way. If you really must fracture your environment for security, it's smarter to use virtual machines, or chroot jails (both of which also can have vulnerabilities - there's no perfection this side of the Moon). If you don't know enough to lock down stuff in a single environment without AppArmour or SELinux, you're going to end up in trouble soon enough anyway, since there are still plenty of ways to expose vulnerabilities.

      The basic philosophy is "Jack doesn't know enough to secure his web server, so we'll make sure when its compromised it will have limited access to other system components." But the end result is it makes the system even more complex, so the odds of Jack ever learning enough to lock it down become much worse.

      --
      "with their freedom lost all virtue lose" - Milton
    5. Re:I always disable those by RiotingPacifist · · Score: 1

      Your doing it wrong! They restrict programs to what they should be doing, ofc it depends on how well they are configured (e.g ive never seen anybody notice apparmor on ubuntu, but plenty of people bitch about selinux on fedora (even though it has stopped in the wild vulnerabilities)).

      We agree that running a program as root where it can do anything is a bad idea, follow the idea through and you shouldn't let a network daemon access to your home, a web browser shouldn't be writing anything to /etc. The idea of security modules is great, atm the problem is that its either to hard for your average user to understand what's going on or security experts claim it cant do enough, but once the interaction with them is perfected your average user should benefit significantly as even relatively unsafe software (firefox,sendmail,etc) will be unexploitable.

      --
      IranAir Flight 655 never forget!
    6. Re:I always disable those by godrik · · Score: 1

      AppArmor is a security module that allows to associate to each process (binary perhaps, I do not know exactly) a exact list of files it can access. The point is that even if apache is running as root and is corrupted, it can not read or modify files from /etc or /usr...

    7. Re:I always disable those by Antique+Geekmeister · · Score: 2, Interesting

      SELinux does help prevent tools from executing in locations or in places that are inappropriate: it helps reduce the destructive capabilities of components that are mis-installed, installed without proper permissions, or that have certain classes of errors. It also helps force you to think before doing something foolish, such as running CGI tools that are not in /var/www/cgi-bin/: it's too easy for foolish people to use .htaccess or poorly handled HTTPD include directives to include some very foolish CGI tools, and I've had SELinux detect this and prevent a fool from running his very dangerous CGI utilities out of his NFS mounted home directory. So it has uses.

      Now, that "Jack will never learn to lock it down, so let's not help him so that he has to do it all from scratch himself" message you seem to have is, I'm afraid to say, both popular and insane. Jack _does not want_ to have to learn this material. Jack just wants to have his web site work. Jack doesn't have the time or the money to invest in a long-term career in server security programming: This is a modest tool that can be helpful against some classic errors. (Running CGI utilities out of home directories is my favorite that is blocked by SELinux by default.)

    8. Re:I always disable those by x2A · · Score: 1

      Wait... SELinux is easier to configure than Apache?!!

      I do the chroot/unionfs/bind mounts way mostly... can stick people on parts of the filesystem mounted with noexec etc, and then use bind mounts to bring directories that will allow executables into their namespace. The main problem I've had is with people running php stuff (probably because of the low bar of entry to writing stuff with php than it being inherently insecure, at least with newer php versions, but that debate's not important here) and finding that somehow people have been able to run code that's downloaded a bot to run. I've found a few of them end up in /tmp, which has then failed simply because /tmp is on an noexec filesystem. Using chattr +ia on directories like /bin, /usr/bin, avoids stuff where tools like 'cp' and 'ls' get kitted (and I rename the chattr tool). None of these things by themselves would probably stop a determined hacker, but most attacks aren't determined hackers (I have no clients that are big enough to attract that kind of attention), but they do stop the automated search-and-infect scripts from working.

      But mostly - I will not compile php as an apache module! Fcgi, each site's php instances will run as their own user! I can't believe the amount of hosts out there that don't do the seperation, and anyone with a site on a server can access everybody elses stuff as it all runs as the apache user.

      Sorry. Little rant there. I've come into too many infected servers tasks with cleaning out infections... it gets old. I guess whatever security measures there are, they work least when you don't use them. That said, sometimes security measures do give more entry points to a system. Code for a telnet server can be really simple and easily audited, that as long as your network's not being sniffed, it can't be broken in to. SSH on the other hand can be (and has been) vulnerable through exploits in the compression libraries, the ssl libraries. I remember a version of Nortan anti-virus email scanner than had a buffer overflow bug that meant that a properly constructed email would allow arbitrary code to run on the system, which meant that if you wasn't running the email virus scanner, you were actually safer than if you were.

      Oops, I forgot to stop ranting. I will now :-)

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    9. Re:I always disable those by Antique+Geekmeister · · Score: 1

      xa wrote:
      > Wait... SELinux is easier to configure than Apache?!!

      Oh, dear. SELinux often has working, well-defined structure that programmers are wise to follow (such as keeping CGI tools in the standard Apach location, /var/www/cgi-bin, rather than scattered around your filesystem).

      And oh, my, yes, PHP utilities add their own flavor to Apache security. (They basically ignore it altogether: there is a lot of very, very dangerous PHP out there.) It basically has all the delightful power of Perl, but running as the shared 'httpd' or 'apache' user, and with less debugging, and with even less quality control than CPAN provides. It's actually quite frightening to see the utilities people stuff in PHP modules expected to run on semi-public webservers.

      I'd be very curous to see guidelines or notes on getting PHP utilities running as their own user. There are some old utilities for managing some shared resources I'd love to see more properly isolated from the 'httpd' user access, and I'd particularly like to provide that for Subversion and git utilities. That's not necessarily PHP, but it's still a good idea to separate the 'httpd' user from the 'svn' user to allow better control of SSH access in parallel to HTTP access to a Subversion repository. I haven't seen any coherent guidelines for that, just huge numbers of webpages which break down to "and then a miracle occurs" in the actual setup.

      But telnet use, like the older 'rsh' use on which ssh is based, allows wholesale password sniffing in a way that even flawed SSH servers do not. Guaranteeing that "your network isn't sniffed" is like guaranteeing that your date doesn't have venereal disease. It's just safer to stick with serious protection until you actually have a reason to use telnet, or to want children.

    10. Re:I always disable those by x2A · · Score: 1

      "I'd be very curous to see guidelines or notes on getting PHP utilities running as their own user"

      Fcgid is what to look for, which is a slightly newer replacement to the original fastcgi. Compile php with --enable-fastcgi. There are a few bits that get more complicated, as each website gets its own php.ini file etc, which can make management more tricky, but nothing that a bit of scripting doesn't sort out very nicely. One good thing is it means I can easily offer multiple versions of php for people that need specific versions (php4, 5.2 and the new 5.3) side by side - launching different version for different file extension (.php4, .php5, .php53). When the first one's run, it spawns a php-cgi child as the user you specified (with obvious uid/gid checks on the files being run) which then sits listening and talking to apache over a pipe/socket - full privilege seperation. Then, user directories can be 700 instead of the 755 (or even 777 if php running as httpd needs to be able to read/write to same directories as the users scp/ftp user!)

      If scripts to make it all manageable would be useful let me know, I'll try dig out the important bits 'n post 'em up somewhere.

      "It basically has all the delightful power of Perl"

      I wish! I've had to do some work recently on projects in php - I always knew I didn't like the language, but I've had the pleasure of finding out all the reasons why not now. I've spent ages looking for how to do certain things in php that you can do in perl and even javascript running in an old browser only to find out that in php you just can't. Ridiculously limited variable scoping control, no anonymous functions (5.3, released 2 weeks ago has it, but it's not made it out into the wild enough to be able to count on that being available yet), poor introspection, inability to trap variable accesses, the list goes on (but they're the main brick walls I've hit with it). Oh and they just randomly change well established vocabulary; like exec(), whether you're programming C, Perl, even writing Bash scripts, it does the same thing... but not php. Oh yeah, you can't have a function that accepts values passed by references if you ever might wanna call it with an immediate value (writeString('hello there'); or writeString(getInput());) because it can't figure out how to pass those by reference, so you end up having to copy everything around between functions wasting cycles when it could just pass a goddamn pointer... grrr!!!

      "Guaranteeing that "your network isn't sniffed" is like guaranteeing that your date doesn't have venereal disease"

      Quite possibly, but point was just that the telnet server has one entry point, which means that with an unsniffed password, it's highly secure, as it's simple enough to guarentee that. The more complex the code, the greater potential for hidden entry points to exist within it. Perhaps what's needed is ssh running as an unprivileged user that merely passes on connections to the telnet server, as then exploits in the compression/encryption code don't open up the server. Academic here really, I know, openssh is a lot better than it used to be, with things like not enabling compression until after user is authenticated so that flaws in the compression code can't be used as an entry point, and a lot of other bugs have been found and closed down. Recent security issues that've been found (that I've been aware of) have been more theoretical than practical.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    11. Re:I always disable those by brm · · Score: 1

      > (Running CGI utilities out of home directories is my favorite that is blocked by SELinux by default.)

      Isn't this more properly in the purview of the web server configuration? The only problem is that it's too easy for Jack to change the web server config to allow the thing he thinks he wants to work. All SELinux is doing is making the security configurations too complex for Jack to understand and disable it.

      Until he realizes he can just disable SELinux and get those .htaccess files to work the way he wants.

    12. Re:I always disable those by Antique+Geekmeister · · Score: 1

      Well, I personally appreciate that it warns me when people are doing stupid things like telling me, as the web admin and the security admin, that a .htaccess has been set to run CGI scripts out of a local directory, by having them fail outright and provide a log of why they failed. This lets him know that it was a bad idea, rather than proceeding merrily along and proceeding to _think_ about what he's doing, earlier in the process.

    13. Re:I always disable those by Antique+Geekmeister · · Score: 1

      Interesting material on the new Fcgid, thank you for the pointer.

      That 'telnet server has only one entry point' is somewhere that you and I disagree. Take a look at a nasty little technique called 'arp poisoning', that can let other devices on your network confuse your switches and get copies of your packets. It's nasty, and a clear proof that running clear text password handling inside a network without _absolute_ control of every node's security leaves you vulnerable to a single compromised server stealing packets from throughout your local network.

      There are ways to block it, but I haven't seen anyone in the last 8 years actually bother, in multiple large and small environments.

    14. Re:I always disable those by x2A · · Score: 1

      "Take a look at a nasty little technique called 'arp poisoning'"

      Where significant is that a risk though? Datacenters I use (and I assume this is common practice, I wouldn't trust anywhere where it wasn't) use virtual lan channels to each customer, so arp packets just can't be passed around... but still, the entry point is still physical access to the network, whether you're sniffing or poisoning, you can't do it behind a router, which is where the majority of the world lives. I'm not saying that risk is low enough to be worth trusting; I don't telnet to my servers, although will often leave a telnet server on a nonstandard port open in case of emergency situation, my point is just that increased complexity of code increases chance of flaws in the code... the telnet server's very easy to make unexploitable, even if your network isn't.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    15. Re:I always disable those by Antique+Geekmeister · · Score: 1

      The virtual LAN channel, provided by tools like load balancers, is fine for protecting you from _outside_ access to your internal data channels. But it doesn't do _anything_ to protect you from internal access! This is the hard, crunchy shell, soft chewy underbelly approach, and it remains unfortunately popular. It only takes _one_ malicious internal node. Once a cracker has gotten inside, whether it's an infected laptop connected by VPN, a Windows zombie infected by who-knows-what channel, a VPN connected laptop that you personally use for remote debugging and which happens to have become rootkitted by any means, or a switch that someone else's machine in the datacenter has been able to access due to poor password choice or an unpatched vulnerability, you are _screwed_ once someone else is inside.

      The potential vulnerabilities, many of which I've seen personally, are legion. It's why I consider a remote data center, or any environment where I don't personally know and own every single node, to be more like a hotel room: you don't leave the money or jewelry sitting out where someone might be tempted, and you don't leave unencrypted passwords in use _anywhere_.

    16. Re:I always disable those by x2A · · Score: 1

      Nooo I've seen the datacenters where I have machines, security is very good, palm scanners, swipe cards, pass codes, cctv... a compromised node will be the other side of their nodes and unable to affect mine, no one can just get onto the network. Datacenters just aren't like hotel rooms in the slightest. Not proper ones. One place, the sales guy tried to sneak us in through a side room to show us inside, they deactivated his card and cancelled his codes locking him out. The only way you're gaining access to my server is through a software vulnerability.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    17. Re:I always disable those by Antique+Geekmeister · · Score: 1

      Yes. For such a facility, physical access is restricted. Do you have a VPN into that environment? Then it's vulnerable to use and abuse by the VPN members, and I've unfortunately just this week explained the facts of life about this to a manager at a partner company who wanted his unpatched, unsecured personal laptop to have access to his company's internal servers "so he can look at things". If I were his IT guy, I'd have been compelled to satisfy his request, because he helps sign the checks. But I'm afraid that sort of thing is typical.

    18. Re:I always disable those by x2A · · Score: 1

      No, access is tcp/ip to your machines. If you need to do work on your server, you can request a kvm be plugged into your machine that you can access from an outside room, or of course they will bring your server out. You can connect to the power supply to turn off/on the power to your individual servers. They're a multimillion installation with no doubt hundreds of customers, from single-server customers to those who'll rent by the floor space. Anyone can put a server there which means that network security is paramount, as no serious (and knowledgeable) business is going to want to put machines on a network, esp pay to have machines on a network, if that network is an entry point to their machines (by stealing your MAC address or so on). It's not hard to secure your network so that the only entry points are those in your software.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    19. Re:I always disable those by Antique+Geekmeister · · Score: 1

      I'm genuinely surprised if your datacenter network isolation is as good as you describe. I've seen such setups specified, even written into contract, and then seen idiots plugging random personal laptops into the secured corpirate subnets simply to get work done. (TFTP setups to update ocre switches are a prime example where I've noticed technicians installing personal hardware.)

      It's not technologically "hard" to secure your network. But it takes sophisticated upstream switches to avoid ARP poisoning, and someone with a clue to configure it, and such resources are often pretty expensive. I'm just not seeing it in use: "authorized" personnel with VPN access are some of the worst potential vectors into such a secured network.

    20. Re:I always disable those by x2A · · Score: 1

      What can I say? We're moving a bunch of servers to a pretty new datacenter as it's close to home (along with other reasons) and I've been 'n checked out the place a couple of times myself, met with techies, met with ppl that run the place, seen how strict the security is (to the point where it got in our way on a few things), got a good idea on their level of ability, and find myself pretty convinced. It's definitely doable, and where something is doable, you can bet there's a fair chance someone somewhere will have done it. I'm not a terribly lucky person which is why I struggle to believe that my experiences is as rare as you make out.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
  8. Just like Linux by Anonymous Coward · · Score: 0

    More and More like windows everyday

    1. Re:Just like Linux by Dunbal · · Score: 1

      More and More like windows everyday

            Actually no, this will probably be fixed by later today, as opposed to having to wait for "n" intervals of "patch tuesday"...

      --
      Seven puppies were harmed during the making of this post.
    2. Re:Just like Linux by Tony+Hoyle · · Score: 3, Insightful

      Unless they're going to add a proper warning for the condition to gcc 'today' it won't, really.

      Sure there are enough developers to go over the kernel to make sure such errors haven't been missed elsewhere, but all it takes is one to miss it and it's still there. Then there's all the other software compiled by gcc..

      I'm not entirely sure how it can lead to an exploit (short of remapping page zero, which requires root privileges so doesn't really count) but since it has it's going to need a proper fix.

    3. Re:Just like Linux by shentino · · Score: 1

      I was going to say fat tuesday but as an example of bloatware it goes without saying.

    4. Re:Just like Linux by shentino · · Score: 1

      It was just a case of overly aggressive optimization. And attempting to dereference a value BEFORE you verify its non nullity is a programming error.

    5. Re:Just like Linux by Anonymous Coward · · Score: 1, Funny

      I'm using NoScript and Adblock Plus so I'm not worried.

    6. Re:Just like Linux by Jimithing+DMB · · Score: 3, Interesting

      Funny enough a few months back I made a very similar error if not the exact same error while coding on the bootloader for Darwin/x86. Except in my case it wasn't exactly a true error because in the bootloader I know that a page zero dereference isn't going to fault the machine but will instead just read something out of the IVT.

      So as I recall it seemed perfectly reasonable to go ahead and initialize a local variable with the contents of something in the zero page and then check for null and end the function. But GCC had other ideas. It assumed that because I had dereferenced the pointer a few lines above that the pointer must not be NULL so it just stripped my NULL check out completely. Had it warned about this like "warning: pointer is dereferenced before checking for NULL, removing NULL check" then that would have been great. But there was no warning so I wound up sitting in GDB (via VMware debug stub) stepping through the code then looking at the disassembly until I realized that.. oops.. the compiler assumed that this code would never be reached because in user-land it would have segfaulted 4 lines ago if the pointer was indeed NULL.

      Obviously the fix is simple. Declare the variable but don't initialize it at that time. Do the null check and return if null. Then initialize the variable. If using C99 or C++ then you can actually defer the local variable declaration until after you've done the NULL check which IMO is preferable. It may be that the guy wrote it as C99 (where you can do this) then went oops, the compiler won't accept that in older C and simply moved the declaration and initialization statement up to the top of the function instead of splitting the declaration from the initialization. My recollection of how I managed to introduce this bug myself is shady but as I recall it was something like that.

    7. Re:Just like Linux by jelle · · Score: 1

      In fact, it already was fixed at least days before this /. article about it...

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    8. Re:Just like Linux by Anonymous Coward · · Score: 0

      Minus its usefulness

    9. Re:Just like Linux by Anonymous Coward · · Score: 0

      Suppose GCC changed its implementation so that NULL pointers were represented by a different bit pattern. All ones rather than all zeroes, say. Then next time you recompiled your code it would have stopped working because there likely wouldn't have been memory mapped at 0xffffffff.

      the compiler assumed that this code would never be reached because in user-land it would have segfaulted 4 lines ago if the pointer was indeed NULL.

      The compiler didn't assume this. The compiler assumed that you weren't dereferencing a null pointer because that isn't valid C. Hence the subsequent null check was redundant.

      When you do things that aren't allowed in C (like dereferencing null) you can't grumble if the compiled code isn't what you expect.

  9. Serious bug in gcc? by Anonymous Coward · · Score: 1, Interesting

    The explanation given by the SANS Internet Storm Center seems strange. Firstly, the code they provide as an example shows one variable being assigned "sk" and then another variable being checked "tun". I think the "if" statement should be checking "sk" and not "tun". Secondly, the assignment could be a perfectly valid assignment of null; "tun->sk" could indeed be null. The compiler should certainly not optimize out the if statement just because the variable has already been assigned. This would be a major fault in the compiler.
    Perhaps they have just oversimplified to the point of writing nonsense...

    1. Re:Serious bug in gcc? by Tony+Hoyle · · Score: 4, Informative

      gcc is definitely doing the wrong thing here.

      Given the code:
      a = foo->bar
      if(foo) something()

      gcc is doing precisely the wrong thing - optimising out the if on the theory that the app would have crashed if it was null.

      What it *should* do is throw a warning (even an error, given the clear intent of the code) pointing out that the variable is dereferensed before it is tested.

      This kind of error being missed by gcc is going to affect a *lot* of code - it's really not that uncommon a coding error, and is easy to do.

    2. Re:Serious bug in gcc? by dakkar · · Score: 2, Informative

      The description given by SANS is a bit misleading. What I believe is happening is:

      1. 1) tun is derefenced during the assignment to sk
      2. 2) if tun were NULL, the dereferencing would blow up the process
      3. 3) so the if (!tun) will always be false if we get there (says the compiler)

      Since point 2 is mostly true, the compiler is not completely wrong to assume point 3

      As Spengler says, a bigger problem is that loading SELinux (or, it looks like, most other security modules) causes the NULL dereference protection to be disabled.

      --
      dakkar - mobilis in mobile
    3. Re:Serious bug in gcc? by Bananenrepublik · · Score: 5, Insightful

      They were writing nonsense. GCC makes use of the fact that in the C language any pointer that was dereferenced can't be NULL (this is made explicit in the standard). People use C as a high-level assembly where these assumptions don't hold. This is why code that doesn't assume this breaks. This issue came up a few months ago on the GCC lists, where an embedded developer pointed out that he regularly maps memory to the address 0x0, thereby running into issues with this assumption in the optimizers. The GCC developers introduced a command-line flag which tells the computer to not make that assumption, therefore allowing the compiler to be used even in environments where NULL pointers can be valid.

      Now, the exploit uses this feature of the compiler (or the C language, if you will) to get the kernel into an unspecified state (which is then exploited) -- the NULL pointer check will be "correctly" optimized away. But in order to do this it first has to make sure that the pointer dereference preceding the NULL pointer check doesn't trap. This needs some mucking around with SELinux, namely one has to map memory to 0x0.

      This is a beautiful exploit, which nicely demonstrates how complex interplay between parts can show unforeseen consequences. Linux fixes this by using the aforementioned new compiler option to not have the NULL pointer check optimized away.

    4. Re:Serious bug in gcc? by Ritchie70 · · Score: 1

      Wish I had mod points today. This is a truly clear and understandable explanation of the issues involved.

      The embedded market is a very good point - and "embedded" doesn't necessarily mean what people thinks it means. It might, for example, mean that graphics card you just put in your computer that runs code itself.

      15 years ago I was dealing with code on a graphics card and, in fact, the video buffer was mapped in at 0x0 - which may have been a questionable choice, except that you could actually SEE a write to a null pointer.... the upper left corner would get garbage.

      --
      The preferred solution is to not have a problem.
    5. Re:Serious bug in gcc? by shentino · · Score: 1

      Except that the program really WOULD crash if foo were NULL.

      In the kernel, null pointer derefs have no place. It's not valid kernel space, and for userland access you're supposed to use special functions anyway.

    6. Re:Serious bug in gcc? by shentino · · Score: 1

      Why the hell is kernel code trying to dereference null pointers in the first place? Last time I checked, zero was in userland.

    7. Re:Serious bug in gcc? by Anonymous Coward · · Score: 2, Insightful

      The point is that GCC silently optimizes it away so the programmer has no idea that it's not even running the code they put in (however incorrect that code is). It's like saying "if there is an error in my code just remove that code and keep the rest without telling me".

    8. Re:Serious bug in gcc? by TheSunborn · · Score: 2, Informative

      This sound more like a gcc/embeded os bug. There is no requirement in c/c++ that the null pointer is (int)0. That is: It don't have to be all 0 bits.
      It just need to be distinct from any valid pointer, so if you run on a platform where you use memory address 0(Valid, but still wierd), you need
      to config gcc(If possible, I don't know if gcc supports this) to use an other bit pattern as null pointer(say 0xeffff), and then you need to configure your embeded os, to never
      return a memory address/buffer that contain the address you have used as null pointer.

    9. Re:Serious bug in gcc? by TheRaven64 · · Score: 5, Interesting
      Except that his explanation is wrong. Dereferencing NULL is illegal, but pointer arithmetic on NULL is legal (and, even if it were illegal, would be practically impossible for a compiler to check). This statement is not dereferencing NULL, it is (potentially) performing pointer arithmetic on NULL (adding the offset of the sk field to it) and then dereferencing the result. This may or may not be valid, depending on how NULL is defined (it doesn't have to be 0 in C, although it usually is), what the offset of sk is, and what the memory layout of the target platform is.

      On most modern platforms, NULL is defined as (void*)0 and the entire bottom page of memory is mapped as no-access. On some embedded systems, however, the bottom few hundred bytes are used for I/O and you get the addresses of these by adding a value to 0. On these systems it is perfectly valid (and correct) C to define a structure which has the layout of the attached devices and then cast 0 to a pointer to this structure and use that for I/O.

      --
      I am TheRaven on Soylent News
    10. Re:Serious bug in gcc? by Ritchie70 · · Score: 0

      I am not aware that NULL is part of the C standard.

      Maybe it got added and I missed it.

      --
      The preferred solution is to not have a problem.
    11. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      I would think the kernel would be the one place where you could expect access to an address close to 0 to succeed.

    12. Re:Serious bug in gcc? by Rockoon · · Score: 2, Insightful

      This issue is a bit more complicated than you people are making it out to be.

      For the most part, programmers DO WANT this kind of optimization, which is why they use an optimizing compiler. Things like dead-code elimination, constant propogation, and whole program optimizations are important to programmers.

      If you don't want this stuff done, you don't reach for an optimizing compiler and then enable those optimizations. Its their purpose. If (something we know at compile time) should *always* be eliminated in a decent optimizing compiler.

      Now, should GCC make assumptions in this specific case about the state of the pointer? Probably not. This isnt actualy a case of "something we know at compile time" so its a bug in the optimizer.

      --
      "His name was James Damore."
    13. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      Linux fixes this by using the aforementioned new compiler option to not have the NULL pointer check optimized away.

      Really? I thought the fix was http://kerneltrap.org/mailarchive/git-commits-head/2009/7/7/6148853 . Can you show me where this is reverted in favor of changing the compiler options?

    14. Re:Serious bug in gcc? by johnw · · Score: 3, Informative

      That is: It don't have to be all 0 bits. It just need to be distinct from any valid pointer,

      Correct - apart from the "just" bit.

      It doesn't need to be all 0 bits.
      It does need to be distinct from any valid pointer.

      *and*

      void *p = 0;

      must generate a null pointer, and:

      p == 0

      must come out true if p is a null pointer. The internal implementation need not be all zeroes, but it does need to look rather like it to source code.

    15. Re:Serious bug in gcc? by Ritchie70 · · Score: 1

      I've re-read these two posts multiple times now and I finally get the subtle distinction being made.

      Suppose the following:

      struct t { int one; int two; int three; };
      struct t* b = 0;

      "b->two" is not a dereference of 0. It is a dereference of "0 + the offset of two within the structure t." (Likely of the address 0x4.)

      However, "b->one" is a dereference of 0.

      So if the element of the structure being dereferenced is the first in the structure, this may be a valid optimization, although the efficiency gained by a jump-if-not-zero being eliminated seems negligible to me, and such an optimization should be explicitly called out in some fashion.

      If the element of the structure isn't the first, this isn't a valid optimization to make.

      --
      The preferred solution is to not have a problem.
    16. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      It should not optimize away invalid code though. It needs to pop a warning or error in those cases. Read the parent you replied to again.

    17. Re:Serious bug in gcc? by QuoteMstr · · Score: 4, Insightful

      Of course NULL is part of the C language, you blathering idiot, and it always has been. The level of ignorance here astounds me. Don't post about things you don't understand.

      Quoting from C89: (not C99, C89, the one that's older than dirt.)

      4.1.5 Common definitions The following types and macros are defined in the standard header . Some are also defined in other headers, as noted in their respective sections.... NULL which expands to an implementation-defined null pointer constant ... A.6.3.13 Library functions * The null pointer constant to which the macro NULL expands ($4.1.5).

      NULL wasn't even "added" in C89: NULL appears in the oldest, cruftiest UNIX code you can imagine. (That link is the original cat command from 1979.)

    18. Re:Serious bug in gcc? by marcansoft · · Score: 5, Insightful

      Sure it does - GCC knows at compile time that if the if() condition were true, we're already in the "undefined behavior" realm and all bets are off. So it gets rid of it. The code is broken: it's not the compiler's job to compile for the maximum defensiveness of the resulting machine code, otherwise we'd all be using bounds-checking compilers. If the compiler realizes that a certain runtime value will lead to undefined results (because the programmer chose to do so), it is free to break the execution as much as it wants in that case for code that runs afterwards. Essentially, undefined behavior is a contract signed by the programmer that says "I certify that this will never happen", which is why the compiler chose to perform this optimization.

      Even though the real bug is clearly in the code, moving on to the realm of what's desirable from a compiler, I think it's clear that this behavior can make some problems worse (to the compiler, problems are binary - if there's a problem all bets are off - but not to us). This is fine in the name of optimization, but I think in this particular instance either a) kernel developers should opt to turn this optimization off, or b) (better) make GCC warn when this kind of optimization happens, because it's quite likely a bug.

      In effect, the code is a form of broken defensive programming (you check after the fact whether you've screwed up). It's wrong, but we still wouldn't want the compiler to silently remove the check. So I think the ideal solution (besides fixing the code) is to add a warning to the compiler. NULL pointer dereferences are a bug in the vast majority of cases, and checking for a NULL pointer after dereferencing it (in such a way that the compiler recognizes it and is about to remove the check) is at best redundant and more likely a bug.

      There's still the issue of the page 0 fuckery. If someone can make page 0 accesses not crash the kernel then that's also a bug - there are good reason why we want NULL and neal-NULL pointer accesses to always crash.

    19. Re:Serious bug in gcc? by QuoteMstr · · Score: 1

      You're correct, but just to clarify for the mouthbreathers around here, consider the following C code:

      void* x = 0; int y = 0; memcpy(&y, &x, sizeof(y));

      There's no guarantee that y is still equal to 0. It follows that initializing a structure with memset(&s, 0, sizeof(s)) might not set to NULL (i.e., the null pointer constant called 0) any pointers in s.

      In practice, the difference doesn't matter. It's practically always 0. The difference is academic; no modern platform uses a non-zero NULL pointer.

    20. Re:Serious bug in gcc? by Rockoon · · Score: 1

      Testing for what is supposed to be impossible is not invalid.

      Imagine that if() was inside a macro, but the code before it wasn't. The macro is fully OK to test for a null reference even if in the context that it is employed (in specific cases) that it should never recieve one. Thats one of the reasons why optimizing compilers are important.

      The code is valid. Crappy? Yes.. Invalid? No.

      --
      "His name was James Damore."
    21. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      pointer arithmetic on NULL is legal

      Not according to the standard.

      The point is that gcc knows what the standard says and if the programmer does something (like pointer arithmetic on a null pointer) that is outside the bounds of the standard, anything can happen.

      The problem is when the programmer "knows" what a particular instance of undefined behavior does, but the compiler doesn't realize that.

      Your explanation of how different systems may react differently to pointer arithmetic on a null pointer is correct, but gcc appears to assume that the programmer is attempting to write standards-compliant (or portable) code. I think it's reasonable, but clearly there needs to be a way to turn that feature off.

    22. Re:Serious bug in gcc? by Rockoon · · Score: 3, Interesting

      In effect, the code is a form of broken defensive programming (you check after the fact whether you've screwed up). It's wrong, but we still wouldn't want the compiler to silently remove the check. So I think the ideal solution (besides fixing the code) is to add a warning to the compiler. NULL pointer dereferences are a bug in the vast majority of cases, and checking for a NULL pointer after dereferencing it (in such a way that the compiler recognizes it and is about to remove the check) is at best redundant and more likely a bug.

      My problem with this sort of thinking is when you throw in macros and templates and whatnot, there can end up being hundreds, thousands, even millions of "redundant" tests againt NULL specified by the expanded source. Now, I suspect that simply adding this warning to GCC and then compiling some large project would generate so many such warnings that the only reasonable choice would be to then disable that warning. The warning would then have no value, and if so then that certainly doesnt address the "problem."

      As far as the other stuff.. my point was that the arguement that the compiler should never optimize away such if() statements is flawed. I was responding to someone who did in fact make such a claim. There are certainly cases where the pointer absolutely cannot be NULL (or absolutely must be) .. ex, the pointer was just assigned, or its nested within another test for null.

      --
      "His name was James Damore."
    23. Re:Serious bug in gcc? by LateArthurDent · · Score: 2, Interesting

      Given the code:
      a = foo->bar;
      if(foo) something()

      gcc is doing precisely the wrong thing - optimising out the if on the theory that the app would have crashed if it was null.

      No, that's not the theory. They weren't optimizing the if out because the app would have crashed, they were optimizing the if out because if the programmer is dereferencing foo beforehand without testing, one can assume that the programmer is sure that foo is not null by that point. I agree with you that a warning should be thrown (and I'm not sure if it is or isn't), but that if really should be optimized out.

    24. Re:Serious bug in gcc? by jelle · · Score: 0

      Why do so many people think that "void * a = b->c" dereferences b? It takes the address of c in b and assigns it to a. It's only doing a pointer calculation: assigning an address of something to a pointer, it's not accessing any memory, so there is no way for a page fault or 'blow up' of any kind to occur.

      It dereferencing the null pointer would 'blow up', then the exploit would not have worked because no code after the 'tun->sk' would be executed.

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    25. Re:Serious bug in gcc? by jelle · · Score: 1

      "any pointer that was dereferenced can't be NULL"

      It's not being dereferenced.

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    26. Re:Serious bug in gcc? by Bananenrepublik · · Score: 1

      This is wrong. No object can be stored at the address pointed to by a NULL pointer. In order to meaningfully (in the framework of the C standard) access the members of a struct, the struct itself has to exist. It can't exist at the address NULL. Therefore it doesn't matter if (ptrdiff_t)NULL + 2 != (ptrdiff_t)NULL, the code is still wrong.

    27. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      You are confused. "a" will be assigned the value stored in "c" field of "b", not the address of "c" field of "b". "a = b->c" is identical semantically to "a = (*b).c" which is completely different from "a = &((*b).c)" where a is actually assigned the address of "c" field in "b". However, even this last statement is undefined behavior if b is NULL.

    28. Re:Serious bug in gcc? by RightSaidFred99 · · Score: 2, Funny

      Because... so many people know the C language? And you clearly don't?

    29. Re:Serious bug in gcc? by RightSaidFred99 · · Score: 0

      Yeah....about that...no.

      struct sock *sk = tun->sk; // initialize sk with tun->sk

      if (!tun)

      return POLLERR; // if tun is NULL return error

      There's no null check. 'tun' is literally being checked for 0 or not 0. I don't know why you're blathering on about nonzero NULL values.

    30. Re:Serious bug in gcc? by RightSaidFred99 · · Score: 1

      It is being dereferenced.

    31. Re:Serious bug in gcc? by Cacadril · · Score: 1

      Why do so many people think that "void * a = b->c" dereferences b? It takes the address of c in b and assigns it to a. It's only doing a pointer calculation: assigning an address of something to a pointer, it's not accessing any memory

      This is wrong. The code computes the address of 'b->c', reads that memory location, and stores the data it gets, into 'a'.

      The comment would have been correct if the code had been "void *a = &b->c;" In this case only the address of 'b->c' (which amounts to adding an offset to the contents of variable 'b') would have been loaded into variable 'a'. As it stands, the data stored in memory at that address is loaded into 'a'. The fact that 'a' is declared as a pointer does not change that. That only means that the data loaded from memory is assumed to be a valid pointer value (or NULL). This has the effect of determining how many bytes of register or stack space is used for the 'a' variable, 4 on 32-bit, 8 on 64-bit. The type declaration of the 'c' member of the 'typeof(*b)' struct determines how many bytes are read from memory.

      --
      There is no substitute for common sense. Especially, no body of rules will do.
    32. Re:Serious bug in gcc? by sjames · · Score: 1

      I could actually see defining all 1s (-1) as the NULL pointer. It would neatly make the error return value of functions that return a pointer more consistent with functions that return an integer. It's also far less likely to be useful to have a pointer to the top of addressable memory (since it could only be a char or (u)int8 value) than it is to point to the bottom. Of course, that would make the if(pointer) construct wrong or less intuitive (depending on if the compiler sees it as if(ptr!=0) or if(ptr!=-1) internally).

      That's not conventional, of course. I can't help thinking about the 1's complement machines that had a 0 and a -0 value that were not equal.

    33. Re:Serious bug in gcc? by marcansoft · · Score: 1

      I think it remains to be seen just how common this sort of optimization is. I'd say it's worth a shot - if there turn out to be hundreds of warnings then oh, well. I'm not sure how smart GCC's optimizer is, but maybe it can be tuned to at least restrict the warning to cases where there's a NULL check after a dereference of the same variable it's NOT wrapped in another NULL check (so the code path through that function, at least to within GCC's optimizer's limits, can indeed apparently hit the dereference if the pointer is NULL).

    34. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      GCC makes use of the fact that in the C language any pointer that was dereferenced can't be NULL (this is made explicit in the standard).

      At this point you could add vast amounts of credibility to your post by providing a reference to the appropriate part of the C spec. If you are so sure the standard says this then presumably you know roughly where so it would be a quick job for you too. This would be so helpful to those of us trying to make up our own minds. I now have to go away and re-read the spec. to find out if this assertion is true.

    35. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      It is not. Dereferencing means, that memory at address pointed by tun (0x0) is read, but this memory is not read. Instead the memory pointed by tun->sk (or tun + offset of sk) is read.

    36. Re:Serious bug in gcc? by shentino · · Score: 1

      Except addresses close to zero are userland from the kernel's POV and should NOT be accessed directly.

    37. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      Jesus dude. FFS. Do we need to draw cartoon explanations? tun is a pointer. To calculate where tun + offset one must read tun's value. Go read some books.

    38. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      Bad bad.

      Pointing NULL anywhere other than at binary zero causes enough code not to work that it is not a good idea (too much code tends to assume memset or static allocation initialized pointers to NULL these days).

      On the last embedded platform I messed with, there were NO invalid addresses period. Pointers were 16 bits and I had 64 KB total RAM.

    39. Re:Serious bug in gcc? by PsychicX · · Score: 1
      I think there are some subtleties here that are not being correctly addressed. Specifically, what's legitimate from the viewpoint of the kernel, versus what is legitimate from the viewpoint of C.

      On these systems it is perfectly valid (and correct) C to define a structure which has the layout of the attached devices and then cast 0 to a pointer to this structure and use that for I/O.

      No, it isn't "valid", per se. It is how you get the desired effect, and might work fine on said device -- but it's a blatant violation of the rules of C.

      Remember that C, like most languages, makes some very basic assumptions about the underlying platform and require certain things of it. One of these is you can't dereference NULL legally, end of story. From the kernel's point of view, strictly by the rules of the underlying processor and machine, this might be totally legal. But the C standard says quite explicitly that you can't be doing this under any condition. Not only that, it's undefined behavior -- you're in a particularly bad no man's land.

      Legal in C and legal on the machine are NOT the same thing. Please remember that difference. C still has rules and assumptions that you have to follow, and when you don't, things like this happen. That's why the code behind this vulnerability is NOT correct. It obeys machine rules but not C's stricter rules.

    40. Re:Serious bug in gcc? by TBBle · · Score: 1

      Going off the C89 spec linked earlier in this discussion

      You're looking for section 3.3.2.3 for -> and 3.3.3.2 for *.

      The latter refers to footnote 34 which indicates that dereferencing the null pointer type is invalid. However, the former makes no statement about requiring that the left operand of -> be a valid pointer, but I suppose you could read into the existing statement "The value is that
      of the named member of the object to which the first expression points, and is an lvalue." the inference that once -> is used on a pointer, that pointer must have pointed to a valid object.

      It's far from explicit though, and I think that'd be the backwards inference to make at that point, myself.

      --
      Paul "TBBle" Hampson
      Paul.Hampson@Pobox.Com
    41. Re:Serious bug in gcc? by Ritchie70 · · Score: 1

      I do understand things, actually, and if goddamn Slashdot would let you edit a freaking post I probably would have pulled it back, not because I thought it was inherently wrong but because it wasn't especially relevant.

      I honestly thought that NULL as part of the language standard was strictly C++, not C. When I learned C and C++ I'm pretty sure that was true.

      Keep in mind, there is a DIFFERENCE between "standard usage" or "in the standard Unix include files" and "the C language." So showing me some old source code for "cat" or something out of /usr/include in the AT&T code base isn't that interesting to me.

      Not knowing the "older than dirt" C89 standard is probably due to having learned C in 1988.

      Personally, I almost never use NULL, because the crufty code bases I deal with have everything defined multiple times - even stupid things like TRUE, FALSE, NULL, ERROR, etc. So there's compile time warnings everywhere due to redefinition, the values vary based on #include order, and it just isn't worth the pain to make sure that some numb skull didn't define NULL as (-1) ten years ago in some obscure application header when you can just use zero.

      PS. Fuck you. At worst, I screwed up - an honest mistake. You were intentionally rude. There are humans behind these letters on the screen, and you need to learn that.

      --
      The preferred solution is to not have a problem.
    42. Re:Serious bug in gcc? by metaforest · · Score: 1

      a = foo->bar

      if(foo) something()

      this code is ill formed! You are initializing a variable from an unverified pointer. The correct way to do this is:

      int a = 0; // if you must to keep the compiler quiet.
      if(!foo) handle_bad_pointer();
      a = foo->bar;

      ------

      WTF would you be thinking that it's EVER acceptable to have your code assign bad values to a variable through an unverified pointer?

    43. Re:Serious bug in gcc? by Your.Master · · Score: 2, Informative

      That's not true. It's not your fault, you just assumed the GP was right, and he's not.

      In your example, you thought b->two was (dereference of (0 + offset)) but actually it's ((dereference of 0) + an offset).

      To get the former you need b to be an actual struct and use (*b.two). Or with it still being a pointer you could do some fancy pointer arithmetic, like *(((int *) b) + 1).

    44. Re:Serious bug in gcc? by Your.Master · · Score: 1

      No, tun is being checked for NULL, which is not necessarily a check for 0 and not 0. The C standard specifies that the boolean value of a pointer is true if and only if the pointer is not null. Tun is clearly a pointer value since it's dereferenced as a pointer in tun->sk.

    45. Re:Serious bug in gcc? by Your.Master · · Score: 1

      It is dereferenced.

      tun->sk is equivalent to (*tun).sk.

      Can you spot the point where tun is dereferenced now?

      If tun were not a pointer but were a structure, and the syntax were tun.sk, THEN it would not be a dereference. Or if you did something insane like ((struct WhateverTunIsButNotAsAPointer) tun).sk.

    46. Re:Serious bug in gcc? by jonadab · · Score: 1

      > it's not the compiler's job to compile for the maximum defensiveness of the
      > resulting machine code, otherwise we'd all be using bounds-checking compilers.

      Have you ever noticed that C code has about a hundred times as many security patches as code written in languages where the compiler (or interpreter, as the case may be) does basic bounds checking and so forth?

      The behavior of dereferencing a NULL pointer *should* be defined, by any well-constructed language standard. A reasonable definition would be "your code is terminated and an error message generated". If the C standard doesn't make it the compiler's job to check for such things, then the C standard is incomplete at best. I would even call it broken.

      --
      Cut that out, or I will ship you to Norilsk in a box.
    47. Re:Serious bug in gcc? by Anonymous Coward · · Score: 0

      you blathering idiot

      Did your virtual penis swell when you wrote that part? Did it feel good?

    48. Re:Serious bug in gcc? by cr_nucleus · · Score: 1

      Of course when you introduce a new type of warning, it will show up a lot in any kind of big project. Developpers didn't have feedback about this particular warning before so they didn't code according to it. Once they start being notified, they will (hopefully) produce code that won't cause this warning and therefore it won't be as common.

    49. Re:Serious bug in gcc? by Rockoon · · Score: 1

      The point is that that is not possible with macros.

      Macro has test for NULL, because it makes sense to do so. Code which uses said macro may, on a case by case basis, make NULL either a certainty or an impossibility. Further, some code may rely on that NULL test being there while other code does not.

      You can't wave your hand and resolve all these issues. Crippling macros doesnt seem like a good idea to me.

      --
      "His name was James Damore."
    50. Re:Serious bug in gcc? by QuoteMstr · · Score: 1

      PS. Fuck you. At worst, I screwed up - an honest mistake. You were intentionally rude. There are humans behind these letters on the screen, and you need to learn that.

      You're right. I shouldn't have let some momentary external frustration seep out onto a public forum. I am sorry.

    51. Re:Serious bug in gcc? by DavidTC · · Score: 1

      Testing for what is supposed to be impossible is indeed valid, and can indeed be optimized away, but the compiler really should say something about it.

      It should mention all dead code, in fact. Anytime it notices code that does nothing that it decides it doesn't need, it should tell the programmer, if only to keep them from maintaining unused code.

      The only exception is the specific case of 'if (0)' tests, which are often used to comment out code where comments wouldn't work, and presumable people know what they're doing there.

      --
      If corporations are people, aren't stockholders guilty of slavery?
    52. Re:Serious bug in gcc? by DavidTC · · Score: 1

      Even if there are a bunch of warnings in some code, that's why warnings are individually configurable. It doesn't even have to be the default.

      In fact, all dead and removed code should generate warnings of some sort.

      --
      If corporations are people, aren't stockholders guilty of slavery?
    53. Re:Serious bug in gcc? by DavidTC · · Score: 1

      Erm, if you think that b->c isn't accessing the memory of b, you need a C refresher course.

      Assigning b to something would be fine if b was NULL. Assigning b->c requires reading b to find out where c is pointing. It does not require reading c, and hence c can be NULL, but it requires reading b, which cannot be NULL.

      --
      If corporations are people, aren't stockholders guilty of slavery?
    54. Re:Serious bug in gcc? by x2A · · Score: 1

      "PS. Fuck you. At worst, I screwed up - an honest mistake. You were intentionally rude. There are humans behind these letters on the screen, and you need to learn that"

      Well said. Everyone makes mistakes (although in this case it seems to come down more to what "in the language" means; personally I think if something's just a constant in an include file that tends to be used then that's not "in the language", even if it is "in a standard", but obviously some would argue. I'm not claiming to know which is the case here)... but not everyone's intentially rude, so which one says more about a person huh?

      Some people just get really wound up over the most pointless things.

      --
      The revolution will not be televised... but it will have a page on Wikipedia
    55. Re:Serious bug in gcc? by Ritchie70 · · Score: 1

      I've been wrong a lot on this one . . . but this seems really quite a lot like a question of implementation by the compiler and perhaps the OS.

      There's no reason I can see to do a read of *((int*)b) to get b->two.

      I've honestly kind of lost track of the point here, but I think a read of address 0x0 was really the point, so perhaps we shouldn't muddy the waters with the word "dereference."

      --
      The preferred solution is to not have a problem.
    56. Re:Serious bug in gcc? by Ritchie70 · · Score: 1

      LMAO

      The reason the "fuck you" came out was my inlaws were just here for 7 hours. I thought they were going to be here maybe 3, 4 max.

      --
      The preferred solution is to not have a problem.
    57. Re:Serious bug in gcc? by RightSaidFred99 · · Score: 1

      You don't know what you're talking about.

      Do you think C has some special logic for (!x) to check (x != null)? No. (!x) checks if X is 0 or nonzero. Period.

      Tun is being checked for zero or nonzero.

  10. Wait, what? by TheRaven64 · · Score: 4, Interesting
    This code looks right?

    struct sock *sk = tun->sk; // initialize sk with tun->sk
    ...
    if (!tun)
    return POLLERR; // if tun is NULL return error

    So, he's dereferencing tun, and then checking if tun was NULL? Looks like the compiler is performing an incorrect optimisation if it's removing the test, but it's still horribly bad style. This ought to be crashing at the sk = tun->sk line, because the structure is smaller than a page, and page 0 is mapped no-access (I assume Linux does this; it's been standard practice in most operating systems for a couple of decades to protect against NULL-pointer dereferencing). Technically, however, the C standard allows tun->sk to be a valid address, so removing the test is a semantically-invalid optimisation. In practice, it's safe for any structure smaller than a page, because the code should crash before reaching the test.

    So, we have bad code in Linux and bad code in GCC, combining to make this a true GNU/Linux vulnerability.

    --
    I am TheRaven on Soylent News
    1. Re:Wait, what? by Anonymous Coward · · Score: 2, Interesting

      The patch.

    2. Re:Wait, what? by TheSunborn · · Score: 4, Insightful

      I think the compiler is correct. If tun is null, then tun->sk is undefined and the compiler can do what even optimization it want.

      So when the compiler see tun->sk it can assume that tun is not null, and do the optimization, because IF tun is null, then the program is invoked undefined behavier, which the compiler don't have to preserve/handle. (How do you keep the semantic of an undefined program??)

    3. Re:Wait, what? by pdh11 · · Score: 5, Interesting

      Technically, however, the C standard allows tun->sk to be a valid address, so removing the test is a semantically-invalid optimisation.

      No. Technically, if tun is null, dereferencing it in the expression tun->sk invokes undefined behaviour -- not implementation-defined behaviour. It is perfectly valid to remove the test, because no strictly conforming code could tell the difference -- the game is already over once you've dereferenced a null pointer. This is a kernel bug (and not even, as Brad Spengler appears to be claiming, a new class of kernel bug); it's not a GCC bug.

      But as other posters have said, it would indeed be a good security feature for GCC to warn when it does this.

      Peter

    4. Re:Wait, what? by Anonymous Coward · · Score: 1, Insightful

      No, dereferencing a NULL pointer results in undefined behaviour. The GCC compiler is generating code which follows the C standard in this case.

      if (tun == null) then the behaviour becomes undefined as soon as the first line is passed.
      if (tun != null) then the check is not needed.
      Since "assuming tun is a non-NULL pointer" falls under the remit of "undefined" the compiler is acting reasonably in doing that.

      "Undefined behaviour" includes anything that the program can possibly do, such as setting your printer on fire and emailing death threats to your grandmother. (Although it would be a malicious compiler which generates code that did that deliberately, it would still follow the standard!)

      Therefore the compiler is allowed to assume that the C program guarantees that tun is not NULL at that point. Expecting any specific behaviour, such as the program halting, is outside the C standard. The compiler could optimize out the read to sk if sk is never used, for example, and that would be an entirely reasonable optimization.

    5. Re:Wait, what? by TheRaven64 · · Score: 3, Informative

      No. Technically, if tun is null, dereferencing it in the expression tun->sk invokes undefined behaviour -- not implementation-defined behaviour

      I've seen a lot of people claiming that, however (as someone who hacks on a C compiler) there are a few things I take issue with in your assertion.

      First, NULL is a preprocessor construct, not a language construct; by the time it gets to the compiler the preprocessor has replaced it with a magic constant[1]. The standard requires that it be defined as some value that may not be dereferenced, which is typically 0 (but doesn't have to be, and isn't on some mainframes). Dereferencing NULL is invalid, however that is not what is happening here.

      The value &(tun->sk) is the address of tun, plus a fixed offset. The expression &(((struct foo*)0)->bar) is valid C and will give the value of the offset of the sk field in the foo struct. A typical definition of NULL is (void*)0, and &(((struct foo*)(void*)0)->bar) will also give the value of the offset of the bar field.

      In this case, it is tun->sk, not &(tun->sk) which is being loaded, however the pointer arithmetic which generates the address happens first. If tun is NULL then this is NULL + {the offset of sk}. While dereferencing NULL is explicitly not permitted, pointer arithmetic on NULL is permitted, and dereferencing any non-NULL memory address is permitted.

      This is obvious from an implementation perspective. If pointer arithmetic on the NULL address were not permitted then every single pointer arithmetic expression would require a check at every intermediate stage to make sure that it did not pass through NULL. For example (a - a + a + 1) would be an invalid pointer arithmetic expression on platforms where NULL is address 0 if address computations were not permitted on NULL.

      [1] GCC and C++1x both declare a new language keyword for an invalid pointer, but this is not part of standard C.

      --
      I am TheRaven on Soylent News
    6. Re:Wait, what? by MadShark · · Score: 1

      Wouldn't lint catch typically catch this sort of problem(possible use of a NULL pointer warning)?

    7. Re:Wait, what? by TheSunborn · · Score: 1

      But it's (tun->sk) not &(tun->sk). That is: The code is looking at the value of the member sk in the struct pointed to by tun. Looking at this value is undefined if tun is null.
      It does not take the address of tun or tun->sk.

    8. Re:Wait, what? by pdh11 · · Score: 1

      While dereferencing NULL is explicitly not permitted, pointer arithmetic on NULL is permitted, and dereferencing any non-NULL memory address is permitted.

      Not any non-null memory address -- only one that points into an object. As there is no object whose address is the null pointer, the dereference is still undefined. And the compiler knows that.

      Another way of looking at it is that tun->sk is equivalent to (*tun).sk, which is even more clearly undefined in C.

      Peter

    9. Re:Wait, what? by Anonymous Coward · · Score: 2, Informative

      You are completely wrong and you should learn some C before posting crap like this.

      The NULL pointer has the value 0 and no other value. Period. Internally, it can be represented by other bit-patterns than all-0. But the C standard demands that
          void *x = 0;
      generates the NULL pointer.

      The last paragraph is also completely wrong because you fail to realize that the substraction of two pointers gives an integer and not another pointer.

      So: please, please don't post again until you've learnt the absolute basics of the C language to prevent further embarrassment!

    10. Re:Wait, what? by johnw · · Score: 4, Informative

      First, NULL is a preprocessor construct, not a language construct; by the time it gets to the compiler the preprocessor has replaced it with a magic constant[1].

      Which must be either "0" or "(void *) 0".

      The standard requires that it be defined as some value that may not be dereferenced, which is typically 0 (but doesn't have to be

      Not true - the standard requires NULL to be defined as one of the two values given above.

      and isn't on some mainframes

      There are indeed some platforms where a null pointer is not an all-bits-zero value, but this is achieved by compiler magic behind the scenes. It is still created by assigning the constant value 0 to a pointer, and can be checked for by comparing a pointer with a constant 0.

    11. Re:Wait, what? by snowgirl · · Score: 1

      I think the compiler is correct. If tun is null, then tun->sk is undefined and the compiler can do what even optimization it want.

      So when the compiler see tun->sk it can assume that tun is not null, and do the optimization, because IF tun is null, then the program is invoked undefined behavier, which the compiler don't have to preserve/handle. (How do you keep the semantic of an undefined program??)

      My favorite expression is that a proper implementation of undefined behavior may be to have monkeys fly out of the user's butt.

      I agree, it's not really an error in GCC that someone implemented something wrong. A nice flag complaining that something is dereferenced before it's checked would be pretty nice...

      Looking at the code, it's a pretty common behavior of programmers. "I'm setting up my variables, so I may as well initialize them with valid data." The problem is that you don't know if it's valid data if it's not a constant!

      --
      WARNING! This girl exceeds the MAXIMUM SAFE standards established by the FDA for BRATTINESS
    12. Re:Wait, what? by Anonymous Coward · · Score: 0

      The fact that NULL does not have to be 0 is a good point. That means that if(!tun) is bad in terms of portability.

    13. Re:Wait, what? by russotto · · Score: 1

      If tun->sk is an array, then tun->sk is equivalent to &(tun->sk). That turns out not to be the case, though.

      This optimization seems to be only useful for evil, though. How often does a programmer put in a test for null on something he's already dereferenced when it isn't an error? Maybe there's some common case where this happens, but I can't think of one off the top of my head. Redundant explicit tests for null are another matter, but that would be a different optimization.

    14. Re:Wait, what? by vslashg · · Score: 3, Informative

      &(((struct foo*)(void*)0)->bar) will also give the value of the offset of the bar field.

      You're speaking with a voice of authority, which is dangerous because of how incorrect in general your post is.

      Others have already pointed out that you are wrong about NULL. Here's precisely what the spec says about the argument to &:

      The operand of the unary & operator shall be either a function designator, the result of a
      [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is
      not declared with the register storage-class specifier.

      (((struct foo*)(void*)0)->bar) in particular is none of those things, and your expression is not legal C.

      Some apparent dereferences of null pointers are allowed. For instance:

      void *a = 0;
      void *b = &(*a);

      The above is legal not because dereferencing a null pointer is legal, but rather because of an explicit exception to the rule carved out in section 6.5.3.2 of the spec, which says that in this case, the & and * cancel, and "the result is as if both were omitted".

      Your expression is neither safe nor portable. If you do need to check the offset of a field in a structure, use the standard library offsetof() macro -- that's what it's for.

    15. Re:Wait, what? by johnw · · Score: 1

      The fact that NULL does not have to be 0 is a good point.

      No, it isn't. NULL *does* have to be 0.

      That means that if(!tun) is bad in terms of portability.

      If your premise were true then your conclusion would be. Since your premise is false your conclusion is unsound.

      In fact "if (!tun)" is fine in terms of portability (though arguably weak in terms of style).

    16. Re:Wait, what? by gnasher719 · · Score: 2, Informative

      The value &(tun->sk) is the address of tun, plus a fixed offset. The expression &(((struct foo*)0)->bar) is valid C and will give the value of the offset of the sk field in the foo struct. A typical definition of NULL is (void*)0, and &(((struct foo*)(void*)0)->bar) will also give the value of the offset of the bar field.

      Wrong. If tun is a null pointer, then the only valid operations are the following:

      1. Assign tun to a pointer variable of a matching type or of type void*, which will set that variable to a null pointer.
      2. Cast tun to another pointer type, which will produce a null pointer.
      3. Cast tun to an integral type, which will produce the value 0 (and this is true whatever bit pattern the compiler uses for null pointers)
      4. Comparing tun to a pointer of a matching type or type void* using the == or != operators.

      Dereferencing a pointer, even if it is just done to calculate an address, is undefined behaviour.

    17. Re:Wait, what? by Athanasius · · Score: 3, Interesting

      This ought to be crashing at the sk = tun->sk line, because the structure is smaller than a page, and page 0 is mapped no-access (I assume Linux does this; it's been standard practice in most operating systems for a couple of decades to protect against NULL-pointer dereferencing).

      If you actually read the exploit code (see: http://grsecurity.net/~spender/cheddar_bay.tgz) the thing that really enables this exploit is one of two ways to map page zero. One of these seems to be a flaw with SELinux (either with the default settings and/or how the default config commonly ships) or using personality(2) to select a personality that explicitly allows this.

      From the exploit for the personality case:

      int main(void)
      {
              int ret;
              struct stat fstat;
       
              ret = personality(PER_SVR4);
       
              if (ret == -1) {
                      fprintf(stderr, "Unable to set personality!\n");
                      return 0;
              }

      Note you do need some setuid root program even with this (from my reading of the exploit code).

      In the SELinux case "it just works" without needing the setuid program it seems.

    18. Re:Wait, what? by QuoteMstr · · Score: 1

      In fact "if (!tun)" is ... weak in terms of style

      What makes you say that? if(x) and if(!x) are perfectly good idiomatic C constructs, and their meaning is apparent at first glance.

    19. Re:Wait, what? by TheSunborn · · Score: 1

      If gcc had a specific case to find
      use of pointer, and then later test of same pointer for 0
      That would be evil and useless(And should give a warning).

      But what most likely happens is that gcc have one optimization pass, that analyse pointer values. And this detect(And remember) that tun does point to a valid object in the entire block. (Or that the code is invalid, but the compiler always assume that the code is valid).

      Then later, the compiler run an other optimization pass, to remove code with no effect. It then look at the if(tun==null) test, and see that a previous pass found out that tun would always point to a valid object. Thus the test is redundent and removed.

    20. Re:Wait, what? by Kickasso · · Score: 1

      Please, for the love of Bob, stop hacking C compilers. You are doing it wrong. You are supposed to read and understand the standard first. And you need to make a habit of answering any question about C code validity by quoting the chapter and verse of the standard, not by some vague reasoning.Go read the standard and find where it talks about OFFSETOF and null pointer dereference. I no longer have a copy on hand, and there's no online free copies, so I can't do it for you. But I assure you that &(((struct foo*)0)->bar) is UB when used in user code. An implementation may implement OFFSETOF in terms of &(((struct foo*)0)->bar) (and most of them do), but the programmer is not supposed to do that himself. He can only call OFFSETOF.

    21. Re:Wait, what? by jelle · · Score: 1

      No it's assigning the address of the sk member in the struct to the sk pointer local variable...

      --
      --- Hindsight is 20/20, but walking backwards is not the answer.
    22. Re:Wait, what? by ext42fs · · Score: 2, Insightful

      I think the compiler is correct. If tun is null, then tun->sk is undefined and the compiler can do what even optimization it want.

      So when the compiler see tun->sk it can assume that tun is not null, and do the optimization, because IF tun is null, then the program is invoked undefined behavier, which the compiler don't have to preserve/handle. (How do you keep the semantic of an undefined program??)

      The compiler is a complete asshole for deliberately optimizing a too late NULL check away instead of screaming "possibly dereferencing NULL" or something.

    23. Re:Wait, what? by Anonymous Coward · · Score: 0

      I think the compiler should be able to see that if tun might not be initialised then tun + offset also might not be initialised and should therefore throw a warning. Or ideally an error, since you shouldn't be able to use things that aren't initialised, but I don't know if you can do that without violating the standard. Then again, if you can't, that may indicate that the standard is bad and to be disregarded in this respect.

    24. Re:Wait, what? by Anonymous Coward · · Score: 0

      Did I miss the day that they removed the restriction from the C standards that pointer arithmetic is ill-defined on the NULL pointer?

      With all your assumptions, tun - &(tun->sk) may give us the offset (lets call it x) of sk for any valid tun pointer, but NULL - &(NULL->sk) is not defined as x. Furthermore, NULL->sk is not the value of something x distance away from NULL, it is ill-defined. It is ill-defined because this implicit "pointer arithmetic" is a dereference of NULL in the standard.

    25. Re:Wait, what? by johnw · · Score: 1

      In fact "if (!tun)" is ... weak in terms of style

      What makes you say that? if(x) and if(!x) are perfectly good idiomatic C constructs, and their meaning is apparent at first glance.

      Interesting how you've edited the text which I wrote in order to change its meaning.

      I won't bother to address your invented version of what I said; I'll stick instead to what I actually said.

      The problem with "if (!tun)" in terms of style is that it conceals what you're testing; specifically that tun is a pointer. I know many people do write code this way, and I would argue that it's a hang over from the days when it actually made a difference to the generated object code. Before optimising C compilers you actually got more efficient code if you wrote "if (!tun)" instead of "if (tun == NULL)". These days however are long past and informed opinion likes to make the meaning of code as clear as possible. If you write:

      if (!flag) /* For a flag ^/
      if (count == 0) /* For a counter */
      if (ptr == NULL) /* For a pointer */

      then you just make it that bit clearer what you're writing. Yes, using "if (!tun)" to test a pointer is entirely correct C, and what's more the practice is extremely widespread, but it fails the test of making the code as clear and self-documenting as possible. It is possible to do better, so I would always try and do it that bit better.

    26. Re:Wait, what? by mal0rd · · Score: 0, Troll
      Right, because:

      if (!flag) // looks like I'm testing a pointer??
      if (!count) // looks like I'm testing a flag??
      if (!ptr) // looks like I'm testing a counter??

      Not only should the name give a clue, but the type of the variable should be available within the past 50 lines or so. I have a bigger problem with the readability of complex conditionals and the !ptr syntax helps. Actually I'm interested if you can give an example of good code where ptr == NULL is more clear than !ptr.

    27. Re:Wait, what? by MSG · · Score: 3, Informative

      Which must be either "0" or "(void *) 0". ...
      There are indeed some platforms where a null pointer is not an all-bits-zero value, but this is achieved by compiler magic behind the scenes. It is still created by assigning the constant value 0 to a pointer, and can be checked for by comparing a pointer with a constant 0.

      What you've said is technically true, but doesn't contradict or clarify the post to which you replied in any way, so I'm not sure what your point is.

      As you point out, a NULL pointer is a pointer which is represented by "(void *) 0" in the C language. However, where you may be confused is that "(void *) 0 != (int) 0". At least, not always. The compiler is responsible for determining if any "0" is used in a pointer context and casting it to the appropriate value, which may not be the same as numeric "0". So, while it's always possible to check for a NULL pointer by comparing a pointer to 0 in code, the machine may use a different value for NULL pointers. When you check "if(p)", the binary code that is produced will be comparing the value of "p" to the NULL address which is appropriate for the machine on which it is running.

      The C FAQ has more information.

    28. Re:Wait, what? by sjames · · Score: 2, Insightful

      Arguably the compiler is wrong because it's (obviously) not actually impossible for address 0 to refer to valid memory however against convention and best practices that may be. The very existence of this problem proves that the compiler can NOT assume that tun is not null.

    29. Re:Wait, what? by RightSaidFred99 · · Score: 1

      No it's not. About all a C compiler can typically do is check if a variable is _never_ assigned and maybe warn about possible null pointer being used.

      For being a bunch of Linux nerds, you all have a poor grasp of C/C++. That coder made a few mistakes. First, he used an implicit cast of a pointer to an int/bool. Second, he did the check after the pointer was dereferenced.

      C is a dangerous language, and you can't blame it on the compiler. In a modern language like Java/C# this never would have even compiled. But of course you can't write a mainstream UNIX kernel in C# or Java.

    30. Re:Wait, what? by RightSaidFred99 · · Score: 1

      Exactly. Finally someone on here who knows what he's talking about. Two issues - one was dereferencing a null and then trying to pretend compiler shouldn't have removed a post-facto test for it in heavy optimization. Second was having the gall to claim an IMPLICIT CAST of a pointer to a (what, int or bool?) should still have triggered some magic "but I know they really mean to use this as a pointer!" logic in the magic C compiler they apparently want to use.

    31. Re:Wait, what? by Anonymous Coward · · Score: 5, Informative

      In this case, it is tun->sk, not &(tun->sk) which is being loaded, however the pointer arithmetic which generates the address happens first. If tun is NULL then this is NULL + {the offset of sk}. While dereferencing NULL is explicitly not permitted, pointer arithmetic on NULL is permitted, and dereferencing any non-NULL memory address is permitted.

      Raven, I've seen you make the same comment a few times in this story. Please stop pushing this nonsense.

      The language standard calls * and -> operations "dereferencing". The way it works is that tun->sk dereferences the whole struct, then hands you the sk field from it.

      When you implement this in your compiler you do an address computation first then load only the field because you don't want to load the whole struct when you don't need to, but that's an implementation detail. The compiler is required to act as if the pointer tun were being dereferenced.

      It would be a major missed optimization bug if the compiler didn't eliminate the later if (!tun) operation. This is a case where the input code is simply wrong.

    32. Re:Wait, what? by Anonymous Coward · · Score: 0

      That only applies to C++, not to C.

    33. Re:Wait, what? by TheRaven64 · · Score: 1

      The language standard calls * and -> operations "dereferencing". The way it works is that tun->sk dereferences the whole struct, then hands you the sk field from it.

      Yes, you're correct. Having checked the standard, my understanding was incorrect. Ah well, there's a reason why I try to avoid working on front-end code...

      --
      I am TheRaven on Soylent News
    34. Re:Wait, what? by Anonymous Coward · · Score: 1, Insightful

      In this case, it is tun->sk, not &(tun->sk) which is being loaded, however the pointer arithmetic which generates the address happens first.

      Well, there is no provision for this. The C standard says (6.5.2.3/4) that the value of tun->sk is that of the sk member of the object to which tun points - but since tun does not point to any object (it is a NULL pointer, remember?), then sk is a member of no object.

      Whatever "pointer arithmetic" is going on behind the scenes, it is the implementation issue and outside of the C standard. Actually, the C standard does not even mention the this term anywhere near this paragraph. Your reasoning is correct from the compiler hacker point of view, but is outside of the spec's scope.

    35. Re:Wait, what? by russotto · · Score: 1

      But gcc does indeed have such a specific test.

      http://gcc.gnu.org/news/null.html

    36. Re:Wait, what? by Anonymous Coward · · Score: 0

      bla bla bla

    37. Re:Wait, what? by Barsamin · · Score: 1

      You are correct in saying that it is tun + offset which is dereferenced (not tun itself).

      (BTW tun is obviously a pointer in the code given, no need to take its address.)

      That means that the compiler knows, if it reaches the if, that tun+offset is not NULL, but not necessarily that tun is not NULL.

      That would be true in general. But what everyone here seems to have missed, is that offset is known at compile time.

      If offset is NULL, then either tun is NULL and we enter the realm of undefined behavior and the compiler is permitted to remove the check, or tune is not NULL in which case the test is dead code.

      If however offset is non NULL, then tun must be non NULL if the test is reached.

      To summarize, if sk is the first member of tun (offset zero), then the compiler has all rights to remove the test. If not, this is a compiler bug.

    38. Re:Wait, what? by Barsamin · · Score: 1

      I'd like to make the last paragraph more precise,

      If sk is not the first member of tun, the compiler can remove the if (since the condition is always true), but it must preserve the body of the if. If it doesn't keep the body, it is a bug.

      On the other hand, if sk is the first member of tun, the compiler can remove the if and its body.

    39. Re:Wait, what? by Anonymous Coward · · Score: 0

      It's funny, because this makes me immediately jump to the idea that relying on memset() of 0 to set pointers to NULL is not strictly C.

      And, the c-faq that you link to, if you click a few links deep and get to the writeup on calloc(), points this out.

      But... Personally, the convenience of being able to memset() your structs rather than initialzing them all by name is just too good to give up. The odds of my code running on architectures where this matter is... (pardon the bad pun) close to nil. And for these folks working on the Linux kernel this is especially true -- if you're writing a kernel it's a pretty safe assumption that you can set a page that will trap at address 0. (And if 0 has some special meaning in your architecture maybe you can handle that in the page fault handler, at some performance cost...)

    40. Re:Wait, what? by Barsamin · · Score: 1

      Why the fuck doesn't slashdot has an edit option.
      Ignore the second post, it is complete bullshit.

      In the first post, replace the second-to-last paragraph by:
      If however offset is non NULL, then tun might or might not be NULL, and the test might be reached. It therefore must be preserved.

      Then add at the end of the post, by test I mean both the if and its body.

    41. Re:Wait, what? by metaforest · · Score: 1

      As other's keep pointing out in kernel space, 0x000000000.. is an invalid address.

      Why is the MMU failing to throw an exception when this invalid address is accessed?

    42. Re:Wait, what? by metaforest · · Score: 1

      sorry for the self reply...

      I meant page zero not the literal address zero. Obviously dereferencing to reach a member of a struct pointer is not going to result in a zero address unless it's the first member.

    43. Re:Wait, what? by gnasher719 · · Score: 1

      Not only should the name give a clue, but the type of the variable should be available within the past 50 lines or so. I have a bigger problem with the readability of complex conditionals and the !ptr syntax helps. Actually I'm interested if you can give an example of good code where ptr == NULL is more clear than !ptr.

      I once had to fixed a bug that was caused by a very experienced programmer changing "if (ptr != NULL)" to "if (! ptr)" because the latter seemed more clear to him, and against all company rules he checked in that change without code review because he was so experienced that his code changes didn't need to be reviewed.

      If you read this and don't get it, then (1) read my description of the code change again very, very carefully and (2) it proves the point that you should compare pointers to NULL explicitly.

    44. Re:Wait, what? by Anonymous Coward · · Score: 0

      Except the compiler would be wrong, in the case of zero mapped pages...

    45. Re:Wait, what? by Your.Master · · Score: 1

      It doesn't prove anything of the sort. It proves that your rules are there for a reason, and it proves that it's not entirely trivial to translate between the two styles, so maybe you should pick one or the other and stick with it.

      I have always preferred the terser style in this case. Just fits my mental model better than the == NULL check, which changes from obvious semantics (to me) to a mathematical statement. Both are valid, though.

    46. Re:Wait, what? by Kickasso · · Score: 1

      Wow, thanks. It used to sell for about 140,000 of today's dollars in my day. Good to see it available for free.

    47. Re:Wait, what? by jgrahn · · Score: 1

      For being a bunch of Linux nerds, you all have a poor grasp of C/C++. That coder made a few mistakes. First, he used an implicit cast of a pointer to an int/bool. [---]

      You mean if(!p) ... ? That's the normal style for many of us, and surely common in the Linux kernel. It's also perfectly safe.

    48. Re:Wait, what? by Anonymous Coward · · Score: 0

      Ok, but how is offsetof() macro defined? Using something very similar to &(((struct foo*)(void*)0)->bar)

    49. Re:Wait, what? by sjames · · Score: 1

      Up until recently, the kernel has made sure the hardware would generate a fault for any access into page zero even though it's not actually obligated to do so.

      A recent change allowed a page to be mapped at 0x00000000. The hardware has never considered address 0 to be in any way special.

      Even without that, the compiler is wrong to make the assumption since given a large enough struct the computed offset can be in valid memory even if page zero is never mapped.

    50. Re:Wait, what? by ratboy666 · · Score: 1

      You are confusing the two things --

      A "pointer" is not an "address". It is not legal to dereference a pointer containing 0. If "0" is a valid address, AND an object could be located there, it would still be necessary to refer to it by something other than "0".

      Now, it so happens that addresses are typically used as pointers, and "0" is simply not allowed as an object address. Which
      also works.

      But, it is true that a dereference from 0 gives undefined behaviour, so, to preserve semantics the compiler CAN make this assumption. This transformation is just as legal as:

      if (!p) do1();
      if (!p) do2();

      if do1() has no way of reaching p, transform to:

      if (!p) {do1(); do2();}

      Of course, if p is global, or otherwise reachable from do1(), this transformation isn't legal. But, in this case, tun can be assumed non-NULL, and the optimization made, because the OTHER interpretation allows it as well (undefined, eg. better than turning your computer into a goat or something).

      --
      Just another "Cubible(sic) Joe" 2 17 3061
    51. Re:Wait, what? by sjames · · Score: 1

      Actually, it's the C compiler that treats the pointers as addresses, I'm just going with it. It is the C language that states that a NULL pointer can't be dereferenced. It is the implementation that chooses 0 as the sentinel value for NULL.

      The C compiler in this case decided that since sk=tun->sk didn't cause a fault, tun must not be 0 (the NULL value). It was wrong. Very wrong. So wrong, it elided the only code that could save the situation from disaster.

      Optimizations that can potentially cause the compiler to make dumb assumptions and compile object code that does NOT cover every possible behavior of the source code should at least have a skull and crossbones in the manual. It should probably issue a warning unless you pass it an appropriate shut up flag. Certainly something like -O3 shouldn't enable it. That's just plain wrong.

      Consider the following:

      #include <sys/mman.h>

      struct a {
      int a[0x400];
      int b;
      };

      struct a *p1;

      int main(int argc, char *argv[]) {
      int c;

      p1 = mmap(0x1000, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1,0);
      p1=0; // NULL pointer
      c=p1->b; // dereference an offset of NULL
      if(!p1)
      return -1;
      return 0; // watch it not trap!
      }

      The code above or minor variations on that theme will NOT trap on most machines when compiled with gcc (and for that matter, a number of other C compilers). With gcc's unwarranted optimization, it also won't return -1.

      Oddly enough, since the assignment to c is never used it could elide the questionable assignment without affecting the program flow at all (provably). Instead, it breaks the meaning of the code by eliminating the if !p1 branch.

    52. Re:Wait, what? by vslashg · · Score: 1

      Ok, but how is offsetof() macro defined? Using something very similar to &(((struct foo*)(void*)0)->bar)

      Perhaps, but perhaps not. That expression might be safe for some implementations of C; if so, there's no reason for the library that ships with that implementation to use something along the above lines to implement the offsetof() macro. But that doesn't mean it's generally safe or portable code.

      Your fundamental premise is wrong, anyhow; not every implementation uses that trick to define offsetof(). In fact, gcc defines a special extension to C/C++, __builtin_offsetof(), to do the work. (gcc is allowed to introduce this new keyword because the standard reserves identifiers starting with a double underscore to the implementation.)

  11. CFLAGS by Epsillon · · Score: 3, Informative

    CFLAGS+= -fno-delete-null-pointer-checks

    Job done (should work with Gentoo, buggered if I know how to do this in other distros, DYOR), even with -O2/-O3. This is an optimisation/code conflict. The code itself is perfectly valid, so if your CFLAGS are -O -pipe you have nothing to worry about. GCC's info pages show what is enabled at various optimisation levels. -fdelete-null-pointer-checks is enabled at -O2. Of course, this only applies when you compile your own kernel. If vendors are supplying kernels compiled with -O2 without checking what it does to the code then it is obvious who is to blame.

    --
    Resistance is futile. Reactance buggers it up.
    1. Re:CFLAGS by Tony+Hoyle · · Score: 3, Informative

      No. That doesn't fix the problem. All it does is stop the broken optimisation (why the *hell* did someone at gcc think such a thing should be default anyway?)

      You need an -ferror-on-bogus-null-pointer-checks parameter so that the code can be fixed.

      It's an easy error to make. It's the compilers job to warn you.. in this case not only did it fail to throw a warning it also made the problem worse by 'optimising' it.

    2. Re:CFLAGS by quintus_horatius · · Score: 1

      All this means is that well-behaved packages (and users) won't accidentally exploit this bug, but it doesn't take away the fact that the kernel shouldn't allow the exploit.

    3. Re:CFLAGS by Anonymous Coward · · Score: 0

      Where do you place the boundary? Should compilers return an error on "x + 0" and "x * 1"? Such unnecessary constructs could indicate a mistake in the code, right?

      And pretty soon, you end up returning an error each time -O3 finds a way to optimize something. Surely the programmer made an error!

    4. Re:CFLAGS by Anonymous Coward · · Score: 0

      I'd just like to say this to all the wankers out there who hate Gentoo because they have this weird prejudiced view that they're all a bunch of over-optimizing speed freaks:

      CFLAGS+= -fno-delete-null-pointer-checks

      Yes, that would be a Gentoo user using Gentoo's source-based package system to REDUCE an optimization and make the system more secure.

      And that's why I like Gentoo, and why the haters can, in fact, go suck it.

    5. Re:CFLAGS by QuoteMstr · · Score: 2, Informative

      (why the *hell* did someone at gcc think such a thing should be default anyway?)

      Because it makes sense on every modern platform on earth except for strange embedded ones, that's why. This kernel bug is the result of incorrect kernel code, not a GCC bug.

    6. Re:CFLAGS by colsandurz45 · · Score: 1

      From the man page: -fdelete-null-pointer-checks Use global dataflow analysis to identify and eliminate useless checks for null pointers. The compiler assumes that dereferencing a null pointer would have halted the program. If a pointer is checked after it has already been dereferenced, it cannot be null. In some environments, this assumption is not true, and programs can safely dereference null pointers. Use -fno-delete-null-pointer-checks to disable this optimization for programs which depend on that behavior. Enabled at levels -O2, -O3, -Os. -fno-delete-null-pointer-checks to disable this optimization for programs which depend on that behavior. Enabled at levels -O2, -O3, -Os.

    7. Re:CFLAGS by systrace · · Score: 1

      Why do we still allow users to map stuff at page 0? This compiler optimization is clever and useful, but it assumes that 0 is an invalid address (as it should be and usually is). The exploit is taking advantage of the fact that mmap to address 0 is allowed. To answer my own question: mmap to 0 might be useful for emulation sometimes, for example, if emulating an IBM-PC BIOS in 16-bit mode where physical memory 0 is valid. Also, it'd break things to change it now. We could require a special system setting before allowing users to do that, but that would also break things. However, there's hope for the NULL deref bugs in the kernel. I've seen patches to fix such problems which seem to be identified by static analysis tools, so someone's running them. Very interesting exploit, though.

    8. Re:CFLAGS by systrace · · Score: 1
      Good point. The boundary would be any structure member offset from 0, like in the example. Otherwise, it could be the architectural page size (for x86 it'd be 4K).

      But it doesn't need a boundary if checked at a stage where the original construct is still accessible. if ptr->member is used before ptr is checked for NULL, throw the warning. Most coding is not going to make a structure that starts at zero. I can imagine doing it in 16-bit real mode code, maybe, but not sure it'd happen even then, and then the warning could be disabled.

      This would be useful, and in the kernel, most coders would be surprised by such an optimization and would rather fix the problem or, as has been the case with some truly unnecessary checks, remove them from the source.

      I agree that gcc should make it a warning. It may be that it identifies it too late (in optimization) and no longer has line number info?

      I also agree this is due to a kernel bug, but a warning could've eliminated that.

    9. Re:CFLAGS by Anonymous Coward · · Score: 0

      +1 to QuoteMstr.

      gcc is doing exactly what it says it will do with -Os, -O2, or -O3 in use. The man page even explicitly states if you want to turn this behaviour off, use -fno-delete-null-pointer-checks.

      This kind of mistake is incredible (to me). I see too many coders fall into the habit of combining declarations and assignments, especially when structs or pointers are in use. I can't speak for the rest of the world, but every time *I* do that, I stop and think about the implications. "Is this really what I want? What are the repercussions? What assumptions am I making here?"

      This kind of assumption being made by kernel coders is quite common. I'm absolutely certain this sort of thing exists elsewhere in the kernel, as well as the BSD kernels.

    10. Re:CFLAGS by Anonymous Coward · · Score: 0

      > in this case not only did it fail to throw a warning it also made the problem worse by 'optimising' it.

      The problem with making it a warning is that the redundant NULL checks often creep in through macro expansion, etc. That's where this optimization really shines. Since gcc knows that the value can't be NULL it can do a better job pruning dead code and simplifying exceptions.

      This is a kernel bug, not a gcc one.

      Tools that do deeper static analysis than gcc (like coverity) can and will flag these kinds of errors, btw. The kernel goes through regular coverity audits so this bug probably wouldn't have lasted long in the code base anyway.

  12. Actually, it's already been fixed by inode_buddha · · Score: 5, Informative

    Actually, it's already been fixed as of 2.6.31-rc3. Interestingly enough, the code by itself was fine until gcc tries to re-assign the pointer value upon compiling. Steven J. Vaughn-Nichols had a decent write-up about it in Computerworld.

    --
    C|N>K
    1. Re:Actually, it's already been fixed by icannotthinkofaname · · Score: 1

      Fixed already?
      *checks date on tfa*
      That's dated just over 24 hours before your post. Stuff gets fixed that quickly, huh? Nice.
      Why is it that a community that codes in its free time can fix a vulnerability in 24 hours, but a monopolistic corporation with nigh-unlimited resources for this kind of stuff takes weeks, months, or years to fix stuff in their OS?

      --
      Let q be a radix > 1. I am in ur base-q, killing 10 d00ds.
    2. Re:Actually, it's already been fixed by wampus · · Score: 0, Flamebait

      How much testing went into that 24 hour old fix? You can bet that Microsoft tests the living shit out of any changes they push out. They'd rather leave a known exploit in place to make sure they aren't introducing new unknown ones.

    3. Re:Actually, it's already been fixed by icannotthinkofaname · · Score: 1

      How much testing went into that 24 hour old fix?

      Excellent question. It took two hours to master use of the exploit. When knowing exactly how it works, how hard could it have been to isolate and debug the offending code?

      --
      Let q be a radix > 1. I am in ur base-q, killing 10 d00ds.
    4. Re:Actually, it's already been fixed by inode_buddha · · Score: 4, Insightful

      Submissions and patches to the kernel are independently tested and verified at least twice before being signed off and committed, usually by upstream developers (more experienced). This is the normal process. The only thing different in this case is that a vulnerability was exposed, hence it is in the news.

      --
      C|N>K
    5. Re:Actually, it's already been fixed by Anonymous Coward · · Score: 0

      The code was not fine, it was a null pointer dereference. GCC's optimization only made the exploit possible, but that's no reason to blame GCC. Garbage in -> Garbage out.

    6. Re:Actually, it's already been fixed by harlows_monkeys · · Score: 2, Interesting

      Actually, it's already been fixed as of 2.6.31-rc3. Interestingly enough, the code by itself was fine until gcc tries to re-assign the pointer value upon compiling

      The code by itself is not fine. The underlying bug is that the kernel is allowing memory at virtual address 0 to be valid. The compiler was designed for an environment where there can never be a valid object at 0, and has chosen the bit pattern 000...000 to be the null pointer. If you want to use C in an environment where 0 can be a valid address, then you need to use a C compiler that uses some bit pattern other then 000...000 for the null pointer.

      And yes, compilers can do that. According to the C standard, assigning the constant 0 to a pointer type does NOT mean assigning the numerical representation of 0. It means assigning a machine dependent value that compares unequal when compared to any pointer to valid memory.

      Furthermore, the Linux version of gcc is designed for an environment where accessing invalid memory causes a fault. Thus, the compiler is doing nothing wrong optimizing out that test for null, since in the environment for which it was designed, null pointers follow the C standard and do not point to a legitimate object, and accesses of illegitimate objects fault, and in such an environment that test can never be executed.

      The kernel developers either need to make sure the kernel environment conforms to gcc's assumptions about its environment, or they should use a special version of gcc designed for the kernel environment.

    7. Re:Actually, it's already been fixed by inode_buddha · · Score: 1

      I stand corrected, and educated. Thank you.

      --
      C|N>K
  13. what the...?! by Anonymous Coward · · Score: 0

    Why the crap doesn't "tun->sk" panic the kernel? They had it coming if the userland can tamper with the kernel's mapping of page 0.

    1. Re:what the...?! by TheRaven64 · · Score: 1

      My (uninformed) guess is that one of these friendly security modules does some NULL-pointer handling and turns something that should be a hard fail into a soft error. There was an OpenSSH vulnerability a couple of years ago like this, where error-recovery code turned something that should have been a crash into a keep-running-in-an-undefined-state.

      --
      I am TheRaven on Soylent News
    2. Re:what the...?! by snowgirl · · Score: 1

      My (uninformed) guess is that one of these friendly security modules does some NULL-pointer handling and turns something that should be a hard fail into a soft error. There was an OpenSSH vulnerability a couple of years ago like this, where error-recovery code turned something that should have been a crash into a keep-running-in-an-undefined-state.

      Just took a jaunt through the exploit code. Your guess is correct. SELinux seems to have an ability to defeat the mmap_min_addr protections that are supposed to block this sort of stuff.

      I wonder sometimes if it's possible to be sufficiently pedantic about security to actually prevent stuff like this from happening.

      I mean, really, the whole question of all of this is more "how do you force programmers to follow correct security in programming?"

      --
      WARNING! This girl exceeds the MAXIMUM SAFE standards established by the FDA for BRATTINESS
    3. Re:what the...?! by marcosdumay · · Score: 1

      I have a better question: "how do you force programmers to follow correct security in SELinux programming?"

      And a few more: Shouldn't that be their goal t start with? Why the hell does it permit to map NULL into something that will not make the kernel panic? To debug?

    4. Re:what the...?! by snowgirl · · Score: 1

      I have a better question: "how do you force programmers to follow correct security in SELinux programming?"

      And a few more: Shouldn't that be their goal t start with? Why the hell does it permit to map NULL into something that will not make the kernel panic? To debug?

      There are two programming errors here actually.

      1. Someone dereferenced an object before validating its inputs.
      2. Someone in SELinux fucked shit up really bad, by creating a hole in a security module.

      The first is addressed with my statement about how do you force a programmer to program in a secure manner.

      The second was unaddressed, with a better statement being, "how do you enforce a plugin against violating the security protocols that you have set up, even if it purports to create a stronger security model than yours?"

      The first is a matter of general programming, the second is a matter of handling security models, and design.

      The first covers most flaws, the second covers things like WMF files being able to put in arbitrary code for a print error callback.

      --
      WARNING! This girl exceeds the MAXIMUM SAFE standards established by the FDA for BRATTINESS
  14. Can enyone explain this? by bperkins · · Score: 1

    This will cause the kernel to try to read/write data from 0x00000000, which the attacker can map to userland

    This was somewhat surprising to me. Digging around a bit, it looks like it has something to do with an seLinux handler.

    Can anyone elaborate on this?

  15. I really don't see how this is a compiler problem? by gbutler69 · · Score: 4, Insightful

    To me, the "if (!tun)" check should/must be before the de-reference; otherwise, it is meaningless! However, the compiler should print a warning in this case, not just optimize it away.

    --
    Over-the-top Response Guy! Giving "Over-the-Top Responses" since 1970.
  16. Wish I had mod points.. nothing to see here! by plasmacutter · · Score: 1

    Actually, it's already been fixed as of 2.6.31-rc3. Interestingly enough, the code by itself was fine until gcc tries to re-assign the pointer value upon compiling. Steven J. Vaughn-Nichols had a decent write-up about it in Computerworld.

    And another mountain out of a molehill allowing microsoft astroturfers to troll a flame-war out of a non-event.

    --
    VLC FOR MAC IS DYING! IF YOU DEVELOP, PLEASE SAVE IT!!
  17. MOD PARENT UP - MOD GRAND PARENT DOWN! by Anonymous Coward · · Score: 0

    Parent is absolutely right and basically everything in grand parent's post is wrong.
    It's sad to see that moderators know nothing about the C language and mod grand parent up, but confirms what most people know anyway: slashdot is not the place for geeks anymore it's the place for lamers.

  18. Re:Linus, you Rookie !! by luca · · Score: 4, Informative

    Ok, I know I shouldn't be feeding the troll, but read the article: the kernel source itself is perfectly fine, is the compiler that optimizes the check away.

  19. no exact code snippet found in Linux by pikine · · Score: 3, Informative

    I tried to google code search for "tun->sk" and Linux doesn't contain that snippet of code. Since SANS claimed that drivers/net/tun.c is at fault, I looked at that source file and didn't find any instances where "if (!...) return ...;" is performed after NULL dereference.

    I think the only fascinating bit of the story is that the SElinux extension allows you to map a page at memory address 0 (the NULL page), making NULL dereferencing valid. I also found out about that a while ago, but I didn't know it has anything to do with SElinux. By the way, mapping the NULL page also works on Mac OS X.

    However, mapping NULL page is typically NOT exploitable. A correct program will simply reject access to NULL pointer, giving it a special semantic regardless whether the memory page itself is valid or not.

    --
    I once had a signature.
  20. "Assembler" by Merdalors · · Score: 2, Informative

    In my days (70's) of supporting a family by getting paid to squeeze code into a 32K "mainframe", everybody called it "Assembler" or "Assembler language".

    --
    Slashdot entertains. Windows pays the mortgage.
    1. Re:"Assembler" by Murple+the+Purple · · Score: 2, Informative

      I remember this as well. And here's evidence:

      http://www.amazon.com/Assembler-Language-Programming-Compatible-Computers/dp/0471886572/

    2. Re:"Assembler" by x2A · · Score: 1

      Yes well these days code's quite a bit bigger than 32K so we've shortened the term by one letter to help compensate :)

      --
      The revolution will not be televised... but it will have a page on Wikipedia
  21. Interesting by improfane · · Score: 3, Funny

    Guys, I'm trying to decide what to post:

    [ ] Downplay how serious flaw is
    [ ] Compare to Window's track record
    [x] Make a meta-reference to Slashdot psychology
    [ ] Post work-around that doesn't fix problem
    [ ] Say that flaw is a feature
    [ ] bash Windows
      [ ] Claim that not all Windows software is bad
    [ ] Claim that the more popular gets, Linux will be targeted more
    [ ] Pretend I understand the problem ...or we could RFA

    --
    Slashdot needs Geekcode | Can anyone recommend any good SCIFI? My tastes: Foundation, Startide Rising, CITY, Ringworld,
  22. code found in Linux 2.6.30 by pikine · · Score: 4, Informative

    Oh, found the code on lxr. It looks like Linux kernels up to 2.6.29.6 are NOT affected, and this is a vulnerability introduced in 2.6.30 due to a fairly significant rewrite of tun.c. Linux 2.6.30 was released in Jun 9, 2009, just a month ago. Funny the tun.c rewrite was not mentioned in the set of changes for 2.6.30.

    I think this example actually shows a forte of Linux as open source. New vulnerability is found very quickly after "new" code is released.

    --
    I once had a signature.
    1. Re:code found in Linux 2.6.30 by ToasterMonkey · · Score: 0

      I think this example actually shows a forte of Linux as open source. New vulnerability is found very quickly after "new" code is released.

      I thought the vulnerability was found first, then the cause.. If that's the case, how did open source help in finding this?

  23. the set of changes for 2.6.30 by pikine · · Score: 4, Informative

    For some reason I didn't link this correctly. The set of changes for 2.6.30 is found http://kernelnewbies.org/Linux_2_6_30.

    --
    I once had a signature.
  24. Re:Linus, you Rookie !! by dotgain · · Score: 1

    How very optimal indeed!

  25. Re:Linus, you Rookie !! by gnasher719 · · Score: 5, Informative

    Ok, I know I shouldn't be feeding the troll, but read the article: the kernel source itself is perfectly fine, is the compiler that optimizes the check away.

    Absolutely not. The code itself has a severe bug: If tun is a null pointer then it invokes undefined behaviour. Undefined behaviour means anything can happen. Anything can happen means a severe bug, especially in kernel code. The optimizing compiler just turned C source code that was buggy, but not obviously enough for the programmer, into assembler code that would have been obviously buggy to anyone. Most definitely not the fault of the compiler.

  26. Running a static checker on the Linux kernel? by Animats · · Score: 2, Interesting

    Isn't someone running a static checker on the Linux kernel? There are commercial tools which will find code that can dereference NULL. However, there aren't free tools that will do this.

    1. Re:Running a static checker on the Linux kernel? by Anonymous Coward · · Score: 0

      Hell, I'm just going by what I see here but shouldn't this have been found with a unit test? I realize part of this is the compiler, but if you know enough to put in a NULL check then you should know enough to research how to test this properly in an automated way.

      Blaming this on the compiler really makes the Linux devs look bad. Dereferencing a pointer and then checking it for NULL is just fucking wrong for any code like this. Admit it, fix it, and move on. Denying it and blaming gcc makes you look like you're either a moron or too proud to discuss technical issues when it means admitting a mistake.

  27. Who is right? by Anonymous Coward · · Score: 0

    one guy blames compiler, other blames code, then another blames compiler, another blamdes code ... repeat x 10....
    all moderated informative, WHOS RIGHT?

    1. Re:Who is right? by Your.Master · · Score: 1

      The code is primarily at fault, and secondarily a certain compiler flag (so still "the code" but not the C code).

  28. What's kept me from bothering with Linux. by dicobalt · · Score: 0, Offtopic

    Everytime I try to use Linux I always end up needing to compile the kernel because I want some special feature or software package that requires it. Software that doesn't ship with any distro as a prepackaged ... package. Anyways, I hate the kernel compile procedures, what a pain. I really wish there was a better tool than menuconfig/xconfig and the ensuing make and install commands.

    For some unexplained reason I always get an obscure weird error. I do know C/C++ but I am not a programmer (especially not a kernel programmer on Linux) so I really don't want to spend days figuring it out. I just want to use it. I am truly amazed it's been 13 years (the first time I compiled a Linux kernel successfully) and there is *STILL* no nice program to manage kernel compiles and translate common errors into plain english or even spanish(which I don't know lol).

    Then an exploit comes out or a necessary kernel upgrade happens and I have to go through it all again. Ugh. Comon guys, someone make a utility that makes compiling and installing a kernel impossible to screw up. Easy even when it's giving bizzare errors. Because the damn thing never does what it's supposed to do! Argh!

    For that matter this wonderful tool should be able to handle compiling any source for nearly any software. You shouldn't need a stinkin RPM or APT package which I can never seem to find the right flavor of even when they are available. Every distro needs to have the same easy to use tool that compiles directly from source and can deal with common errors itself.

    13 years, and I'm still waiting.

    1. Re:What's kept me from bothering with Linux. by iggymanz · · Score: 1

      Stop waiting, Linux isn't for you. compiling a kernel of any OS with new code added will be somewhat hard. almost all Linux users don't compile kernels, the ones that do don't mind the work.

    2. Re:What's kept me from bothering with Linux. by dicobalt · · Score: 1

      I suppose you are right, there is no place for me on Linux. I am more then a user but not a system/kernel programmer. There is no room for those middle ground people on Linux. Something I would think Linux developers/distros would be very concerned about. It's just another thing stopping Linux from more a widespread adoption. You have to be willing to submit to idiot prepackaged environments (like grandma does), or you have to make your environment all by yourself through years of personal experience in system level software design/programming. No middle ground, really? That's insane. But that's how it is I guess.

    3. Re:What's kept me from bothering with Linux. by armanox · · Score: 1

      And what software "requires" a kernel recompile? Most software that you compile will require kernel headers that match the running kernel, but, I haven't seen any software in the past 10 years that requires a kernel recompile.

      --
      I'm starting to think GNU is the problem with "GNU/Linux" these days.
    4. Re:What's kept me from bothering with Linux. by dbIII · · Score: 1

      I think that he must be bitching about the time more than ten years ago that he tried to compile a monolithic kernel for all his hardware and doesn't know that all distros will have what he needs already built as modules.

    5. Re:What's kept me from bothering with Linux. by True+Grit · · Score: 1

      Everytime I try to use Linux I always end up needing to compile the kernel

      Every time? Always? Wow, such strong words, pity you don't back them up with anything.

      a better tool than menuconfig/xconfig

      The tool isn't the problem, IMO, its the sometimes incomplete and/or confusing descriptions of the config options which tend to trip people up. Of course, this is why all the main distros compile the kernel for you. No one ever said doing it yourself was easy (or was even supposed to be). Hell, when is doing *anything* yourself "easier" than having someone do it for you?

      there is no place for me on Linux.

      Actually, I'm wondering just how hard you actually tried to make a place for yourself...

      I am more then a user but not a system/kernel programmer.

      "system/kernel programmers" aren't the only people who compile their own kernels.

      Something I would think Linux developers/distros would be very concerned about.

      Why do you think all the major distros provide their users with precompiled kernels?

      It's just another thing stopping Linux from more a widespread adoption.

      Being able to compile the kernel yourself has absolutely nothing to do with Linux's lack of popularity, and you've made no attempt to show that anyone *has* to compile it...

      idiot prepackaged environments

      You do realize this description basically applies also to Windows & Mac OS, not just to all of the most popular Linux distros in use, don't you? "idiot" just doesn't make any sense here.

      make your environment all by yourself

      "Linux from Scratch" is the *only* "distro" that actually requires that.

      through years of personal experience in system level software design/programming

      Hyperbole much?

      Many, many people compile the kernel on a routine basis without ever looking at the source code.

      But that's how it is I guess.

      That would only be true if your "it" was in any way remotely connected with reality...

      Of course it doesn't help that you started off with a vague reference to "problems that require you to compile the kernel yourself", without, unfortunately, any specifics at all. You'll need to actually give a real example of this kind of "problem" before anyone can take you seriously...

    6. Re:What's kept me from bothering with Linux. by Tweenk · · Score: 1

      Comon guys, someone make a utility that makes compiling and installing a kernel impossible to screw up.

      Already exists.
      make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers
      dpkg -i linux-*

      Not sure about RPM-based distros.

      --
      Those who would give up liberty to obtain working drivers, deserve neither liberty nor working drivers.
  29. No, it's a compiler bug. (test code) by qieurowfhbvdklsj · · Score: 0

    Here's a simple test program. Compare the output when compiled with "gcc -o test test.c" to the output with "gcc -O2 -o test test.c". I used gcc version 4.3.2 (Gentoo 4.3.2-r3 p1.6, pie-10.1.5)

    (Wow, the "preview" is ruining the formatting of this code.)

    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <sys/mman.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>

    int main () {

        int fd;

        char *string = " This text was read from a null pointer!\n";
        int length = strlen(string);

        char *pointer; /* Create a simple file... */
        fd = open("random_nonexistant_file", O_CREAT | O_RDWR | O_TRUNC, 0666);
        write(fd, string, length); /* mmap the file to address zero */
        pointer = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0)
    ; /* note: gcc optimizer doesn't know that the return value was null */ /* Let's dereference that pointer and write to it! */

        pointer[0] = 42; /* Then we'll display it, but not using printf
        since it refuses to print from null pointers. */

        write(1, pointer, length); /* Also print the pointer value, just to make sure it is null. */

        printf("Pointer address: %d\n", (int) pointer); /* Now let's find out if GCC thinks the pointer could possibly be null... */

        if (pointer == 0) {
            printf("The pointer is null!\n");
        } else {
            printf("The pointer is not null!\n");
        };

    };

    Either way, the pointer is displayed to be zero, but when you run the unoptomized version, it correctly states that the pointer is null, but the optimized version will tell you that it isn't null. When optimization changes the behavior of a functional program, it is clearly doing the wrong thing.

  30. Re:No, it's a compiler bug. (test code) by rtfa-troll · · Score: 1

    You can spin it any way you want but it is still not true. There are jokes about "undocumented features" but this isn't even that. It's a clearly documented feature if you look up the optimisation. It's not even incorrect according to the C standard. When you dereference the null pointer then you get "undefined behaviour" up to and including initiation of global nuclear war on computers with the appropriate peripherals (unfortunately I can't find the original Fortran quote I am abusing here). The fact that your compiler does different things during different compiles is perfectly correct and the least of your problems.

    This code is only reasonably legitimate because Linux user processes normally do guarantee that null pointer de-references cause aborts.

    --
    =~ s,(.*),<sarcasm>$1</sarcasm>,g if any_point_you_wish();
  31. Re:Linus, you Rookie !! by sjames · · Score: 1

    I don't know that I would go so far as to call it FINE, since it certainly violates best practices, but it's not technically wrong.

  32. Re:Linus, you Rookie !! by sjames · · Score: 2, Informative

    The code makes a potentially undefined assignment, but before doing anything significant with it, it checks for the undefined condition. It's not technically wrong but it is against best practices. Without the invalid optimization it wouldn't be a problem. In turn, the optimization is in the opposite condition. It is technically wrong, but where best practices are followed, it does no harm.

  33. Re:No, it's a compiler bug. (test code) by rtfa-troll · · Score: 1

    Reply to myself; sorry

    This code is only reasonably legitimate because Linux user processes normally do guarantee that null pointer de-references cause aborts.

    Bullshit; What you mean is:

    The reason this could be legitimate in the Linux Kernel is because they have a special environment where null pointer dereferences are guaranteed not to cause a crash. However, that means that they have to rely on the compiler behaving in a defined way which means that they are fundamentally responsible for checking all the optimisations etc. etc. which their code relies on.

    In a Linux user process, the compiler behaviour would be fine because Linux user processes normally do guarantee that null pointer de-references cause aborts. The kernel code would be wrong because

    Thinking about this, it seems more, it seems to be a needlessly hairy and careless thing to allow in kernel code. There's a perfectly legitimate way to do this in C (get the buffer, check it's not null, use it). That legitimate way could be optimised by the compiler to be just as fast as the code used. Why not just do it right in the first place. Then, when someone cuts and pastes into user code at some later point, there won't be an problems.

    --
    =~ s,(.*),<sarcasm>$1</sarcasm>,g if any_point_you_wish();
  34. Re:Linus, you Rookie !! by Anonymous Coward · · Score: 0

    And if I had to venture a guess, this mistake probably came about from one of the commercial contributors. Namely, the one that skyrocketed to the 4th spot in contributions last month (seeing as how well, Red Hat's been at this for a long time now, and while it's not impossible that they committed this flaw to the core, it's far more likely that Intel's newfound interest and throwing muscle @ the linux kernel is probably what caused this).

  35. Re:Linus, you Rookie !! by KibibyteBrain · · Score: 1

    But that is one issue with some of the FOSS mentalities out there. Source is only half of a software product. A quality build is the second half. If you don't spend as much effort on your build/test workflow as your dev workflow, then what is the point? There is no such thing as "correct source". The product you ship is either working or not, and software runs in binary form.

  36. Bullshit by omb · · Score: 1

    The compiler cannot know tun == 0, which is what the "if (!tun)" is testing (BTW as a pun), and the code is clearly crackpot.

    Any idiot, who tries to defend GCC.&#160;or "undefined" to justify optimisation removing this 0-test needs to spend the rest of their lives writing absolute machine code, in HEX, as they clearly do not understand high-level languages.

    If, and only if "tun = 0; if (!tun) ..." be optimised, since NULL is not guarented to be 0.

    If anyone wrote this code, as opposed to it getting patched in, they need their coding finger cut off, since it is not only dangerous, manifestly daft, stupid, BUT also a race unless LOCKED+INTERRUPTS off.

    Clearly this code did not get enough competent eyes.

    1. Re:Bullshit by gnasher719 · · Score: 2, Informative

      If, and only if "tun = 0; if (!tun) ..." be optimised, since NULL is not guarented to be 0.

      I left your comments about some C programmers out, because they just make you look like an idiot.

      A "null pointer constant" is by definition either an integer constant expression with a value of zero, or such an expression cast to (void *).
      NULL is guaranteed to be a macro that evaluates to a "null pointer constant", with parentheses around it if needed.
      In certain contexts (when assigned to a pointer lvalue, or when compared to a pointer expression), the compiler will replace a "null pointer constant" with a null pointer of the correct type.
      When used as the operand of &&, || or !, or used as the controlling expression in an if, while, do-while statement or ?: expression, a null pointer is converted to an int with value 0, any valid pointer that is not a null pointer is converted to an int with value 1.
      When a null pointer is cast to in integer type, the result is 0. When an integer with value 0 is cast to a pointer type, the result is a null pointer.

      The representation of a null pointer (that is what is stored in memory and what memcpy would copy) is not guaranteed to be all-bits zero, but the compiler guarantees that all of the above is still true.

      Dereferencing a null pointer invokes undefined behavior. Whether the instructions that a compiler generates to do this dereferencing cause a crash is irrelevant, the fact that a null pointer is dereferenced is enough. This also applies to pointer arithmetic, where the code will usually not crash, but nevertheless is undefined behaviour. And it is quite clear in the definition of the C language that a compiler is allowed to always assume that there is no undefined behavior. The dereferencing of tun invokes undefined behaviour when tun is a null pointer, therefore the compiler is allowed by the rules of the C language to _assume_ that tun is not a null pointer. Therefore it is absolutely legal for the compiler to remove the test.

  37. Stupid, stupid by omb · · Score: 1

    This is all a HUGE nonsense, I sincerely hope that none of you, who think this "undefined" ever write real used code, Goedel's theorem tells you that the compilers cannot know, except in a few tiny, well defined circumstances, what the value of a variable will be, at run time. That is why compiler optimization is HARD, eg

    As part of the thread has already pointed out, THIS&#160;IS&#160;REALLY&#160;BAD&#160;CODE, full of puns and races, it should never have got past the sub-system maintainer, Morton & Tovolds.

    The moral here is __think__, __write__what__you__mean__, and get sensitive code REVIEWED, by somebody competent.

  38. Re:Linus, you Rookie !! by bonch · · Score: 1, Informative

    Obviously, it is technically wrong since we're now reading a story about a null pointer exploit in the kernel...

  39. Good by omb · · Score: 1

    Thank you for expaining this both correctly an in detail, I simply did not have the patience or tolerance of rubbish!

    1. Re:Good by Anonymous Coward · · Score: 0

      Hahaha, how ironic. Matter of fact, Raven was wrong on *all* points. And gullible people like you believe him. Sigh.

  40. Very Dangerous Attitude by omb · · Score: 1

    One reason why C++ needs the Scott Myers books is because Barjne took your attitude,

    so the standard MUST specify, in detail, what is to happen but the name of the game is to write the standard so that behavior is intuitive and obvious,

    Complexity is the enemy of correctness.

    1. Re:Very Dangerous Attitude by Kickasso · · Score: 1

      The standard must be this and that, and also bake your rolls and serve your coffee, but for any number of reasons whe have the standard that we have. Respect it, or don't touch the compiler with your little dirty hands. What could be simpler?

  41. Yes it REALLY , it's a compiler bug. (test code) by omb · · Score: 1

    Absolute, CORRECT, CLEAR.

    I once had a PhD student who could not understand this, he was very cleaver, but always too agressive, and constantly broke a good optimizing BCPL compiler for the PDP10, since I didnt seem to be able to teach him about regression tests either, even though he did do a lot of good he was, correctly, downgraded to a D.Phil by the external since he couldnt explain himself in the viva.

    Code Review is not useless.

  42. Re:Linus, you Rookie !! by lilo_booter · · Score: 4, Informative

    Umm - no - the *code* does the undefined behaviour and *then* checks if the undefined behaviour could happen. But, heck, mistakes happen - it was identified and fixed. Not much of a story really.

  43. Maybe they should use C99 by harlows_monkeys · · Score: 1

    A comment on Reddit pointed out something interesting. He speculated that the reason the test was after the assignment is that the programmer was trying to follow the often recommended style of initializing your variables when you declare them. The kernel uses C89, which requires all declarations to be at the top of the function, before any code (other than initializers). Thus, he couldn't test for null before initializing.

    C99 removes the restriction that declarations have to be first in the body. If the kernel were using C99, the programmer could have done his argument sanity checks first, such as the check for the null pointer, and then declared and initialized the variable, AFTER the test.

    1. Re:Maybe they should use C99 by Anonymous Coward · · Score: 0

      That is the lamest excuse for this kind of bug I've heard in a long time. I suppose, then, that code such as

      int result = format_my_harddrive();

      if (i_didnt_really_mean_it)
              return;

      is OK, because I was forced to declare "result" at the top and initializing it there is "pretty" ?? Geez...

    2. Re:Maybe they should use C99 by True+Grit · · Score: 1

      Thus, he couldn't test for null before initializing.

      Of course he could. 'recommended style' != 'required rule'

      In fact, in the very next function that follows the function with the bug in tun.c, there is an uninitialized variable being declared, and then initialized later, *after* a sanity check. In hindsight, this should have been done here too.

      I'm guessing the author probably just made an honest mistake of looking at the code above:

      struct tun_struct *tun = __tun_get(tfile);

      and thinking that the __tun_get function, which initializes the tun pointer, wouldn't return a NULL. We now know it obviously can, so perhaps he simply forgot or misremembered that.

      If the kernel were using C99, the programmer could have done his argument sanity checks first

      Programmers still make mistakes when using C99 too. After all, this *is* pointer-heavy C we're talking about here. :)

  44. Re:Linus, you Rookie !! by Anonymous Coward · · Score: 2, Informative

    The code *IS* technically wrong: It dereferences a NULL pointer. The fact that the pointer is checked against NULL *after* dereferencing it does not help one bit. Once you invoke undefined behavior, the code could do ANYTHING you can imagine and it wouldn't be the compiler's fault.

  45. Dumb ... by omb · · Score: 1

    The very last thing you need is an OS, especially embeded, think mobile, or desktop, where one error, often in a daemon, or driver brings the whole thing crashing to a halt, and one that you can't debug. Think M$ Windows BSOD.

    The OS is there to manage those problems, and stop the buggy process, and only those. Not your last hours editing or last weeks work or your corporate web server. So this is, once again confused nonsense; in the kernel NULL ==== (void *)0, but the kernel TRAP handler treats KERNEL ILLEGAL 0 DEREFERNCES specially [(NB NULL ==== 0) is not true in all architectures], indeed all KERNEL errors are specially handeled or disabled. In effect, the kernel will trap, log, and terminate processes which " ill mem ref" unless they have a registered or default handler [think boot time probes for mem-mapped devices] but the hardware gives you enough context to determined what happened or is broken

  46. Re:Linus, you Rookie !! by Anonymous Coward · · Score: 1, Insightful

    You, sir, have no clue what you're talking about. This has nothing to do with best practices, the code is just wrong. That is, unless you consider "you won't dereference a NULL pointer" a "best practice". The rest of us consider it a fundamental law of the universe.

  47. I call shenanigans. by argent · · Score: 1

    A comment on Reddit pointed out something interesting. He speculated that the reason the test was after the assignment is that the programmer was trying to follow the often recommended style of initializing your variables when you declare them. The kernel uses C89, which requires all declarations to be at the top of the function, before any code (other than initializers). Thus, he couldn't test for null before initializing.

    You mean there was some orbital mind control laser preventing him from writing this?

    struct sock *sk = tun ? tun->sk : NULL; // initialize sk with tun->sk
    ...
    if (!tun)
        return POLLERR; // if tun is NULL return error

    Or this?

    struct sock *sk;
    ...
    if (!tun)
        return POLLERR; // if tun is NULL return error
     
    sk = tun->sk; // initialize sk with tun->sk

    This was a simple oversight.

    1. Re:I call shenanigans. by Your.Master · · Score: 1

      You didn't read the second sentence. He wants to initialize variable at declaration time.

      That could just as easily have been done by

      struct sock *sk = NULL;

      But anyway, style is one of the most important parts of the rubric, but choosing style over correctness is rarely a good idea.

    2. Re:I call shenanigans. by argent · · Score: 1

      You didn't read the second sentence. He wants to initialize variable at declaration time.

      Which my first alternate did.

  48. It's a compiler bug, pure and simple. by argent · · Score: 1

    The compiler assumed that if tun had been dereferenced, it couldn't be NULL. That's a false assumption, and there's probably dozens of other time-bombs sitting in code compiled with that compiler that just haven't been discovered yet.

    1. Re:It's a compiler bug, pure and simple. by True+Grit · · Score: 1

      The compiler assumed that if tun had been dereferenced, it couldn't be NULL.

      Well, technically, the compiler assumed that since it had been given the '-fdelete-null-pointer-checks' optimization option, that that was what you wanted it to do. :)

      That's a false assumption

      The author's of that compiler optimization *knew* that it was a false assumption "for some environments". Read that option's description. This wasn't a bug in the typical sense, e.g., an accident or unintended behavior. The issue appears to be a little more interesting:

      a) Should this option have been included by default in the -On options that it was (2/3/s)? Perhaps it should have been restricted to just -O3, where the "dangerous" optimizations supposedly live?

      b) How are compiler author's to decide what opts are used for a given -On? If an optimization that is useful for, say, 90%(*) of compiler users, should it be included and on by default, or are you/others suggesting an optimization should only default to on if its valid for *all* compiler users? Who should carry the burden of taking explicit actions to keep the compiler from doing something thats not useful, or simply invalid, in their environment, the 90%, or the 10%?

      c) Do the kernel devs have *some* responsibility here (aside from the mistake in the code itself)? Perhaps the kernel make should have been explicitly turning this option off, because in the kernel environment, this optimization is *not* useful? After all, if an app plays with a null pointer, just the app stops, but if the kernel does the same thing, the whole world might come crashing down. :) Those two environments obviously need to handle null pointers a bit differently...

      Note: I'm not arguing for/against the kernel devs or the compiler devs, I'm just asking.

      (*) I pulled the 90/10 ratio out of thin air, its just for discussion's sake. The compiler devs probably have a better idea of how broadly useful this particular option really is... or do they? :)

    2. Re:It's a compiler bug, pure and simple. by argent · · Score: 1

      Well, technically, the compiler assumed that since it had been given the '-fdelete-null-pointer-checks' optimization option, that that was what you wanted it to do. :)

      If that option changes the semantics of the language, it's not an optimization. If you explicitly check for a null pointer, then no compiler flags should remove that check. If the compiler is generating an extra null pointer check for safety, that's a different matter, but REMOVING that safety check shouldn't remove explicitly included code.

      If it does, that's a bug. Which I hope the compiler guys will decide, and fix it, instead of arguing that the programmer should have to know that -O3 or -fdelete-null-pointer-checks deletes code that other code that it's optimized out depends on for correctness.

      Perhaps it should have been restricted to just -O3, where the "dangerous" optimizations supposedly live?

      No, it should be in the -fthis-is-not-a-c-compiler -fyes-I-really-mean-it options -fyes-I-am-an-idiot-why-do-you-ask.

      If an optimization that is useful for, say, 90%(*) of compiler users, should it be included and on by default, or are you/others suggesting an optimization should only default to on if its valid for *all* compiler users?

      If an optimization changes the semantics of the language, it should be on for zero percent of the users, no matter what options they set. Or else it's not an optimization, it's a bug.

    3. Re:It's a compiler bug, pure and simple. by True+Grit · · Score: 1

      If that option changes the semantics of the language, it's not an optimization.

      The "semantics of the language" don't help us since, in this case, we were already in "Undefined Behavior" territory by the time of the ptr check.

      Which I hope the compiler guys will decide, and fix it

      Looks like the kernel guys have gone with one of the other options I mentioned, they are explicitly turning off that optimization option for a kernel build.

      http://it.slashdot.org/comments.pl?sid=1307017&cid=28747953

      Note the last two paras in that post, and in particular: "(I think the argument that the gcc optimization is generally a bug have been sufficiently debunked, it's busted tunneling code, no ifs ands or buts)"

      No, it should be in the -fthis-is-not-a-c-compiler -fyes-I-really-mean-it options -fyes-I-am-an-idiot-why-do-you-ask.

      This is an utterly silly response given the complex situation of this particular error:

      1) A language which allows for implementations to handle NULL differently. C doesn't have a strict clear specification for how to handle NULL derefs, or for that matter, even what NULL ultimately equates to, precisely *because* its used in so many different environments.

      2) Invalid code to begin with (a ptr check after the ptr had already been used)

      3) That bad code, even *with* the ptr check removed, would normally have PANICed the kernel, *except* when a linux security module was loaded that *allowed* valid memory to be mapped to addr 0, which *violated* a basic premise of GCC (and most C compilers). This point is the biggie: its extremely linux-specific, how in the hell can a cross-platform compiler (that is not linux specific) have handled this situation, or even *known* about it, never mind what the C Standard says about this, or more accurately, what it *doesn't* say?

      4) an optimization option that (we now know) shouldn't have been used for the kernel (now fixed - see the post above).

      Notice how it took *several* things, in sequence, to "go wrong" for this error to occur?

      And point #4 is I believe the real issue: a "user" of the GCC compiler was not setting up GCC to properly handle their obviously unusual environment. The onus should be on the *user* to use the tool properly, not for the tool to just "magically know" how it should behave in wildly different environments. Indeed, how *could* it possibly know what do in this complex case? It seems from the post above, that the "user" in this case (the linux kernel), is doing exactly that: telling GCC not to do something that isn't valid for their environment (but is perfectly valid for *most* other users, e.g., the compiling of *applications*, as opposed to a complex operating system kernel).

      Suggesting that we go back to more conservative compilers that don't attempt significant optimizations (which ultimately *requires* the modification and even *removal* of source code from the output) just isn't realistic at all. The world seems to be actually headed in the opposite direction: compilers that optimize even more aggressively.

    4. Re:It's a compiler bug, pure and simple. by argent · · Score: 1

      The "semantics of the language" don't help us since, in this case, we were already in "Undefined Behavior" territory by the time of the ptr check.

      Quality of implementation considerations rule out nasal demons.

      Yes, the code is busted, I'm not saying it isn't, but busted or not: removing a null pointer check added by the programmer... as opposed to one added by the compiler... is not a valid optimization. Even if you think it's safe to remove.

  49. Re:Linus, you Rookie !! by sjames · · Score: 2, Interesting

    The rest of us consider it a fundamental law of the universe.

    Clearly, your universe is too small! Technically, the code dereferenced NULL+offset where offset (and so NULL+offset) is non zero (which I presume you are hard wired to consider to be the NULL value).

    In an environment where a segv (or equivalent) won't be triggered, the code's not wrong until it makes use of an invalid dereference. The if would have prevented it. I don't think that makes it GOOD since in most environments it will fail.

    In some languages or with some C optimizers, the assignment would never be evaluated at all until after the if.

    Let's face it, the bug is a corner case in the complex interaction between the compiler and the kernel's vision of the environment.

  50. Re: Not really a joke by Douglas+Goodall · · Score: 1

    I have found errors in assemblers before during intense debugging. When the C doesn't do what you want, and the results in the debugger don't make sense, you have to toss all your assumptions and will yourself to see the non-obvious. I found bugs in the Intel assembler and the PharLap assembler in certain addressing modes that were not commonly used by assembly coders. These language tools are just that, Tools. When you are a serious software engineer, you are responsible down to the bit level for efficiency and reliability. It doesn't happen often, but when you are scratching your head and going around in circles, you have to check it down to the bits.

  51. SELinux? by metrix007 · · Score: 1

    How does this get past SELinux?

    If you can limit everything that people can do after exploiting a vulnerability and being on the system, and reducing root to nothing, how does this vulnerability/exploit differ?

    --
    If you ignore ACs because they are anonymous - you're an idiot.
  52. Remote exploit? by Macka · · Score: 1

    giving him complete control of the remote machine

    Where exactly does it say in TFA that this has been used to do a remote attack? It doesn't, and the YouTube demo shows quite clearly that Brad Spengler is already logged into the box he's cracking using his own account. Trailrunner7 is trying to sex this up. Of cause if there were a sizable population of consumer Linux desktops out there, and an active virus hacker community targeting the said consumers with all the social tricks they use in the Windows world to get them to execute attachments, then we would be in a world of trouble at this point. But of cause we're not are we.

  53. Mod parent up by wdebruij · · Score: 1

    This was a very clear explanation, thanks.

  54. Re:Linus, you Rookie !! by Your.Master · · Score: 1

    Why do so many people in this article think that tun->sk dereferences an offset? It offsets a dereference. There's a huge difference here. The compiler would be strictly wrong if it were the former, but the compiler is not violating the C standard (arguably the optimization is over-aggressive, but it's not WRONG).

    There are two bugs here:

    1. Null-pointer dereference. This is not an offset-dereference.
    2. Compiling with -fdelete-null-pointer-checks in a C-incompatible environment where NULL pointers can actually be validly dereferenced. Getting rid of that optimization would essentially leave you with a slightly-less performant offshoot language of C where you can dereference NULL.

    The submitted patch fixes only the former (thus far, anyway).

  55. No, NULL is not okay here. by reiisi · · Score: 1

    When you look at the code in context, tun is set by a function call, then you get to the initialization of the local sk variable, and after that it attempts to check the value of tun.

    So, yeah, the test is too late.

    --
    Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
  56. how the vulnerability was found? by reiisi · · Score: 1

    I'm pretty sure the guy who found it was not just throwing NULL pointers at all the APIs. (He used the source to find it.)

    --
    Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
  57. check the source? by reiisi · · Score: 1

    In the source, tun was set by a function call before the lines quoted.

    I'd say that's a bug in the the friendly article, myself.

    --
    Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
  58. real world by reiisi · · Score: 1

    In the real world, you are not using this kernel.

    --
    Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
  59. several thousand machines by reiisi · · Score: 1

    Maybe you have intricate dependencies. They do exist. Maybe you are running thousands of Linux machines. That's great.

    But it seems odd that you don't seem to realize that this particular bug is most likely not in any of the kernels running on any of those thousands of machines.

    --
    Computer memory is just fancy paper, CPUs just fancy pens with fancy erasers; the 'net is just a fancy backyard fence.
  60. Re:I really don't see how this is a compiler probl by RichiH · · Score: 1

    I think it's save to assume that there will be an option to warn about this, soon ;)

    That being said, you can already switch off the particular optimization, which is already planned for all (default) future kernel builds.

  61. Re:Linus, you Rookie !! by sjames · · Score: 1

    Why do so many people in this article think that tun->sk dereferences an offset?

    Because that's what it does? Gcc sure thinks so based on the code it generates. Yes, I did actually check, given c=p->b, p is a pointer to struct a, and struct a is struct a { int a[0x400]; int b; };, it loads the register for c with the data at the address p+offset. That generates exactly 1 fetch at the address of p+offset. In x86, that's movl 4096(%eax), %eax

    Note that just by having int a[0x400], I make sure that even when p=0, the actual memory access happens in page 1, not page zero, so even if the kernel makes sure page zero will always fault, the compiler generated code will happily let me do p->b when p=0. If you don't think it should, blame the compiler. Neither the kernel nor the hardware can know what source code lead to the memory access at address 0x1000, only the compiler can know that.

    If you then demand that there be two unmapped pages at the start of the address space, I'll just define int a[0x800] and bring the problem right back.

    That all means that the compiler's implicit assumption that p->b will necessarily fault when p=0 is dead wrong (and no, gcc does not confine that assumption to cases where the size of the struct is smaller than a page). Further, since C defines the NULL pointer and gcc (and most others) use 0 as a sentinel value for the NULL pointer, it's the compiler's responsibility to enforce that. The hardware doesn't consider accessing address 0 to be at all special.

    The convention of the kernel disallowing page zero being mapped and the compiler assuming that will cause a fault if a NULL pointer is used is a dirty hack. It does give a substantial performance benefit, so we can mostly forgive it (though it really should only assume that when sizeof(struct) < page size).

    Eliding code (that is, generating object code that doesn't do what the source code is defined to do) based on an assumption from a dirty hack that has provable failure cases is not something we can excuse. For the potential benefit of 8 bytes and 0.3 nano seconds it introduced a nasty security flaw.

    It's worth noting that if anyone at all had followed best practices, none of the ugliness would have had any actual effect, but it's the compiler that was dead wrong.

    Given that that's a rather big assumption and can cause so much badness, it probably shouldn't be enabled by the innocuous looking -O3. In all other cases I've seen, when optimizations might affect correctness, the manual warns about that and states under what conditions the problems can occur. All of the cases I've seen were shortcuts in floating point operations that might lose precision, not something that would rip out elements of program flow.

  62. Re:No, it's a compiler bug. (test code) by qieurowfhbvdklsj · · Score: 1

    I didn't use 'NULL' anywhere in the program. I used address '0', which 'NULL' is usually defined as, but strictly speaking, isn't the same thing. Basically what happened was that GCC, upon seeing me use the value in that pointer to access memory, up and decided it couldn't possibly be zero, and used that information for optimizations.

    Just because there is a NULL value doesn't mean the compiler should assume that that value is always NULL.

    In particular, if you want to use vm86 mode in Linux, for example to use BIOS calls or any other real-mode software which will want to look at the first page of memory, you have to map that memory to that address, which necessarily involves using pointers to address zero.