akira2501 21 hours ago

You should not be calling getentropy() often enough to be concerned about it's performance. Of course RAND_bytes will be faster because it doesn't have to context switch into ring 0 to do the job. The vDSO feels like a complete punt by libc authors on providing a sane interface to random number generation particularly in threaded environments, but to be fair, POSIX really is zero help here.

Finally if you just need to seed an RNG once in a single threaded process, there's always getauxval(3) with the AT_RANDOM op, combined with any number of RNGs works a real treat.

  • fanf2 21 hours ago

    Why would I use Linux-only getauxval() when POSIX specifies a reasonably portable getentropy()?

    Your theory about the relative performance is what I thought, but it turns out not to be the case for older versions of OpenSSL.

    The cover letter for getrandom() vDSO support explains the whys and wherefores pretty well https://lwn.net/ml/all/20240712014009.281406-1-Jason@zx2c4.c...

    • akira2501 20 hours ago

      Auxiliary values are a part of the ELF specification.

      Did you compare older versions of OpenSSL against the kernels that were contemporary to their release dates?

      And I read the LKML thread. In particular, I don't agree with statement 2, which seems to boil down to "it's harder to get right on VMs, and one time we forgot we had to special case hibernation, so that serves as justification for the vDSO."

      The notion seemingly being "we want to make it easy to write carefree cryptographically secure code all managed by the kernel." I think you can have two of those three but probably not all three at once. What end state are we actually trying to create here?

      • fanf2 19 hours ago

        Auxiliary values are part of ELF, but it only specifies the layout in memory. ELF doesn’t specify a header that defines the AT_… values and some systems don’t even spell them with that prefix.

      • djbusby 18 hours ago

        > What end state are we actually trying to create here?

        Getting sufficiently random bits (perhaps crypto) in a portable and fast way.

      • dale_glass 20 hours ago

        I don't see what the big deal is here? Why fight so much over such a tiny patch?

        To me this all seems like a no-brainer. A performant way to do a security-critical thing with less footguns, using an already existing mechanism.

        • akira2501 20 hours ago

          I don't see what's making you interpret this as a "big deal" or a "fight." This is Hacker News on a Saturday. I'm offering some really light and off the cuff analysis over what may potentially be a bad feature.

          I would not consider the kernel's internal entropy management a way to find "less foot guns." I don't think I'm the only one who feels this way, in particular, I think it's telling that the only way to form a cogent argument around this feature is by invoking VMs with bad vendor state management facilities.

          Anyways.. I felt like commenting because this generally feels like the "worse is actually better" trend in kernel development that's become en vogue lately. I personally, just don't like it, and I thought this was a forum where I could just basically say that, without someone feeling confronted by it.

          • dale_glass 19 hours ago

            > I don't see what's making you interpret this as a "big deal" or a "fight."

            I meant the general amount of discussion about it, including here, LWN and LKML

            > I'm offering some really light and off the cuff analysis over what may potentially be a bad feature.

            In what way could it be bad? I can only see it as a bit more complexity than needed, perhaps.

            > I would not consider the kernel's internal entropy management a way to find "less foot guns."

            Why not? The kernel is the ultimate arbiter of everything and the best place to have an accurate view. Userspace is at the mercy of the kernel, so it can't be as good.

            > I think it's telling that the only way to form a cogent argument around this feature is by invoking VMs with bad vendor state management facilities.

            That's what I mean by less footguns: a solution where userspace code can be written in a straightforward manner and not worry that everything might have changed underneath is less likely to go wrong.

            > I felt like commenting because this generally feels like the "worse is actually better" trend in kernel development that's become en vogue lately.

            What do you see as "worse"? It's faster, and it's less troublesome. Win/Win as far as I can see.

          • johnisgood 7 hours ago

            Well, I would have never considered to use getauxval() for the purposes mentioned and I have not seen it used either, so thank you for mentioning it.

    • why_only_15 17 hours ago

      Why does portability matter here? I guess if you want to run on macOS too?

    • monocasa 14 hours ago

      Can't getentropy(3) block for arbitrary amounts of time since it's based on get getrandom(2), whereas the data for AT_RANDOM is already on the initial thread's stack?

      • jart 13 hours ago

        The getrandom(2) man page guarantees it doesn't block or get a signal if it's less than 256 bytes and you're not using GRND_RANDOM. That's basically the subset of getrandom that getentropy uses.

        • monocasa 13 hours ago

          That's not my reading.

          > If the urandom source has not yet been initialized, then getrandom() will block, unless GRND_NONBLOCK is specified in flags.

          And glibc's implementation doesn't specify any flags. https://github.com/bminor/glibc/blob/e67f8e6dbd5ec98578a775b...

          Where as GRND_RANDOM is about switching to the random source instead of the urandom source.

          > GRND_RANDOM

          > If this bit is set, then random bytes are drawn from the random source (i.e., the same source as the /dev/random device) instead of the urandom source....

          The combo seems to imply both sources can block, urandom is just less likely to.

          https://man7.org/linux/man-pages/man2/getrandom.2.html

          • jart 13 hours ago

            Yes but what does initialized mean? Is that like an early bootup thing?

            • monocasa 10 hours ago

              There isn't a guarantee of that.

              It is the current implementation that it's only an early boot time thing, but it would make sense to revert to uninitialized in cases like is brought up in the patch series. That is when some event like vm rehydration means that existing entropy needs to be invalidated. On x86 you'll pretty much always have an hwrng when you have virtualization extensions, but that isn't true for other archs.

              • jart 10 hours ago

                It's such a ridiculous API. What's the point of documenting a guarantee if there's officially speaking no guarantee? When I implemented getentropy() for cosmo libc, it'll actually issue three system calls in the best case on Linux to block signals while calling getrandom() because I've never trusted it.

                But I still refuse to believe it's possible for a PRNG to block in a way where there's observable side-effects like EINTR. It's just too insane. There's no Linux architecture that does this when flags==0 && size<=256 and there never will be one, because that's a bug. Prove that it can happen and we shall patch the kernel to make it not happen.

                • monocasa 36 minutes ago

                  I mean, if there isn't enough entropy yet to seed the kernel's PRNG (because say, you just resumed a VM image, and all entropy pools are invalidated), and you didn't specify that it's allowed to fail becuase you didn't specify non block, what is it supposed to do other than block and allow signals and thus potentially fail with EINTR?

                  I fail to see the bug here.

            • fanf2 11 hours ago

              Yes, exactly.