Page MenuHomeFreeBSD

ip6_id: Avoid blocking if random(4) is not available
AbandonedPublic

Authored by cem on Apr 19 2019, 7:57 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 25, 10:54 PM
Unknown Object (File)
Thu, Apr 25, 10:33 PM
Unknown Object (File)
Thu, Apr 25, 7:05 AM
Unknown Object (File)
Sat, Apr 20, 12:13 AM
Unknown Object (File)
Sun, Apr 7, 9:00 AM
Unknown Object (File)
Sun, Apr 7, 8:28 AM
Unknown Object (File)
Sun, Apr 7, 7:49 AM
Unknown Object (File)
Jan 27 2024, 9:42 AM
Subscribers

Details

Reviewers
jhb
hrs
bz
Summary

If kern.random.initial_seeding.bypass_before_seeding is disabled, random(4)
and arc4random(9) will block indefinitely until enough entropy is available
to initially seed Fortuna.

Test Plan

Given use of high-performance but non-CSPRNG generators, maybe it makes more
sense for this interface to be available (without strong random seed) during
such initial conditions rather than block. But I am not really familiar with
ip6_id and am looking for some expert opinion.

Diff Detail

Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 23776
Build 22724: arc lint + arc unit

Event Timeline

sys/netinet6/ip6_id.c
188–191

If CPU cost isn't a big concern in this anticipated-to-be-rare scenario, and the tradeoff seems better, one other option would be to take the SHA256 digest of the cyclecount to better distribute the bits.

Is there a notification for when we are fully seeded the first time and entropy is available? FlowIDs are a controversial subject as to what they mean and what they are good to use for (see various RFCs and drafts, especially from Brian Carpenter in the last years). BSD enable random flowids by default but we could equally, if not set by application, leave them 0 for the first few packets.

That said, this is not needed before interfaces are up which is quite a way into multi-user normally. I keep wondering if it's maybe just done too early if it is a problem?

In D19973#429484, @bz wrote:

Is there a notification for when we are fully seeded the first time and entropy is available?

Not programmatic (yet), but I think there could be if we needed/wanted one. We print "random: unblocking device." to dmesg.

FlowIDs are a controversial subject as to what they mean and what they are good to use for (see various RFCs and drafts, especially from Brian Carpenter in the last years). BSD enable random flowids by default but we could equally, if not set by application, leave them 0 for the first few packets.

Ok.

That said, this is not needed before interfaces are up which is quite a way into multi-user normally. I keep wondering if it's maybe just done too early if it is a problem?

Yeah, that's true. There is no problem if we can guarantee is_random_seeded() before flowids are ever generated. But it does seem to happen early enough, maybe on lo0? Or perhaps some embedded board doesn't have any great source of early entropy and must pass some IPv6 traffic first before being seeded.

Edit (example):

Apr 17 17:24:41 testvm kernel: arc4rand may block once with the following non-sleepable locks held:
Apr 17 17:24:41 testvm kernel: exclusive sleep mutex pcbinfohash (pcbinfohash) r = 0 (0xfffffe000038dd78) locked @ /usr/home/conrad/src/freeb>
Apr 17 17:24:41 testvm kernel: exclusive rw udpinp (udpinp) r = 0 (0xfffff80003ca6208) locked @ /usr/home/conrad/src/freebsd/sys/netinet6/udp>
Apr 17 17:24:41 testvm kernel: stack backtrace:
Apr 17 17:24:41 testvm kernel: #0 0xffffffff80c11f64 at witness_debugger.part.14+0xa4
Apr 17 17:24:41 testvm kernel: #1 0xffffffff80c15265 at witness_warn+0x285
Apr 17 17:24:41 testvm kernel: #2 0xffffffff80c93371 at arc4rand+0x41
Apr 17 17:24:41 testvm kernel: #3 0xffffffff80c93538 at arc4random+0x18
Apr 17 17:24:41 testvm kernel: #4 0xffffffff80e10abc at randomid+0x2c
Apr 17 17:24:41 testvm kernel: #5 0xffffffff80e10bc0 at ip6_randomflowlabel+0x10
Apr 17 17:24:41 testvm kernel: #6 0xffffffff80e0c615 at in6_pcbconnect_mbuf+0x2d5
Apr 17 17:24:41 testvm kernel: #7 0xffffffff80e30b35 at udp6_connect+0x295
Apr 17 17:24:41 testvm kernel: #8 0xffffffff80c454e8 at soconnectat.part.16+0x118
Apr 17 17:24:41 testvm kernel: #9 0xffffffff80c4c2ae at kern_connectat+0x25e
Apr 17 17:24:41 testvm kernel: #10 0xffffffff80c4c362 at sys_connect+0x52
Apr 17 17:24:41 testvm kernel: #11 0xffffffff81098994 at amd64_syscall+0x424
Apr 17 17:24:41 testvm kernel: #12 0xffffffff8106ff3d at fast_syscall_common+0x101

I think we can just use zero for the label if enough entropy is not available. A flow label of zero indicates no flow label "treatment" in the network. On my test machine most early packets are already have a flow label of zero. From RFC 6437

A Flow Label of zero is used to indicate packets that have not been labeled.

Even then, the RFC series is deliberately non binding on what should go into a flow label. Here is the most normative text from RFC 6437 on flow label randomness

In statistics, a discrete uniform distribution is defined as a
probability distribution in which each value in a given range of
equally spaced values (such as a sequence of integers) is equally
likely to be chosen as the next value.  The values in such a
distribution exhibit both variability and unguessability.  Thus, as
specified in Section 3, an approximation to a discrete uniform
distribution is preferable as the source of flow label values.
Intentionally, there are no precise mathematical requirements placed
on the distribution or the method used to achieve such a
distribution.
In D19973#429748, @thj wrote:

I think we can just use zero for the label if enough entropy is not available. A flow label of zero indicates no flow label "treatment" in the network.

That’s easy and fine with me. Is that reasonable, @bz?

This function is also used for non-flowid number generation; I’m not sure if those can be zero early on.

In D19973#429776, @cem wrote:
In D19973#429748, @thj wrote:

I think we can just use zero for the label if enough entropy is not available. A flow label of zero indicates no flow label "treatment" in the network.

That’s easy and fine with me. Is that reasonable, @bz?

For IPv6 flowid as I said initially "we could equally, if not set by application, leave them 0 for the first few packets."

This function is also used for non-flowid number generation; I’m not sure if those can be zero early on.

What else are we looking at? Your initial description describes the problem but not really what all is affected?

In D19973#429780, @bz wrote:
In D19973#429776, @cem wrote:

This function is also used for non-flowid number generation; I’m not sure if those can be zero early on.

What else are we looking at? Your initial description describes the problem but not really what all is affected?

The two functions tagged below. One is apparently for flowids but I’m away from my workstation and not sure what the scope of the other one’s use is.

sys/netinet6/ip6_id.c
273

Just these two functions.

280

And this.

Will pursue available initial seeding in another way.