summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-06-25 12:25:36 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-06-25 12:25:36 -0700
commit805185b7c7a1069e407b6f7b3bc98e44d415f484 (patch)
tree8e252490fc55ac4a2ef591efa06d078211fc639f /net/ipv4
parentc75597caada080effbfbc0a7fb10dc2a3bb543ad (diff)
parentfe9f4ee6c61a1410afd73bf011de5ae618004796 (diff)
downloadlwn-805185b7c7a1069e407b6f7b3bc98e44d415f484.tar.gz
lwn-805185b7c7a1069e407b6f7b3bc98e44d415f484.zip
Merge tag 'net-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter and IPsec. Current release - regressions: - do not acquire dev->tx_global_lock in netdev_watchdog_up() - ethtool: keep rtnl_lock for ops using ethtool_op_get_link() - fix deadlock in nested UP notifier events Current release - new code bugs: - eth: - cn20k: fix subbank free list indexing for search order - airoha: fix BQL underflow in shared QDMA TX ring Previous releases - regressions: - netfilter: - flowtable: fix offloaded ct timeout never being extended - nf_conncount: prevent connlimit drops for early confirmed ct Previous releases - always broken: - require CAP_NET_ADMIN in the originating netns when modifying cross-netns devices - report NAPI thread PID in the caller's pid namespace - mac802154: fix dirty frag in in-place crypto for IOT radios - sctp: hold socket lock when dumping endpoints in sctp_diag, avoid an overflow - eth: gve: fix header buffer corruption with header-split and HW-GRO - af_key: initialize alg_key_len for IPComp states, prevent OOB read" * tag 'net-7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (213 commits) selftests: bonding: add a test for VLAN propagation over a bonded real device vlan: defer real device state propagation to netdev_work net: add the driver-facing netdev_work scheduling API net: turn the rx_mode work into a generic netdev_work facility net: ethtool: keep rtnl_lock for ops using ethtool_op_get_link() rxrpc: Fix rxrpc_rotate_tx_rotate() to check there's something to rotate rxrpc: Fix leak of released call in recvmsg(MSG_PEEK) rxrpc: Fix socket notification race rxrpc: Fix potential infinite loop in rxrpc_recvmsg() rxrpc: Fix oob challenge leak in cleanup after notification failure rxrpc: Fix the reception of a reply packet before data transmission afs: Fix uncancelled rxrpc OOB message handler afs: Fix further netns teardown to cancel the preallocation charger rxrpc: Fix double unlock in rxrpc_recvmsg() rxrpc: Fix leak of connection from OOB challenge rxrpc: Fix ACKALL packet handling net: hns3: differentiate autoneg default values between copper and fiber net: hns3: fix permanent link down deadlock after reset net: hns3: refactor MAC autoneg and speed configuration net: hns3: unify copper port ksettings configuration path ...
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_gre.c6
-rw-r--r--net/ipv4/ip_output.c7
-rw-r--r--net/ipv4/ip_vti.c3
-rw-r--r--net/ipv4/ipip.c3
-rw-r--r--net/ipv4/netfilter/nf_reject_ipv4.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c10
-rw-r--r--net/ipv4/tcp_ao.c4
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv4/udp_tunnel_nic.c2
-rw-r--r--net/ipv4/xfrm4_input.c2
10 files changed, 30 insertions, 13 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 208dd48012d9..3efdfb4ffa21 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1457,6 +1457,9 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
__u32 fwmark = t->fwmark;
int err;
+ if (!rtnl_dev_link_net_capable(dev, t->net))
+ return -EPERM;
+
err = ipgre_newlink_encap_setup(dev, data);
if (err)
return err;
@@ -1486,6 +1489,9 @@ static int erspan_changelink(struct net_device *dev, struct nlattr *tb[],
__u32 fwmark = t->fwmark;
int err;
+ if (!rtnl_dev_link_net_capable(dev, t->net))
+ return -EPERM;
+
err = ipgre_newlink_encap_setup(dev, data);
if (err)
return err;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3b4e9b8af044..e6dd1e5b8c32 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1116,8 +1116,8 @@ alloc_new_skb:
!(rt->dst.dev->features & NETIF_F_SG)))
alloclen = fraglen;
else {
- alloclen = fragheaderlen + transhdrlen;
- pagedlen = datalen - transhdrlen;
+ alloclen = fragheaderlen + transhdrlen + fraggap;
+ pagedlen = datalen - transhdrlen - fraggap;
}
alloclen += alloc_extra;
@@ -1164,9 +1164,6 @@ alloc_new_skb:
}
copy = datalen - transhdrlen - fraggap - pagedlen;
- /* [!] NOTE: copy will be negative if pagedlen>0
- * because then the equation reduces to -fraggap.
- */
if (copy > 0 &&
INDIRECT_CALL_1(getfrag, ip_generic_getfrag,
from, data + transhdrlen, offset,
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 95b6bb78fcd2..3b80929994a0 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -596,6 +596,9 @@ static int vti_changelink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm_kern p;
__u32 fwmark = t->fwmark;
+ if (!rtnl_dev_link_net_capable(dev, t->net))
+ return -EPERM;
+
vti_netlink_parms(data, &p, &fwmark);
return ip_tunnel_changelink(dev, tb, &p, fwmark);
}
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 4f89a03e0b49..b643194f57d2 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -494,6 +494,9 @@ static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
bool collect_md;
__u32 fwmark = t->fwmark;
+ if (!rtnl_dev_link_net_capable(dev, t->net))
+ return -EPERM;
+
if (ip_tunnel_netlink_encap_parms(data, &ipencap)) {
int err = ip_tunnel_encap_setup(t, &ipencap);
diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
index fecf6621f679..4626dc46808f 100644
--- a/net/ipv4/netfilter/nf_reject_ipv4.c
+++ b/net/ipv4/netfilter/nf_reject_ipv4.c
@@ -89,7 +89,7 @@ static bool nf_skb_is_icmp_unreach(const struct sk_buff *skb)
if (iph->protocol != IPPROTO_ICMP)
return false;
- thoff = skb_network_offset(skb) + sizeof(*iph);
+ thoff = skb_network_offset(skb) + ip_hdrlen(skb);
tp = skb_header_pointer(skb,
thoff + offsetof(struct icmphdr, type),
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c0e85cc171ae..ca1180dba1de 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1058,7 +1058,9 @@ static struct ctl_table ipv4_net_table[] = {
.data = &init_net.ipv4.sysctl_tcp_reordering,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ONE,
+ .extra2 = &init_net.ipv4.sysctl_tcp_max_reordering,
},
{
.procname = "tcp_retries1",
@@ -1293,7 +1295,8 @@ static struct ctl_table ipv4_net_table[] = {
.data = &init_net.ipv4.sysctl_tcp_max_reordering,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ONE,
},
{
.procname = "tcp_dsack",
@@ -1676,6 +1679,9 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
*/
table[i].mode &= ~0222;
}
+ if (table[i].extra2 >= (void *)&init_net.ipv4 &&
+ table[i].extra2 < (void *)(&init_net.ipv4 + 1))
+ table[i].extra2 += (void *)net - (void *)&init_net;
}
}
diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
index 2f69bcecae78..a56bb79e15e0 100644
--- a/net/ipv4/tcp_ao.c
+++ b/net/ipv4/tcp_ao.c
@@ -1747,6 +1747,10 @@ static int tcp_ao_delete_key(struct sock *sk, struct tcp_ao_info *ao_info,
* them and we can just free all resources in RCU fashion.
*/
if (del_async) {
+ if (ao_info->current_key == key)
+ WRITE_ONCE(ao_info->current_key, NULL);
+ if (ao_info->rnext_key == key)
+ WRITE_ONCE(ao_info->rnext_key, NULL);
atomic_sub(tcp_ao_sizeof_key(key), &sk->sk_omem_alloc);
call_rcu(&key->rcu, tcp_ao_key_free_rcu);
return 0;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 26dd751ec72a..00ec4b5900f2 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2688,7 +2688,7 @@ static int tcp_mtu_probe(struct sock *sk)
struct sk_buff *skb, *nskb, *next;
struct net *net = sock_net(sk);
int probe_size;
- int size_needed;
+ u64 size_needed;
int copy, len;
int mss_now;
int interval;
@@ -2712,7 +2712,7 @@ static int tcp_mtu_probe(struct sock *sk)
mss_now = tcp_current_mss(sk);
probe_size = tcp_mtu_to_mss(sk, (icsk->icsk_mtup.search_high +
icsk->icsk_mtup.search_low) >> 1);
- size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
+ size_needed = probe_size + (tp->reordering + 1) * (u64)tp->mss_cache;
interval = icsk->icsk_mtup.search_high - icsk->icsk_mtup.search_low;
/* When misfortune happens, we are reprobing actively,
* and then reprobe timer has expired. We stick with current
diff --git a/net/ipv4/udp_tunnel_nic.c b/net/ipv4/udp_tunnel_nic.c
index 9944ed923ddf..3b32a0afa979 100644
--- a/net/ipv4/udp_tunnel_nic.c
+++ b/net/ipv4/udp_tunnel_nic.c
@@ -301,7 +301,7 @@ __udp_tunnel_nic_device_sync(struct net_device *dev, struct udp_tunnel_nic *utn)
static void
udp_tunnel_nic_device_sync(struct net_device *dev, struct udp_tunnel_nic *utn)
{
- if (!utn->need_sync)
+ if (!utn->need_sync || utn->work_pending)
return;
queue_work(udp_tunnel_nic_workqueue, &utn->work);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index c2eac844bcdb..f6f2a8ef3f88 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -76,8 +76,6 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
dev_net(dev), NULL, skb, dev, NULL,
xfrm4_rcv_encap_finish);
- if (async)
- dev_put(dev);
return 0;
}