I'll let others handle the new instructions, but wanted to comment on
this piece.

+++ share/man/man4/bpf.4        10 Nov 2025 20:51:14 -0000
@@ -189,6 +189,9 @@
 .Dv BIOCGSTATS .
 .Pp
 .It Dv BIOCLOCK
+Sets the locked flag on the
+.Nm
+descriptor.

The full block of text once expanded:

     BIOCLOCK
             This ioctl is designed to prevent the security issues associated
             with an open bpf descriptor in unprivileged programs.  Even with
             dropped privileges, an open bpf descriptor can be abused by a
             rogue program to listen on any interface on the system, send
             packets on these interfaces if the descriptor was opened read-
             write and send signals to arbitrary processes using the signaling
             mechanism of bpf.  By allowing only "known safe" ioctls, the
             BIOCLOCK ioctl prevents this abuse.  The allowable ioctls are
             BIOCFLUSH, BIOCGBLEN, BIOCGDIRFILT, BIOCGDLT, BIOCGDIRFILT,
             BIOCGDLTLIST, BIOCGETIF, BIOCGHDRCMPLT, BIOCGRSIG, BIOCGRTIMEOUT,
             BIOCGSTATS, BIOCIMMEDIATE, BIOCLOCK, BIOCSRTIMEOUT,
             BIOCSWTIMEOUT, BIOCDWTIMEOUT, BIOCVERSION, TIOCGPGRP, and
             FIONREAD.  Use of any other ioctl is denied with error EPERM.
             Once a descriptor is locked, it is not possible to unlock it.  A
             process with root privileges is not affected by the lock.

             A privileged program can open a bpf device, drop privileges, set
             the interface, filters and modes on the descriptor, and lock it.
             Once the descriptor is locked, the system is safe from further
             abuse through the descriptor.  Locking a descriptor does not
             prevent writes.  If the application does not need to send packets
             through bpf, it can open the device read-only to prevent writing.
             If sending packets is necessary, a write-filter can be set before
             locking the descriptor to prevent arbitrary packets from being
             sent out.

That's quite a lot of words explaining the locking mechanism and how it is
supposed to be used.  There is strong implication that this ioctl op sets
the lock which activates this behaviour.

I don't like the idea of mentioning a 'lock on the descriptor'.  From a
programmer's perspective, descriptor refers to the 'fd'.  But there are
other styles of locks on fd, reachable with fcntl and flock.

I don't like the sentence about root not being affected, and I regret
that we did this:

        if (d->bd_locked && suser(p) != 0) {
                /* list of allowed ioctls when locked and not root */
                switch (cmd) {

I wonder if we've modified enough programs that we can change this:
constrain root's abilities on a bd_locked bpf also.

Reply via email to