[PATCH RFC v3 82/90] net: use net_may() for raw and packet sockets

From: Josef Bacik

Date: Thu Nov 05 2026 - 10:44:31 EST


Creating an IPv4 or IPv6 raw socket or a packet socket requires
CAP_NET_RAW over the owner of the network namespace. So does sending
certain IP options and IPv6 extension headers from an ordinary socket.
Convert these checks to NET_RIGHT_RAW.

AF_XDP, LLC, NFC and IEEE 802.15.4 sockets are not converted.

No functional change.

Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
net/ipv4/af_inet.c | 2 +-
net/ipv4/ip_options.c | 8 ++++----
net/ipv6/af_inet6.c | 2 +-
net/ipv6/datagram.c | 6 +++---
net/packet/af_packet.c | 2 +-
5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 7677b0343abd..b24b50e0098e 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -320,7 +320,7 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,

err = -EPERM;
if (sock->type == SOCK_RAW && !kern &&
- !ns_capable(net->user_ns, CAP_NET_RAW))
+ !net_may(net, NET_RIGHT_RAW))
goto out_rcu_unlock;

sock->ops = answer->ops;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 09d745112c15..c9ab57a6f1a8 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -393,7 +393,7 @@ int __ip_options_compile(struct net *net,
optptr[2] += 8;
break;
default:
- if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (!skb && !net_may(net, NET_RIGHT_RAW)) {
pp_ptr = optptr + 3;
goto error;
}
@@ -428,7 +428,7 @@ int __ip_options_compile(struct net *net,
opt->router_alert = optptr - iph;
break;
case IPOPT_CIPSO:
- if ((!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) || opt->cipso) {
+ if ((!skb && !net_may(net, NET_RIGHT_RAW)) || opt->cipso) {
pp_ptr = optptr;
goto error;
}
@@ -441,7 +441,7 @@ int __ip_options_compile(struct net *net,
case IPOPT_SEC:
case IPOPT_SID:
default:
- if (!skb && !ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (!skb && !net_may(net, NET_RIGHT_RAW)) {
pp_ptr = optptr;
goto error;
}
@@ -530,7 +530,7 @@ int ip_options_get(struct net *net, struct ip_options_rcu **optp,
kfree(opt);
return -EINVAL;
}
- if (opt->opt.srr && !ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (opt->opt.srr && !net_may(net, NET_RIGHT_RAW)) {
kfree(opt);
return -EPERM;
}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a9b8b4b42a1a..03a630b92680 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -164,7 +164,7 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,

err = -EPERM;
if (sock->type == SOCK_RAW && !kern &&
- !ns_capable(net->user_ns, CAP_NET_RAW))
+ !net_may(net, NET_RIGHT_RAW))
goto out_rcu_unlock;

sock->ops = answer->ops;
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 191c9733ff9f..3d3e9fd4443a 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -912,7 +912,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
err = -EINVAL;
goto exit_f;
}
- if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (!net_may(net, NET_RIGHT_RAW)) {
err = -EPERM;
goto exit_f;
}
@@ -932,7 +932,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
err = -EINVAL;
goto exit_f;
}
- if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (!net_may(net, NET_RIGHT_RAW)) {
err = -EPERM;
goto exit_f;
}
@@ -957,7 +957,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
err = -EINVAL;
goto exit_f;
}
- if (!ns_capable(net->user_ns, CAP_NET_RAW)) {
+ if (!net_may(net, NET_RIGHT_RAW)) {
err = -EPERM;
goto exit_f;
}
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index cf6429f09477..006349f214e6 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3417,7 +3417,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
__be16 proto = (__force __be16)protocol; /* weird, but documented */
int err;

- if (!ns_capable(net->user_ns, CAP_NET_RAW))
+ if (!net_may(net, NET_RIGHT_RAW))
return -EPERM;
if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
sock->type != SOCK_PACKET)

--
2.55.0