Index | Thread | Search

From:
Matthew Luckie <mjl@luckie.org.nz>
Subject:
[patch] allow IP_RECVIF setsockopt with inet pledge
To:
tech@openbsd.org
Date:
Thu, 16 Apr 2026 08:25:27 +1200

Download raw body.

Thread
  • Matthew Luckie:

    [patch] allow IP_RECVIF setsockopt with inet pledge

Hi,

I have written a small program that runs unpriviledged that uses
IP_RECVIF to obtain the interface a UDP datagram arrives on.  I would
like to be able to pledge("inet stdio") but pledge does not allow
IP_RECVIF.  I think it should be able to -- pledge_sockopt() allows
the equivalent functionality provided by IPV6_RECVPKTINFO.

Attached is a one-line change to kern_pledge.c that allows for it.
I've tested it in openbsd 7.8.  I also noticed that ip.4 did not
document existence of IP_RECVIF so I copied the description from
freebsd's ip.4 man page and tweaked it (I believe IP_RECVIF is allowed
for SOCK_RAW sockets too).

Patch is against HEAD.

Matthew

diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index 27e29612cd8..124c4685ce0 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -213,6 +213,35 @@ setsockopt(s, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl));
 .Ed
 .Pp
 If the
+.Dv IP_RECVIF
+option is enabled on a
+.Dv SOCK_DGRAM
+or
+.Dv SOCK_RAW
+socket, the
+.Xr recvmsg 2
+call returns a
+.Vt "struct sockaddr_dl"
+corresponding to the interface on which the
+packet was received.
+The
+.Va msg_control
+field in the
+.Vt msghdr
+structure points to a buffer that contains a
+.Vt cmsghdr
+structure followed by the
+.Vt "struct sockaddr_dl" .
+The
+.Vt cmsghdr
+fields have the following values:
+.Bd -literal -offset indent
+cmsg_len = CMSG_LEN(sizeof(struct sockaddr_dl))
+cmsg_level = IPPROTO_IP
+cmsg_type = IP_RECVIF
+.Ed
+.Pp
+If the
 .Dv IP_IPSECFLOWINFO
 option is enabled on a
 .Dv SOCK_DGRAM
diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c
index 21861720b8b..99c43580073 100644
--- a/sys/kern/kern_pledge.c
+++ b/sys/kern/kern_pledge.c
@@ -1475,6 +1475,7 @@ pledge_sockopt(struct proc *p, int set, int level, int optname)
 		case IP_PORTRANGE:
 		case IP_RECVDSTADDR:
 		case IP_RECVDSTPORT:
+		case IP_RECVIF:
 			return (0);
 		case IP_MULTICAST_IF:
 		case IP_MULTICAST_TTL: