Increase security by adjusting kernel settings by default: `kernel.yama.ptrace_scope` & `net.core.bpf_jit_harden` both defaulting to `1`

I would like to put this to discussion: does it make sense to default kernel.yama.ptrace_scope & net.core.bpf_jit_harden to 1? Both are 0 at the moment.
Update regarding the ongoing discussion below: it might be useful to consider 2 at bpf_jit_harden rather than 1 because the performance disadvantage might be not noteworthy in practice.

This adds some mitigations for respective attacks. While searching for a solution for a different problem, I stumbled over the two through the Arch Wiki, became curious and wondered about our defaults could be improved:

net.core.bpf_jit_harden:
Arch) https://wiki.archlinux.org/title/Security#BPF_hardening
Kernel Docs) Documentation for /proc/sys/net/ — The Linux Kernel documentation
kernel.yama.ptrace_scope:
Arch) Security - ArchWiki
Kernel Docs) Yama — The Linux Kernel documentation

I avoid further elaboration and refer to both the arch wiki and the related kernel documentation.

With regards to net.core.bpf_jit_harden:
I am not sure how much unprivileged code is affected on Fedora about this, but imho the mitigation (value 1 hardens against unprivileged code) is worth to be put in place and justifies the trade-off in performance: I saw that Arch sets this already by default to 2 (hardens against all code) in its hardened-kernel (though 0 in the other kernel but still suggesting 1 or 2), so if even a do-it-yourself community defaults to 2 for everyone using the hardened kernel (and generally suggesting it), I presume the performance trade-off ain’t that worse. I am aware that there are major differences between the distributions, but presume in this respect there might be comparability. Update: given the ongoing discussion below, it might be useful to consider to use 2 rather than 1 in bpf_jit_harden.

With regards to kernel.yama.ptrace_scope:
@decathorpe mentioned that he heard that Ubuntu already defaulted to 1. Arch sets this already by default to 1 too (also in the normal kernel, not just the hardened one). Again, I think 1 makes sense while 2 or 3 might cause negative trade-offs, in which we would have a bigger/wider issue with origins from somewhere else anyway. But feel free to discuss, again, my experience here is limited…

For now, I just want to raise some awareness of the possibilities and facilitate a discussion.

For the record (assuming this question might come up): The Fedora kernel is built with CONFIG_BPF_JIT_ALWAYS_ON=y/true (source: kernel-ark; can be verified with net.core.bpf_jit_enable=1)

1 Like

kernel.yama.ptrace_scope should default to 1 already but it seems that elfutils-default-yama-scope is setting it to 0 and elfutils-libs depends on it so anything that depends on elfutils will pull it in (which includes systemd).

Have no real opinion on net.core.bpf_jit_harden, my only personal use case for BPF is sched-ext which requires a privileged user so its unaffected.

Hm … do you know if that’s intentional? Lowering security below what the kernel defaults to by installing a package doesn’t sound like a good idea to me.

1 Like

Well, its not even something you have to install because its automatically pulled in with libelf which is pulled in by systemd and others.

To me this looks like the resolut of a disagreement over a decade ago, originally yama was enabled (1196825) but it affected existing software like gdb, the elfutils utils, reptyr and more (1209492, 1234951) so it was intentionally disabled by the elfutils maintainers (1250079).

I don’t know if this would still or ever did affect end-users or if developers just complained because their workflow was interrupted but I’ve asked around and apparently other distros just keep it at 1 so it should probably be fine to remove elfutils-default-yama-scope as a dependency though I think its fine to keep for developers that don’t want to manually override the scope every time.

3 Likes

Hmm… I would raise the question why it is fine for other distros to go the more secure way, which in some docs I read seem a little to be considered a best practice, while we don’t. The two mentioned examples also use, e.g., systemd.

As mentioned, my experience in this very field is limited, but in other areas, the need to disable security features, which others seem able to use, often is rooted in non-optimal practices (which doesn’t mean this is the case here of course). Not sure if it is maybe useful to evaluate WHY other can use this function and we don’t? Maybe it is indeed just the time that has passed that solved some issues that occurred earlier: the tickets are 10+ years old. Might be at least worth to be re-evaluated given the circumstances.

I presume those who need it 0 are qualified to identify and set it manually, as you say, keep the possibility shall be ok. For others the default might be better at 1 imho.

The proposal would mean that developers need to run GDB as root much more often because just-in-time debugging is gone for regular users. The is a trade-off here.

I believe that the system’s security should not be opt-in. I don’t dare give percentages, since I don’t really know the percentage of end users vs. developers using Fedora, but it seems more logical to me that the system should be “more” secure by default, and that each person should independently consider changing these configurations as needed for their use case.

This would only affect attaching tools like gdb / strace to already running processes, but not when those tools actually spawn those processes, right?

admin@fedora ~> sudo sysctl kernel.yama.ptrace_scope=1
kernel.yama.ptrace_scope = 1

