Skip to content

privsep: ps_root_recvmsg: Permission denied on FreeBSD 14.4 (raw socket sendmsg EPERM) #600

@zachfi

Description

@zachfi

Summary

On FreeBSD 14.4-RELEASE-p1 with dhcpcd 10.3.1, the privsep root proxy's sendmsg() on raw sockets returns EPERM, preventing DHCPv6 IA_NA lease acquisition and IPv6 ND entirely. This worked correctly on FreeBSD 14.3.

Symptoms

/var/log/daemon.log shows repeated:

dhcpcd[pid]: ps_root_recvmsg: Permission denied
dhcpcd[pid]: igb2: soliciting an IPv6 router

The error fires roughly every 64 seconds (the RS retransmit interval) and no global IPv6 address is ever assigned. DHCPv4 on the same interface is unaffected.

Environment

  • OS: FreeBSD 14.4-RELEASE-p1 (amd64)
  • dhcpcd: 10.3.1 (built from ports net/dhcpcd)
  • Capsicum: present and tested as yes in configure
  • Interface: single egress NIC (igb2), dhcpcd_iface="igb2" in rc.conf
  • dhcpcd.conf:
    duid
    persistent
    nohook resolv.conf
    
    interface igb2 {
      ia_na 1
    }
    

Root cause analysis

The privsep root proxy opens two raw sockets in ps_root_startcb():

  • nd_fd: SOCK_RAW | IPPROTO_ICMPV6 — used for IPv6 ND (router solicitation/advertisement)
  • dhcp6_wfd: SOCK_RAW | IPPROTO_UDP — used for DHCPv6 sending

ps_inet_sendmsg() calls sendmsg() on these descriptors from within the root proxy process and receives EPERM on FreeBSD 14.4. The same code path worked on 14.3.

Running dhcpcd with -d -B (debug, no background) confirms the failure:

sending on RawSocket socket → Permission denied
multicasting SOLICIT6 → Permission denied

Hypothesis

FreeBSD 14.4 appears to have tightened raw socket privilege checks or changed Capsicum capability rights in a way that blocks sendmsg() on raw sockets from the root proxy. The ps_rights_limit_fdpair() call applies CAP_READ | CAP_WRITE | CAP_EVENT | CAP_SHUTDOWN — it's possible CAP_WRITE is no longer sufficient for sendmsg() on raw sockets in 14.4, or a kernel change now requires an additional right/privilege for IPPROTO_ICMPV6 raw socket writes.

This is distinct from the privsep socket permission issues fixed in 10.3.0 (MSG_EOR) and 10.3.1 (MSG_PEEK) — those were IPC socket fixes; this is a raw socket sendmsg() EPERM from the root process itself.

Workaround

Rebuilding dhcpcd with --disable-privsep restores full DHCPv4+DHCPv6 functionality. The FreeBSD port (net/dhcpcd) does not currently expose a PRIVSEP build option, so this requires a per-jail make.conf override — a separate report has been sent to the port maintainer.

Suggested investigation

  • Check whether FreeBSD 14.4 changed the privilege model for SOCK_RAW | IPPROTO_ICMPV6 sockets (e.g. requires PRIV_NETINET_RAW or similar even when running as root)
  • Check whether ps_rights_limit_fd* needs an additional Capsicum right for raw socket sendmsg() on 14.4
  • Consider whether the root proxy should open raw sockets after Capsicum rights are applied, or whether rights need to be widened for the nd/dhcp6 write fds

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions