Announcement

Collapse
No announcement yet.

Systemd 241 Being Prepared With "System Down" Security Fixes

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #11
    Originally posted by lucrus View Post
    As Guest already pointed out, there's no way to store that information in a C array, without completely breaking compatibility with almost all existing C code. We could imagine to invent a optional compiler switch that automatically adds code to:
    1. store the array size somewhere else, maybe a portion of the heap memory, but not into the array itself, when the array is created or the pointer is referenced. That alone would hit performance to a level that would render C useless.
    2. enable automatic checks on every array access (square brackets) and pointer dereference, by looking up bounds stored in point 1. That would render any C code execution slower than ancient Scheme on a 80286 machine.
    3. garbage collect all the sheer amount of array and pointer sizes information stored in 1.
    If you really want that all, then I have good news for you: that compiler switch already exists. You can switch to javac...
    Technically you can easily store it before the array, unless it's part of a struct whose layout must be exact. In this case probably needs a new syntax to declare such arrays, just to avoid this ambiguity.

    I would hate for it to be added though.

    Comment


    • #12
      Originally posted by caligula View Post

      I suppose so if you use bounds checked arrays.

      The main reason why C does allow out of bounds access is that storing the array length was horribly expensive when computers had only 1 to 32 kB of RAM. Now they have 32 GB, but C programmers will still argue that billion dollar bugs every now and then are way better than wasting 4 bytes worth of space for every array.
      Yeah though afaik on amd64 it will use up 8 (not 4) bytes as noted here [1]. OTOH when I have an array in C++ I still usually store its length somewhere so it kinda evens out except that in Rust it's part of the language and enforced which is awesome.
      But I'm not saying everything in Rust is good.


      [1] https://iandouglasscott.com/2018/05/...-fat-pointers/

      Comment


      • #13
        Damn, Rust is more disgusting than I thought.

        Comment


        • #14
          Originally posted by caligula View Post

          I suppose so if you use bounds checked arrays.

          The main reason why C does allow out of bounds access is that storing the array length was horribly expensive when computers had only 1 to 32 kB of RAM. Now they have 32 GB, but C programmers will still argue that billion dollar bugs every now and then are way better than wasting 4 bytes worth of space for every array.
          I am a hobby C programmer and I don't think you fully understand this do you? First of all 4 bytes is not by any means a suitable size to store any random array length so this is far off already (this has nothing to do with 32bits vs 64bits by the way).
          Second in C code you can easily access stuff in an array without using the brackets at all - imagine a pointer to an array for example.
          Third. If you check for out of bounds access every single time you access an array it will be a performance hit no matter if you are running on a gazillion terrahertz or 1Mhz. Have you ever considered how much more complex the code will get if you need to check out of bounds on every array access!? do that in assembly code first and see the difference. If you have a tight loop then using extra registers for storing array length can be a significant performance hit as you may need to push and pop on the stack to be able to do all the thing you need to do in that loop.



          http://www.dirtcellar.net

          Comment


          • #15
            Originally posted by hussam View Post

            Hypothetically speaking, how would one store a length property in a C array anyway? An extra 4 bytes at the end for the size at the end of the bytes sequence?
            Perhaps, throw the length and the array pointer into a struct, and pass the struct pointer around? Another argument they have used against bounds checking is that it takes an arithmatic operation to do, adding a little more overhead. Ignore this, better to be safe adn a little slower.

            Also, avoid alloca. Send all of your variable length data to functions as an array pointer you malloc'd. The use of alloca in systemd is egregious.
            Last edited by jpg44; 13 January 2019, 12:18 PM.

            Comment


            • #16
              Originally posted by hreindl View Post

              what exactly did you not understand in "which is not possible on proper configured systems"? :-)

              [harry@localhost:~]$ cat /dev/kmsg
              cat: /dev/kmsg: Operation not permitted

              and for some hardening you need to do your homework to begin with, group 4502 don't exist by default

              [root@srv-rhsoft:~]$ cat /etc/fstab | grep hidepid
              # https://linux-audit.com/linux-system...depid-to-proc/
              proc /proc proc rw,nosuid,nodev,noexec,relatime,hidepid=2,gid=4502

              [root@srv-rhsoft:~]$ cat /etc/systemd/system/systemd-logind.service.d/hidepid.conf
              [Service]
              SupplementaryGroups=4502
              Can't think of any reasons of having such anal security measures on my desktop PC. And on a sever it also doesn't make a lot of sense given that nowadays it's trendy to put each daemon into a container. In this case if an attacker gets access to a root user via journald this hardening is pretty much worthless.

              Comment


              • #17
                Originally posted by hussam
                how would one store a length property in a C array anyway? An extra 4 bytes at the end for the size at the end of the bytes sequence?
                LOL, nice low quality bait.

                Originally posted by Weasel View Post
                Automatic bounds checks are garbage because they apply everywhere, even in places where they are not needed, which is disgusting (not just the bytes, lol, also execution, wasting an entry in the branch predictor, and cache pollution).
                You don't need to perform checks every time you access the array elements. Instead, only once per operation, which means O(1) overhead per any array operation. This is already way better than the current behavior. Computing the length would be O(1) instead of O(n). A boxed representation only requires few bytes. If you care about the caches so much, use a custom allocator.

                Useless bounds checks also make you more vulnerable to Spectre. The irony.
                There are ways to avoid that.

                Originally posted by lucrus
                As hussam already pointed out, there's no way to store that information in a C array, without completely breaking compatibility with almost all existing C code.
                Of course you can add a new array type with its own operations and functions. I didn't ask you to use C. Look how other languages (not C++) did it.

                If you really want that all, then I have good news for you: that compiler switch already exists. You can switch to javac...
                Java is one possibility. It's not dramatically slower. Enterprises use it. The runtime will be a it bloated for generating simple logs though.

                Originally posted by waxhead
                First of all 4 bytes is not by any means a suitable size to store any random array length so this is far off already (this has nothing to do with 32bits vs 64bits by the way).
                Well obviously the size needs to be stored using size_t.

                Second in C code you can easily access stuff in an array without using the brackets at all - imagine a pointer to an array for example.
                You can also kill yourself in 10000 different ways. It doesn't imply you should.

                If you check for out of bounds access every single time you access an array it will be a performance hit no matter if you are running on a gazillion terrahertz or 1Mhz. Have you ever considered how much more complex the code will get if you need to check out of bounds on every array access!?
                Bollocks. You keep around references to a boxed representation, check once, and use optimized safe operations that validate with the size field.

                Originally posted by jpg44
                Another argument they have used against bounds checking is that it takes an arithmatic operation to do, adding a little more overhead. Ignore this, better to be safe adn a little slower.
                Java does this and I can tell you it's not really that slow.

                Comment


                • #18
                  Originally posted by Weasel View Post
                  Damn, Rust is more disgusting than I thought.
                  Yeah, nothing beats the beauty of a plain pointer that will let you read whatever memory location you can think of (and quite often locations you don't think about).

                  Comment


                  • #19
                    Originally posted by caligula View Post
                    LOL, nice low quality bait.
                    Sure my idea was bad but no, definitely not a bait. I'm actually interested on how this can be accomplished in C. I know it is easy with an Array class in object oriented languages.

                    @jpg44 That's a good idea. I think GLib achieves something similar with structs.

                    Comment


                    • #20
                      Maybe it's my own bias here, but it seems to me that people take a certain amount of delight in bugs in systemd. That seemed evident to me when I read about these vulnerabilities on Reddit.

                      To me it's simply a case of 'bug found in systemd...systemd devs patch it and release a new version'. This is pretty much the case with every software project ever. People talk about systemd like it's the only program to ever have an exploit found in it.

                      Comment

                      Working...
                      X