admin@fedora ~> sleep 1000 &
admin@fedora ~> ps | grep sleep
   3858 pts/1    00:00:00 sleep

admin@fedora ~> gdb -p 3858
GNU gdb (Fedora Linux) 16.3-1.fc42
[...]
Attaching to process 3858
ptrace: Operation not permitted.
(gdb) q

admin@fedora ~> kill -9 3858
fish: Job 1, 'sleep 1000 &' terminated by signal SIGKILL (Forced quit)

admin@fedora ~> gdb /bin/sleep
GNU gdb (Fedora Linux) 16.3-1.fc42
[...]
(gdb) run 60
Starting program: /usr/bin/sleep 60
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Correct!

3 Likes

Thanks, then I had remembered this correctly. To be honest, that sounds like an acceptable tradeoff to me for setting the default to 1.

2 Likes

I just set my system to net.core.bpf_jit_harden=1 (also kernel.yama.ptrace_scope=1) at runtime to see if average tasks/activities work smooth and keep it that way (if so, I will later try to set it permanent), though I cannot imagine this to cause issues for average use cases of Fedora (and for specialized cases that might be relevant, I assume here as well that those affected will know how to mitigate).

I would maybe put both settings to relevant WGs/SIGs so that they can add their considerations if applicable, but in case of a doubt, I tend to prefer more security by default in both cases, and assume that is in the interest of the majority of the community, at least if no one can come up with potential issues - we already can see at other communities that both settings seem to be fine defaults.

1 Like

At $dayjob we have security controls for both of these values prescribed by DISA for RHEL 9, and I want to say we’ve had them for quite some time in our compliance documentation (at least back through RHEL 8). Mind you, DISA has given us problematic guidance in the past, but neither of these controls has caused us operational issues that I can find anywhere in our documentation history. We’re applying these values via entries somewhere in sysctl.conf. (Along with 31 others, but more than half of them are networking related.)

STIG ID Control Value
RHEL-09-213080 kernel.yama.ptrace_scope 1
RHEL-09-251045 net.core.bpf_jit_harden 2

Anyhow, I’m not saying we should do things to Fedora just because DISA made a recommendation to RHEL, but since the topic did come up in conversation I wanted to share that we have been using these controls on a product based on Fedora for years. The sky didn’t fall or anything like that, and life generally should continue.

1 Like

Wow, interesting that the suggesting is here to even go to 2. I like the idea, surely more security is better than less, but I would indeed ask here if the performance impact is noteworthy. I feel not qualified to predict this in different use cases / conditions / applications. I’ll try 2 and see in the next days when working on battery if battery life “feels” different with that. I got a little curious too ^^

Happy to help!

I totally agree with you, for most use cases setting it to 1 should be fine.

Minor addition: Didn’t do a precise testing/benchmark or so, but just working on battery as usual. My subjective perception/feeling: battery life is the same. So when working with email, Firefox stuff, file editing, etc., it seems to be fine. Not sure if there are activities on Fedora that cause privileged users’ code to be processed in bpf_jit in a way / amount that would noteworthy impact performance when hardening is imposed on it. I stick with 2 for now in bpf_jit_harden and 1 at ptrace_scope.

So we might consider/discuss to update my proposal to bpf_jit_harden to 2 rather than 1, and ptract_scope 1 as already suggested earlier. Except someone knows about performance/consumption issues in some use cases?

From what I understand systemd makes the most use of BPF. I also have bpf_jit_harden set to 2 on a notebook running Fedora 42 KDE, and I haven’t noticed any additional performance issues (although I should clarify that the notebook is quite old, so it doesn’t have the best possible performance to begin with).

+1 for that!

@decathorpe do we need a change proposal for this? Given the mentioned tickets, it seems this type of decision has been done within bugzilla in the past, and changing these two settings now to “2”/“1” or at least “1”/“1” seems a minor decision in terms of the impact on user experience (I have seen WGs doing much more invasive decisions without change proposal). So I assume this can be processed through FESCo or so in the usual public way without a dedicated change proposal?

I would classify this as a System-Wide Change.

1 Like

I try to find some time to create a proposal ^^

Since you/FESCo will be involved with the decision making, would you agree that “2” makes sense rather than “1” for net.core.bpf_jit_harden? Still working with “2”, and I cannot identify performance impacts or anything else on average desktop/workstation activities, nor could I identify issues from others.

I ask in order to determine if the proposal should go with “2” from the beginning (so “2” for bpf_jit_harden, and “1” for ptrace_scope). I tend to assume this makes sense, and if “2” is in the proposal, FESCo could still decide to stick with “1” as “compromise in the middle” between the current condition and the proposal" without a new change proposal (just in case if there is disagreement with “2”).

I don’t know enough about eBPF to comment on that. But proposing “2” as the new default, with “1” as a fallback if there are sufficient arguments against “2” sounds good to me.

1 Like