* [PATCH net v5 3/3] nfc: llcp: fix TLV parsing OOB in nfc_llcp_connect_sn
From: Lekë Hapçiu @ 2026-07-16 20:35 UTC (permalink / raw)
To: David Heidelberg
Cc: davem, edumazet, kuba, pabeni, krzk, horms, linux-kernel, netdev,
oe-linux-nfc, Lekë Hapçiu, stable
In-Reply-To: <20260716203507.7328-1-snowwlake@icloud.com>
nfc_llcp_connect_sn() walks the TLV array of an LLCP CONNECT PDU
looking for the Service Name TLV, but shares the same class of bugs
as nfc_llcp_recv_snl() / nfc_llcp_parse_gb_tlv():
1. tlv_array_len = skb->len - LLCP_HEADER_SIZE wraps when skb->len
is 0 or 1. The subsequent loop then runs far past the buffer.
2. The per-iteration guard `offset < tlv_array_len` only proves one
byte is available, but the body reads both tlv[0] (type) and
tlv[1] (length).
3. The peer-supplied `length` field is used to advance `tlv` without
being checked against the remaining array space, so a crafted
length walks `tlv` past the buffer. On the following iteration
tlv[0]/tlv[1] are read from adjacent memory.
4. When an LLCP_TLV_SN is found, the function returns &tlv[2] with
*sn_len = length but without verifying that `length` bytes at
tlv[2..] are still inside the TLV array. The caller in
nfc_llcp_recv_connect() then uses this (pointer, length) pair as
a service name, so it may read past the PDU.
Fix: reject frames smaller than LLCP_HEADER_SIZE up front; add TLV
header and TLV value guards at the top of each iteration. The value
guard also ensures that the (&tlv[2], length) pair returned on
LLCP_TLV_SN lies fully inside the TLV array.
Also use LLCP_HEADER_SIZE instead of the magic literal `2` to match
the style of neighbouring LLCP receive paths.
Reported-by: Simon Horman <horms@kernel.org>
Closes: https://lore.kernel.org/netdev/20260417160438.GH31784@horms.kernel.org/
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Signed-off-by: Lekë Hapçiu <snowwlake@icloud.com>
---
net/nfc/llcp_core.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index edec2fd83f79..c4dda8e7cfcf 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -849,12 +849,22 @@ static struct nfc_llcp_sock *nfc_llcp_sock_get_sn(struct nfc_llcp_local *local,
static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
{
u8 type, length;
- const u8 *tlv = &skb->data[2];
- size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0;
+ const u8 *tlv;
+ size_t tlv_array_len, offset = 0;
+
+ if (skb->len < LLCP_HEADER_SIZE)
+ return NULL;
+
+ tlv = &skb->data[LLCP_HEADER_SIZE];
+ tlv_array_len = skb->len - LLCP_HEADER_SIZE;
while (offset < tlv_array_len) {
+ if (tlv_array_len - offset < 2)
+ break;
type = tlv[0];
length = tlv[1];
+ if (tlv_array_len - offset - 2 < length)
+ break;
pr_debug("type 0x%x length %d\n", type, length);
--
2.51.0
^ permalink raw reply related
* [PATCH net v5 2/3] nfc: llcp: fix OOB read of DM reason byte in nfc_llcp_recv_dm
From: Lekë Hapçiu @ 2026-07-16 20:35 UTC (permalink / raw)
To: David Heidelberg
Cc: davem, edumazet, kuba, pabeni, krzk, horms, linux-kernel, netdev,
oe-linux-nfc, Lekë Hapçiu, stable
In-Reply-To: <20260716203507.7328-1-snowwlake@icloud.com>
nfc_llcp_recv_dm() reads skb->data[2] (the DM reason byte) without
first verifying that skb->len is at least LLCP_HEADER_SIZE + 1. A DM
PDU carrying only the 2-byte LLCP header from a rogue peer therefore
triggers a 1-byte OOB read.
Add the minimum-length guard at function entry, matching the pattern
used by nfc_llcp_recv_snl() and nfc_llcp_recv_agf().
Fixes: 5c0560b7a5c6 ("NFC: Handle LLCP Disconnected Mode frames")
Cc: stable@vger.kernel.org
Signed-off-by: Lekë Hapçiu <snowwlake@icloud.com>
---
net/nfc/llcp_core.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index aed5fe1afef0..edec2fd83f79 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1250,6 +1250,11 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
struct sock *sk;
u8 dsap, ssap, reason;
+ if (skb->len < LLCP_HEADER_SIZE + 1) {
+ pr_err("Malformed DM PDU\n");
+ return;
+ }
+
dsap = nfc_llcp_dsap(skb);
ssap = nfc_llcp_ssap(skb);
reason = skb->data[2];
--
2.51.0
^ permalink raw reply related
* [PATCH net v5 1/3] nfc: nci: fix u8 underflow in nci_store_general_bytes_nfc_dep
From: Lekë Hapçiu @ 2026-07-16 20:35 UTC (permalink / raw)
To: David Heidelberg
Cc: davem, edumazet, kuba, pabeni, krzk, horms, linux-kernel, netdev,
oe-linux-nfc, Lekë Hapçiu, stable
In-Reply-To: <20260716203507.7328-1-snowwlake@icloud.com>
nci_store_general_bytes_nfc_dep() computes the General Bytes length by
subtracting a fixed header offset from the peer-supplied atr_res_len
(POLL) or atr_req_len (LISTEN) field:
ndev->remote_gb_len = min_t(__u8,
atr_res_len - NFC_ATR_RES_GT_OFFSET, /* offset = 15 */
NFC_ATR_RES_GB_MAXSIZE);
Both length fields are __u8. When a malicious NFC-DEP peer sends an
ATR_RES/ATR_REQ whose length is smaller than the fixed offset (< 15
or < 14 respectively), the subtraction wraps:
atr_res_len = 0 -> (u8)(0 - 15) = 241
min_t(__u8, 241, NFC_ATR_RES_GB_MAXSIZE=47) = 47
The subsequent memcpy then reads 47 bytes beyond the valid activation
parameter data into ndev->remote_gb[]. This buffer is later fed to
nfc_llcp_parse_gb_tlv() as a TLV array.
Reject the frame with NCI_STATUS_RF_PROTOCOL_ERROR when the length is
below the required offset. The existing caller already logs and
continues for other helpers that return a non-OK status from this
switch, so no change is required on the caller side.
Fixes: 767f19ae698e ("NFC: Implement NCI dep_link_up and dep_link_down")
Cc: stable@vger.kernel.org
Signed-off-by: Lekë Hapçiu <snowwlake@icloud.com>
---
net/nfc/nci/ntf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 87f76a29f0ec..1a38f4666e97 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -653,6 +653,9 @@ static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev,
switch (ntf->activation_rf_tech_and_mode) {
case NCI_NFC_A_PASSIVE_POLL_MODE:
case NCI_NFC_F_PASSIVE_POLL_MODE:
+ if (ntf->activation_params.poll_nfc_dep.atr_res_len <
+ NFC_ATR_RES_GT_OFFSET)
+ return NCI_STATUS_RF_PROTOCOL_ERROR;
ndev->remote_gb_len = min_t(__u8,
(ntf->activation_params.poll_nfc_dep.atr_res_len
- NFC_ATR_RES_GT_OFFSET),
@@ -665,6 +668,9 @@ static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev,
case NCI_NFC_A_PASSIVE_LISTEN_MODE:
case NCI_NFC_F_PASSIVE_LISTEN_MODE:
+ if (ntf->activation_params.listen_nfc_dep.atr_req_len <
+ NFC_ATR_REQ_GT_OFFSET)
+ return NCI_STATUS_RF_PROTOCOL_ERROR;
ndev->remote_gb_len = min_t(__u8,
(ntf->activation_params.listen_nfc_dep.atr_req_len
- NFC_ATR_REQ_GT_OFFSET),
--
2.51.0
^ permalink raw reply related
* [PATCH net v5 0/3] nfc: fix remaining OOB bugs in NCI/LLCP parsing
From: Lekë Hapçiu @ 2026-07-16 20:35 UTC (permalink / raw)
To: David Heidelberg
Cc: davem, edumazet, kuba, pabeni, krzk, horms, linux-kernel, netdev,
oe-linux-nfc, Lekë Hapçiu
Rebased against David's linux-nfc for-linus tree [1], as requested.
This was originally a 5-patch series. Two of the five (the
parse_gb_tlv()/parse_connection_tlv() offset-wrap fix and the
nfc_llcp_recv_snl() TLV bounds fix) have since been fixed independently
by other contributors already merged into for-linus:
d8bd2dedbde5 ("nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers")
27256cdb290e ("nfc: llcp: bound SNL TLV parsing to the skb and add length checks")
Those two are dropped from this series to avoid duplicating work. The
remaining three patches are unchanged in substance from v4, just
rebased and renumbered:
1/3 (was 1/5) - nci_store_general_bytes_nfc_dep() u8 underflow
2/3 (was 4/5) - nfc_llcp_recv_dm() OOB read of the reason byte
3/3 (was 5/5) - nfc_llcp_connect_sn() TLV parsing OOB
All three still reproduce against current for-linus (verified against
1671b8fb7300 before rebase). checkpatch --strict is clean on all three.
[1] https://codeberg.org/linux-nfc/linux.git for-linus
Lekë Hapçiu (3):
nfc: nci: fix u8 underflow in nci_store_general_bytes_nfc_dep
nfc: llcp: fix OOB read of DM reason byte in nfc_llcp_recv_dm
nfc: llcp: fix TLV parsing OOB in nfc_llcp_connect_sn
net/nfc/llcp_core.c | 19 +++++++++++++++++--
net/nfc/nci/ntf.c | 6 ++++++
2 files changed, 23 insertions(+), 2 deletions(-)
--
2.51.0
^ permalink raw reply
* [PATCH 3/3 net-next] ipv6: add CAP_NET_ADMIN check for forwarding and force_forwarding sysctl
From: Fernando Fernandez Mancera @ 2026-07-16 20:37 UTC (permalink / raw)
To: netdev
Cc: horms, pabeni, kuba, edumazet, davem, idosch, dsahern,
Fernando Fernandez Mancera
In-Reply-To: <20260716203713.17392-1-fmancera@suse.de>
As commit 8292d7f6e871 ("net: ipv4: add capability check for net
administration") did for IPv4, make sure that CAP_NET_ADMIN is required
to modify IPv6 forwarding and force_forwarding sysctl. This keep the
consistency of permission check logic between both protocols.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
net/ipv6/addrconf.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f6fa2715b450..b2a0e6a4189d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6363,11 +6363,15 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
static int addrconf_sysctl_forward(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
+ struct net *net = ctl->extra2;
struct ctl_table lctl;
int *valp = ctl->data;
int val = *valp;
int ret;
+ if (write && !ns_capable(net->user_ns, CAP_NET_ADMIN))
+ return -EPERM;
+
/*
* ctl->data points to idev->cnf.forwarding, we should
* not modify it until we get the rtnl lock.
@@ -6805,6 +6809,9 @@ static int addrconf_sysctl_force_forwarding(const struct ctl_table *ctl, int wri
int old_val = *valp;
int ret;
+ if (write && !ns_capable(net->user_ns, CAP_NET_ADMIN))
+ return -EPERM;
+
tmp_ctl.extra1 = SYSCTL_ZERO;
tmp_ctl.extra2 = SYSCTL_ONE;
tmp_ctl.data = &new_val;
--
2.55.0
^ permalink raw reply related
* [PATCH 2/3 net-next] ipv6: remove unnecessary reset of position pointer
From: Fernando Fernandez Mancera @ 2026-07-16 20:37 UTC (permalink / raw)
To: netdev
Cc: horms, pabeni, kuba, edumazet, davem, idosch, dsahern,
Fernando Fernandez Mancera
In-Reply-To: <20260716203713.17392-1-fmancera@suse.de>
The position pointer is only advanced if the return value of the proc
handler is positive at new_sync_write(). Therefore no need to manually
reset it when doing error handling.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
Note: The checkpatch warnings here are false positive, lctl cannot be
const in this context
---
net/ipv6/addrconf.c | 24 ++++--------------------
1 file changed, 4 insertions(+), 20 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f1fe9ede1edb..f6fa2715b450 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6363,10 +6363,9 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
static int addrconf_sysctl_forward(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
+ struct ctl_table lctl;
int *valp = ctl->data;
int val = *valp;
- loff_t pos = *ppos;
- struct ctl_table lctl;
int ret;
/*
@@ -6382,8 +6381,6 @@ static int addrconf_sysctl_forward(const struct ctl_table *ctl, int write,
if (write)
ret = addrconf_fixup_forwarding(ctl, valp, val);
- if (ret)
- *ppos = pos;
return ret;
}
@@ -6462,10 +6459,9 @@ static int addrconf_disable_ipv6(const struct ctl_table *table, int *p, int newf
static int addrconf_sysctl_disable(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
+ struct ctl_table lctl;
int *valp = ctl->data;
int val = *valp;
- loff_t pos = *ppos;
- struct ctl_table lctl;
int ret;
/*
@@ -6481,8 +6477,6 @@ static int addrconf_sysctl_disable(const struct ctl_table *ctl, int write,
if (write)
ret = addrconf_disable_ipv6(ctl, valp, val);
- if (ret)
- *ppos = pos;
return ret;
}
@@ -6667,10 +6661,9 @@ int addrconf_sysctl_ignore_routes_with_linkdown(const struct ctl_table *ctl,
size_t *lenp,
loff_t *ppos)
{
+ struct ctl_table lctl;
int *valp = ctl->data;
int val = *valp;
- loff_t pos = *ppos;
- struct ctl_table lctl;
int ret;
/* ctl->data points to idev->cnf.ignore_routes_when_linkdown
@@ -6685,8 +6678,6 @@ int addrconf_sysctl_ignore_routes_with_linkdown(const struct ctl_table *ctl,
if (write)
ret = addrconf_fixup_linkdown(ctl, valp, val);
- if (ret)
- *ppos = pos;
return ret;
}
@@ -6767,10 +6758,9 @@ int addrconf_disable_policy(const struct ctl_table *ctl, int *valp, int val)
static int addrconf_sysctl_disable_policy(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
+ struct ctl_table lctl;
int *valp = ctl->data;
int val = *valp;
- loff_t pos = *ppos;
- struct ctl_table lctl;
int ret;
lctl = *ctl;
@@ -6782,9 +6772,6 @@ static int addrconf_sysctl_disable_policy(const struct ctl_table *ctl, int write
if (write && (*valp != val))
ret = addrconf_disable_policy(ctl, valp, val);
- if (ret)
- *ppos = pos;
-
return ret;
}
@@ -6816,7 +6803,6 @@ static int addrconf_sysctl_force_forwarding(const struct ctl_table *ctl, int wri
int *valp = ctl->data;
int new_val = *valp;
int old_val = *valp;
- loff_t pos = *ppos;
int ret;
tmp_ctl.extra1 = SYSCTL_ZERO;
@@ -6852,8 +6838,6 @@ static int addrconf_sysctl_force_forwarding(const struct ctl_table *ctl, int wri
rtnl_net_unlock(net);
}
- if (ret)
- *ppos = pos;
return ret;
}
--
2.55.0
^ permalink raw reply related
* [PATCH 1/3 net-next] ipv4: remove unnecessary reset of position pointer
From: Fernando Fernandez Mancera @ 2026-07-16 20:37 UTC (permalink / raw)
To: netdev
Cc: horms, pabeni, kuba, edumazet, davem, idosch, dsahern,
Fernando Fernandez Mancera
In-Reply-To: <20260716203713.17392-1-fmancera@suse.de>
The position pointer is only advanced if the return value of the proc
handler is positive at new_sync_write(). Therefore no need to manually
reset it when doing error handling.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
net/ipv4/devinet.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a35b72662e43..8b68fe37e6ba 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2607,10 +2607,9 @@ static int devinet_conf_proc(const struct ctl_table *ctl, int write,
static int devinet_sysctl_forward(const struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
+ struct net *net = ctl->extra2;
int *valp = ctl->data;
int val = *valp;
- loff_t pos = *ppos;
- struct net *net = ctl->extra2;
int ret;
if (write && !ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -2623,7 +2622,6 @@ static int devinet_sysctl_forward(const struct ctl_table *ctl, int write,
if (!rtnl_net_trylock(net)) {
/* Restore the original values before restarting */
*valp = val;
- *ppos = pos;
return restart_syscall();
}
if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
--
2.55.0
^ permalink raw reply related
* [PATCH 0/3 net-next] Misc. minor improvements on IPv4/IPv6 sysctl handling
From: Fernando Fernandez Mancera @ 2026-07-16 20:37 UTC (permalink / raw)
To: netdev
Cc: horms, pabeni, kuba, edumazet, davem, idosch, dsahern,
Fernando Fernandez Mancera
Minor improvements for sysctl proc handlers of IPv4 and IPv6, they were
found while working on [1] and [2].
[1] https://lore.kernel.org/netdev/20260712013941.4570-1-fmancera@suse.de/
[2] https://lore.kernel.org/netdev/20260622130857.5115-1-fmancera@suse.de/
Fernando Fernandez Mancera (3):
ipv4: remove unnecessary reset of position pointer
ipv6: remove unnecessary reset of position pointer
ipv6: add CAP_NET_ADMIN check for forwarding and force_forwarding
sysctl
net/ipv4/devinet.c | 4 +---
net/ipv6/addrconf.c | 31 +++++++++++--------------------
2 files changed, 12 insertions(+), 23 deletions(-)
--
2.55.0
^ permalink raw reply
* Re: [PATCH net-next v4 2/3] ptp: Add driver for R-Car Gen4
From: Niklas Söderlund @ 2026-07-16 20:35 UTC (permalink / raw)
To: Vadim Fedorenko
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-renesas-soc, devicetree, linux-kernel, netdev
In-Reply-To: <21d2e632-5307-4b48-be7b-1269b55f70fe@linux.dev>
Hi Vadim,
Thanks for your feedback.
On 2026-07-02 15:39:25 +0100, Vadim Fedorenko wrote:
> On 02/07/2026 13:55, Niklas Söderlund wrote:
> > Add driver for the gPTP timer found on R-Car Gen4 devices. The timer is
> > system-wide and shared by different Ethernet devices on each Gen4
> > platform. The operation of the timer is however not completely in
> > depended of the systems Ethernet devices.
> >
> > - On R-Car S4 is gated by the RSWITCH Ethernet module clock.
> >
> > - On R-Car V4H is gated by the RTSN Ethernet module clock.
> >
> > - On R-Car V4M is gated by its own module clock, the system have
> > neither RTSN or RSWITCH device. But the module clock is the same as
> > RTSN on V4H and the documentation referees to it as tsn (EtherTSN).
> >
> > The gPTP device do have its own register space on all three platforms.
> > But on S4 and V4H it will share its clock and reset property with
> > RSWITCH or RTSN, respectively.
> >
> > Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> > ---
> > * Changes since v3
> > - Clamp increment calculated to register limitations.
> > - Check return value of clk_get_rate().
> > - Disable PM if ptp_clock_register() fails.
> > ---
>
> [...]
>
> > +struct ptp_rcar_gen4_priv {
> > + void __iomem *base;
> > + struct clk *clk;
> > +
> > + struct ptp_clock *clock;
> > + struct ptp_clock_info info;
> > +
> > + spinlock_t lock; /* Registers access. */
> > + s64 default_addend;
> > +};
> > +
> > +#define ptp_to_priv(ptp) container_of(ptp, struct ptp_rcar_gen4_priv, info)
> > +
> > +static int ptp_rcar_gen4_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
> > +{
> > + struct ptp_rcar_gen4_priv *priv = ptp_to_priv(ptp);
> > + s64 addend = priv->default_addend;
> > + bool neg_adj = scaled_ppm < 0;
> > + unsigned long flags;
> > + s64 diff;
> > +
> > + if (neg_adj)
> > + scaled_ppm = -scaled_ppm;
> > + diff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC);
> > + addend = neg_adj ? addend - diff : addend + diff;
> > +
> > + /* Clamp value to register limits, defined as in nanoseconds.
> > + * bit[31:27] - integer
> > + * bit[26:0] - decimal
> > + */
> > + addend = clamp_val(addend, 0, UINT_MAX);
>
> is it always positive number?
Yes.
The value written to the PTPTIVC0_REG register is the timer increment in
ns per clock pulse. The PTP is clocked by different rates on different
SoC. 200Mhz on V4H and 320Mhz on S4. On each pulse the PTP timer is
incremented by this value. For example,
If clock frequency is 50 MHz, 100Mhz, 200Mhz, 320MHz or 400MHz,
it should be respectively set to a value around 0xA0000000, 0x50000000,
0x28000000, 0x19000000 or 0x14000000.
>
> > +
> > + spin_lock_irqsave(&priv->lock, flags);
> > + iowrite32(addend, priv->base + PTPTIVC0_REG);
> > + spin_unlock_irqrestore(&priv->lock, flags);
> > +
> > + return 0;
> > +}
>
> [...]
>
> > +static struct ptp_clock_info ptp_rcar_gen4_info = {
> > + .owner = THIS_MODULE,
> > + .name = "R-Car Gen4 gPTP",
> > + .max_adj = 50000000,
>
> even though clamping addend may work, I would suggest adjusting
> ".max_adj" value to the one which will not make addend overflow.
> And as a reminder, .max_adj is the absolute value in ppb that can be set
> for a single call of .adjfine - the value is checked against
> [-(.max_adj),.max_adj] range.
Thanks for the reminder, but is this not then correct and prevents any
overflow? From the calculations above.
(a) s64 addend = priv->default_addend;
...
(b) if (neg_adj)
(b) scaled_ppm = -scaled_ppm;
(c) diff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC);
(d) addend = neg_adj ? addend - diff : addend + diff;
Section (a) copies the default addend value. This value is calculated at
probe time as a function of the PTP module clock (50 MHz, 100Mhz,
200Mhz, 320MHz or 400MHz) to a known value. The max value being
0xA0000000 for a 50Mhz module clock.
Sections (b) and (d) deals with the value we add at each clock tick is
in fact based on the PTP module clock itself.
So the one place we could overflow is in section (c). Lets look at the
worse case scenario.
addend = priv->default_addend = <from PTP clock worse case 50 MHz> = 0xA0000000
scaled_ppm_to_ppb(scaled_ppm) = .max_adj = 50000000
addend * scaled_ppm_to_ppb(scaled_ppm)
= 0xA0000000 * 50000000
= 0x1DCD65000000000
That is OK and fits inside a s64.
div_s64(0x1DCD65000000000, NSEC_PER_SEC)
= div_s64(0x1DCD65000000000, 1000000000L)
= 0x8000000
That is OK and does not overflow.
But I agree it's not very clear and depends on knowing from the
datasheet that the possible PTP clock rates are.
How can I best move forward here? Drop the clamp added and depend on the
.max_adj value to prevent the overflow with the implicit knowledge of
the clock rates? I can extend the comment in the probe function of how
priv->default_addend is computed, but for somebody looking at the
calculation that might not help much.
>
> > + .adjfine = ptp_rcar_gen4_adjfine,
> > + .adjtime = ptp_rcar_gen4_adjtime,
> > + .gettime64 = ptp_rcar_gen4_gettime,
> > + .settime64 = ptp_rcar_gen4_settime,
> > +};
--
Kind Regards,
Niklas Söderlund
^ permalink raw reply
* [PATCH net v2 2/2] geneve: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-16 20:35 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, andrew+netdev
Cc: fmancera, sd, linville, mschiffer, maoyixie.tju, netdev,
linux-kernel, stable
In-Reply-To: <20260716203500.70573-1-doruk@0sec.ai>
A tunnel changelink() operates on at most two netns, dev_net(dev) and
the sticky underlay netns geneve->net. They differ once the device is
created in or moved to a netns other than the one the request runs in.
The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
so a caller privileged there but not in geneve->net can rewrite a geneve
device whose underlay lives in geneve->net.
geneve_changelink() applies the new configuration against geneve->net:
geneve_link_config() and the geneve_quiesce()/geneve_unquiesce() pair
reopen the underlay sockets in that netns (geneve_sock_add() uses
geneve->net), so the same reasoning as the tunnel changelink series
applies here.
Gate geneve_changelink() with rtnl_dev_link_net_capable(), at the top of
the op before any attribute is parsed, matching ipgre_changelink() and
the rest of the "require CAP_NET_ADMIN in the device netns for
changelink" series.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 5b861f6baa3a ("geneve: add rtnl changelink support")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
v2: correct the Fixes: tag to the commit that added changelink (Fernando Mancera).
drivers/net/geneve.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 396e1a113cd4..03c99a016298 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -2376,6 +2376,9 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
struct geneve_config cfg;
int err;
+ if (!rtnl_dev_link_net_capable(dev, geneve->net))
+ return -EPERM;
+
/* If the geneve device is configured for metadata (or externally
* controlled, for example, OVS), then nothing can be changed.
*/
--
2.43.0
^ permalink raw reply related
* [PATCH net v2 1/2] vxlan: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-16 20:34 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, andrew+netdev
Cc: fmancera, sd, linville, mschiffer, maoyixie.tju, netdev,
linux-kernel, stable
In-Reply-To: <20260716203500.70573-1-doruk@0sec.ai>
A tunnel changelink() operates on at most two netns, dev_net(dev) and
the sticky underlay netns vxlan->net. They differ once the device is
created in or moved to a netns other than the one the request runs in.
The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev),
so a caller privileged there but not in vxlan->net can rewrite a vxlan
device whose underlay lives in vxlan->net.
vxlan_changelink() validates and applies the new configuration against
vxlan->net (vxlan_config_validate(vxlan->net, ...)) and can reopen the
underlay socket in that netns, so the same reasoning as the tunnel
changelink series applies here.
Gate vxlan_changelink() with rtnl_dev_link_net_capable(), at the top of
the op before any attribute is parsed, matching ipgre_changelink() and
the rest of the "require CAP_NET_ADMIN in the device netns for
changelink" series.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 8bcdc4f3a20b ("vxlan: add changelink support")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
v2: correct the Fixes: tag to the commit that added changelink (Fernando Mancera).
drivers/net/vxlan/vxlan_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 67c367cc5662..d834a4865aec 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -4421,6 +4421,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
struct vxlan_rdst *dst;
int err;
+ if (!rtnl_dev_link_net_capable(dev, vxlan->net))
+ return -EPERM;
+
dst = &vxlan->default_dst;
err = vxlan_nl2conf(tb, data, dev, &conf, true, extack);
if (err)
--
2.43.0
^ permalink raw reply related
* [PATCH net v2 0/2] vxlan, geneve: require CAP_NET_ADMIN in the device netns for changelink
From: Doruk Tan Ozturk @ 2026-07-16 20:34 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, andrew+netdev
Cc: fmancera, sd, linville, mschiffer, maoyixie.tju, netdev,
linux-kernel, stable
The recent series "require CAP_NET_ADMIN in the device netns for
changelink" (8165f7ff57d9..27ccb68e7ccc) added rtnl_dev_link_net_capable()
and gated the eight IP tunnel drivers (ip_gre, ipip, ip_vti, ip6_tunnel,
ip6_gre, ip6_vti, sit, xfrm_interface). VXLAN and GENEVE share the exact
same shape but were not covered: both store the underlay netns sticky at
newlink (vxlan->net / geneve->net) and their changelink() operates on that
netns, while the generic RTM_NEWLINK path only checks CAP_NET_ADMIN against
dev_net(dev). Once such a device is created in or moved to another netns,
a caller privileged in dev_net(dev) but not in the underlay netns can
reconfigure the tunnel'"'"'s underlay.
This completes that series for the two UDP tunnel drivers that were left
out. Same helper, same placement (top of changelink, before any attribute
is parsed).
Verified on next-20260714 in QEMU with CONFIG_VXLAN=y + CONFIG_USER_NS=y:
an unprivileged user namespace holding CAP_NET_ADMIN only in a child netns
issues an IFLA_INFO_DATA changelink on a vxlan device whose underlay lives
in init_net. Before: returns 0 (reconfigures the init_net underlay).
After: returns -EPERM.
v2:
- Correct the Fixes: tag on both patches to the commit that added
changelink support (8bcdc4f3a20b for vxlan, 5b861f6baa3a for geneve),
as pointed out by Fernando Mancera. No code changes.
Doruk Tan Ozturk (2):
vxlan: require CAP_NET_ADMIN in the device netns for changelink
geneve: require CAP_NET_ADMIN in the device netns for changelink
drivers/net/geneve.c | 3 +++
drivers/net/vxlan/vxlan_core.c | 3 +++
2 files changed, 6 insertions(+)
base-commit: cc2b5f627e8ccbae1188ef2d8be3e451d7f933a5
--
2.43.0
^ permalink raw reply
* [REGRESSION][BISECTED] stmmac: suspend hangs since 1b9707e6f1a9 ("net: stmmac: enable RPS and RBU interrupts")
From: tresonic @ 2026-07-16 20:10 UTC (permalink / raw)
To: netdev; +Cc: regressions, rmk+kernel, kuba
Hello,
Please bear with me, this is my first time writing to a mailing list...
Since commit 1b9707e6f1a9, suspend (systemctl suspend) causes a full system freeze on my laptop. Fans and keyboard backlight stay powered; the machine is completely unresponsive and requires a hard power-off (holding the power button) to recover. I could not get any kernel output from the hang.
- Reproduces on current master
- git revert 1b9707e6f1a9... on top of master fixes the issue
- Workaround: sudo ip link set eno1 down before suspend avoids the hang entirely; with the interface down, suspend/resume works normally even on the bad commit
Hardware:
64:00.0 Ethernet controller: Motorcomm Microelectronics. YT6801 Gigabit Ethernet Controller (rev 01)
Kernel driver in use: dwmac-motorcomm
[ 5.672548] YT8531S Gigabit Ethernet stmmac-6400:00: attached PHY driver (mii_bus:phy_addr=stmmac-6400:00, irq=POLL)
[ 5.890940] dwmac-motorcomm 0000:64:00.0 eno1: PHY [stmmac-6400:00] driver [YT8531S Gigabit Ethernet] (irq=POLL)
Thank you,
tresonic
^ permalink raw reply
* Re: [PATCH net 2/7] selftests: openvswitch: add config file
From: Aaron Conole @ 2026-07-16 20:00 UTC (permalink / raw)
To: Matthieu Baerts (NGI0)
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Shuah Khan, netdev, linux-kselftest, linux-kernel,
Eelco Chaudron, Ilya Maximets, dev
In-Reply-To: <f7t5x2frlkh.fsf@redhat.com>
Aaron Conole <aconole@redhat.com> writes:
> Hi Matthieu,
>
> "Matthieu Baerts (NGI0)" <matttbe@kernel.org> writes:
>
>> The kselftests doc mentions that a config file should be present "if a
>> test needs specific kernel config options enabled". This selftest
>> requires some kernel config, but no config file was provided.
>>
>> We could say that a sub-target could use the parent's config file, but
>> the kselftests doc doesn't mention anything about that. Plus the
>> net/openvswitch target is the only net target without a config file.
>
> We've been operating on that assumption from the openvswitch side, but
> it's true that isn't explicitly documented anywhere, and I guess it
> isn't officially supported in the kselftest framework. I guess we'll
> need to keep updating this config as we add tests for things like SCTP,
> and others, and maybe that's a good thing like we can add a comment
> describing which tests take which configs.
>
> The downside is for most of the OVS testing we use the NIPA scripts
> and those 'inherit' the parent config, so it would be a change on our
> side from the development standpoint (but probably something we should
> have been doing from the beginning).
>
> That said, would it be worth also exploring the 'cascading
> configuration' support? It seems like a useful feature, but maybe it
> should be a separate discussion. I ask because of how OVS interacts
> with the networking stack as an 'alternative bridge' so-to-speak, I do
> worry about having to duplicate lots of configurations between the two
> as we expand the test coverage on OVS side.
>
>> Here is a new config file, which is a trimmed version of the net one,
>> with hopefully the minimal required kconfig on top of 'make defconfig'.
>
> Should this also remove the OVS configs from the upper level since there
> shouldn't be OVS tests executing there (ie: CONFIG_OPENVSWITCH*)?
Actually, forget this part. The P-MTU tests in pmtu.sh use ovs to
create a datapath through OVS. So these configurations need to stay at
the top level as well.
>> The Fixes tag points to the introduction of the net/openvswitch target,
>> just to help validating this target on stable kernels.
>>
>> Fixes: 25f16c873fb1 ("selftests: add openvswitch selftest suite")
>> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
>> ---
>> To: Aaron Conole <aconole@redhat.com>
>> To: Eelco Chaudron <echaudro@redhat.com>
>> To: Ilya Maximets <i.maximets@ovn.org>
>> Cc: dev@openvswitch.org
>> ---
>> tools/testing/selftests/net/openvswitch/config | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>>
>> diff --git a/tools/testing/selftests/net/openvswitch/config
>> b/tools/testing/selftests/net/openvswitch/config
>> new file mode 100644
>> index 000000000000..c659749cd086
>> --- /dev/null
>> +++ b/tools/testing/selftests/net/openvswitch/config
>> @@ -0,0 +1,16 @@
>> +CONFIG_GENEVE=m
>> +CONFIG_INET_DIAG=y
>> +CONFIG_IPV6=y
>> +CONFIG_NETFILTER=y
>> +CONFIG_NET_IPGRE=m
>> +CONFIG_NET_IPGRE_DEMUX=m
>> +CONFIG_NF_CONNTRACK=m
>> +CONFIG_NF_CONNTRACK_OVS=y
>> +CONFIG_OPENVSWITCH=m
>> +CONFIG_OPENVSWITCH_GENEVE=m
>> +CONFIG_OPENVSWITCH_GRE=m
>> +CONFIG_OPENVSWITCH_VXLAN=m
>> +CONFIG_PSAMPLE=m
>> +CONFIG_VETH=y
>> +CONFIG_VLAN_8021Q=y
>> +CONFIG_VXLAN=m
^ permalink raw reply
* Re: [PATCH v8 1/9] dt-bindings: mmc: Document fixed-layout NVMEM provider support
From: Rob Herring (Arm) @ 2026-07-16 19:42 UTC (permalink / raw)
To: Loic Poulain
Cc: Andrew Lunn, Bjorn Andersson, linux-wireless, Johannes Berg,
daniel, linux-block, linux-mmc, Paolo Abeni, Eric Dumazet,
Conor Dooley, netdev, Balakrishna Godavarthi, Simon Horman,
Srinivas Kandagatla, Luiz Augusto von Dentz, Marcel Holtmann,
Bartosz Golaszewski, Russell King, Jens Axboe, Konrad Dybcio,
Jeff Johnson, David S. Miller, Saravana Kannan, linux-bluetooth,
Rocky Liao, Christian Marangi, Ulf Hansson, Krzysztof Kozlowski,
Heiner Kallweit, devicetree, linux-arm-msm, linux-kernel, ath10k,
Jakub Kicinski
In-Reply-To: <20260703-block-as-nvmem-v8-1-98ae32bfc49a@oss.qualcomm.com>
On Fri, 03 Jul 2026 15:45:14 +0200, Loic Poulain wrote:
> Allow an eMMC hardware partition node to describe an NVMEM layout so the
> partition can be exposed as an NVMEM provider. This lets a partition
> (e.g. an eMMC boot partition) store device-specific information such as a
> WiFi MAC address or a Bluetooth BD address and reference it through NVMEM
> cells.
>
> Accept "fixed-layout" as the partition node compatible, in addition to
> "fixed-partitions", so the layout can be described directly on the
> partition node.
>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
> .../devicetree/bindings/mmc/mmc-card.yaml | 23 +++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 net-next] net: rnpgbe: Delete a null pointer check in rnpgbe_rm_adapter()
From: Andrew Lunn @ 2026-07-16 19:40 UTC (permalink / raw)
To: Markus Elfring
Cc: netdev, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, MD Danish Anwar, Michael Grzeschik, Paolo Abeni,
Uwe Kleine-König, Vadim Fedorenko, Yibo Dong, LKML,
kernel-janitors, Dan Carpenter
In-Reply-To: <a4fe0527-6302-45dc-b4be-40282c2673b6@web.de>
On Thu, Jul 16, 2026 at 07:26:21PM +0200, Markus Elfring wrote:
> From: Markus Elfring <elfring@users.sourceforge.net>
> Date: Thu, 16 Jul 2026 19:15:06 +0200
>
> The check for the pointer “mucse” was finally identified as undesirable.
I'm not sure finally is appropriate. It was one of the first questions
i asked. Also, i expect anybody looking at a Coccinelle report to take
the time to understand the code and decide what the correct fix is. We
have too many developers doing the minimum to make the tool happy,
without actually thinking.
Please also include the reasoning behind this. The commit message is
all about "Why?" Why is it undesirable?
And lastly, please always start a new thread for a new version of the
patch.
Andrew
---
pw-bot: cr
^ permalink raw reply
* [PATCH net v2] mac802154: llsec: reject frames shorter than the authentication tag
From: Doruk Tan Ozturk @ 2026-07-16 19:34 UTC (permalink / raw)
To: alex.aring, stefan, miquel.raynal
Cc: davem, edumazet, kuba, pabeni, horms, leitao, linux-wpan, netdev,
linux-kernel, stable
llsec_do_decrypt_auth() computes the associated-data length for the
AEAD request as
assoclen += datalen - authlen;
where datalen is the number of bytes after the MAC header and authlen
(4, 8 or 16) is the length of the authentication tag. Nothing verifies
that the frame actually carries at least authlen payload bytes. A
secured frame whose payload is shorter than the tag makes
datalen - authlen negative; assoclen is then passed to
aead_request_set_ad() as an unsigned value close to 4 GiB, so
crypto_aead_decrypt() walks far off the end of the scatterlist that
only spans the real frame.
The frame is fully attacker-controlled and reaches this path from any
IEEE 802.15.4 peer in radio range. Reject frames whose payload is
shorter than the authentication tag before the subtraction.
Dynamically reproduced on a KASAN kernel as a general-protection-fault
in the AEAD scatterwalk, and the fix confirmed.
Fixes: 4c14a2fb5d14 ("mac802154: add llsec decryption method")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
v2 (Breno Leitao review):
- drop the redundant self-Reported-by.
- move the length check above sg_init_one() (datalen/authlen are
already available there).
- Assisted-by trailer -> 0sec:multi-model.
Carrying Simon Horman Reviewed-by; v2 only moves the same check earlier.
net/mac802154/llsec.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index 5e7cc11fab3a..85452ef9a58c 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -891,6 +891,11 @@ llsec_do_decrypt_auth(struct sk_buff *skb, const struct mac802154_llsec *sec,
data = skb_mac_header(skb) + skb->mac_len;
datalen = skb_tail_pointer(skb) - data;
+ if (datalen < authlen) {
+ kfree_sensitive(req);
+ return -EBADMSG;
+ }
+
sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen);
if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) {
--
2.43.0
^ permalink raw reply related
* [PATCH net v2] mac802154: llsec: reject frames shorter than the authentication tag
From: Doruk Tan Ozturk @ 2026-07-16 19:31 UTC (permalink / raw)
To: alex.aring, stefan, miquel.raynal
Cc: davem, edumazet, kuba, pabeni, horms, leitao, linux-wpan, netdev,
linux-kernel, stable
In-Reply-To: <20260709131246.44517-1-doruk@0sec.ai>
llsec_do_decrypt_auth() computes the associated-data length for the
AEAD request as
assoclen += datalen - authlen;
where datalen is the number of bytes after the MAC header and authlen
(4, 8 or 16) is the length of the authentication tag. Nothing verifies
that the frame actually carries at least authlen payload bytes. A
secured frame whose payload is shorter than the tag makes
datalen - authlen negative; assoclen is then passed to
aead_request_set_ad() as an unsigned value close to 4 GiB, so
crypto_aead_decrypt() walks far off the end of the scatterlist that
only spans the real frame.
The frame is fully attacker-controlled and reaches this path from any
IEEE 802.15.4 peer in radio range. Reject frames whose payload is
shorter than the authentication tag before the subtraction.
Dynamically reproduced on a KASAN kernel as a general-protection-fault
in the AEAD scatterwalk, and the fix confirmed.
Fixes: 4c14a2fb5d14 ("mac802154: add llsec decryption method")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
---
v2 (Breno Leitao review):
- drop the redundant self-Reported-by.
- move the length check above sg_init_one() (datalen/authlen are
already available there).
- Assisted-by trailer -> 0sec:multi-model.
Carrying Simon Horman Reviewed-by; v2 only moves the same check earlier.
net/mac802154/llsec.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c
index 5e7cc11fab3a..85452ef9a58c 100644
--- a/net/mac802154/llsec.c
+++ b/net/mac802154/llsec.c
@@ -891,6 +891,11 @@ llsec_do_decrypt_auth(struct sk_buff *skb, const struct mac802154_llsec *sec,
data = skb_mac_header(skb) + skb->mac_len;
datalen = skb_tail_pointer(skb) - data;
+ if (datalen < authlen) {
+ kfree_sensitive(req);
+ return -EBADMSG;
+ }
+
sg_init_one(&sg, skb_mac_header(skb), assoclen + datalen);
if (!(hdr->sec.level & IEEE802154_SCF_SECLEVEL_ENC)) {
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net] mac802154: llsec: reject frames shorter than the authentication tag
From: Doruk Tan Ozturk @ 2026-07-16 19:31 UTC (permalink / raw)
To: Breno Leitao
Cc: Alexander Aring, Stefan Schmidt, Miquel Raynal, davem, edumazet,
kuba, pabeni, Simon Horman, linux-wpan, netdev, linux-kernel,
stable
In-Reply-To: <20260709131246.44517-1-doruk@0sec.ai>
Will do both in v2, thanks.
-Doruk
^ permalink raw reply
* Re: [RFC PATCH net-next v0 2/6] net: fix GeoNetworking
From: Andrew Lunn @ 2026-07-16 19:28 UTC (permalink / raw)
To: Simon Dietz
Cc: simon.dietz, andrew+netdev, davem, edumazet, johannes, kuniyu,
linux-wireless, netdev
In-Reply-To: <20260716153917.3399255-1-dietz23838@hs-ansbach.de>
> drop:
> - pr_info("Packet was dropped.");
> + //pr_info("Packet was dropped.");
> kfree_skb(skb);
Don't comment it out, remove it.
And maybe think about incriminating a counter.
> @@ -1003,21 +1031,41 @@ static int gn_rcv(struct sk_buff *skb, struct net_device *dev,
>
> switch (gh->gc_h.ht) {
> case CH_HT_GUC:
> + if (!pskb_may_pull(skb, GN_BASE_HEADER_SIZE + sizeof(struct gn_guc_header) + sizeof(struct btp_header)))
> + goto drop;
The netdev coding style asks for lines to be < 80 characters long.
We also have quite a lot of #defines for lengths of various
headers. So maybe add some _HLEN macros.
Andrew
^ permalink raw reply
* Re: [PATCH v2 00/11] rust: driver: use pointers instead of indices for ID info
From: Danilo Krummrich @ 2026-07-16 19:18 UTC (permalink / raw)
To: Gary Guo, Greg Kroah-Hartman, Rafael J. Wysocki, Viresh Kumar,
Uwe Kleine-König, Michal Wilczynski, Igor Korotin,
Rob Herring
Cc: Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Daniel Almeida,
Tamir Duberstein, Alexandre Courbot, Onur Özkan,
FUJITA Tomonori, David Airlie, Simona Vetter, Bjorn Helgaas,
Krzysztof Wilczyński, Abdiel Janulgue, Robin Murphy,
Dave Ertman, Ira Weiny, Leon Romanovsky, Len Brown,
Saravana Kannan, Drew Fustini, Guo Ren, Fu Wei, driver-core,
rust-for-linux, linux-kernel, netdev, nova-gpu, dri-devel,
linux-pci, linux-acpi, devicetree, linux-pm, linux-pwm, linux-usb
In-Reply-To: <20260629-id_info-v2-0-56fccbe9c5ef@garyguo.net>
On Mon Jun 29, 2026 at 2:39 PM CEST, Gary Guo wrote:
> MAINTAINERS | 1 -
> drivers/acpi/bus.c | 6 +-
> drivers/cpufreq/rcpufreq_dt.rs | 1 -
> drivers/gpu/drm/nova/driver.rs | 1 -
> drivers/gpu/drm/tyr/driver.rs | 1 -
> drivers/gpu/nova-core/driver.rs | 3 +-
> drivers/pwm/pwm_th1520.rs | 1 -
> include/acpi/acpi_bus.h | 11 --
> rust/helpers/acpi.c | 16 ---
> rust/helpers/helpers.c | 1 -
> rust/kernel/acpi.rs | 14 +--
> rust/kernel/auxiliary.rs | 18 +--
> rust/kernel/device_id.rs | 207 +++++++++++++++++++---------------
> rust/kernel/driver.rs | 137 ++--------------------
> rust/kernel/i2c.rs | 26 ++---
> rust/kernel/net/phy.rs | 66 +----------
> rust/kernel/of.rs | 14 +--
> rust/kernel/pci.rs | 25 ++--
> rust/kernel/platform.rs | 5 +-
> rust/kernel/usb.rs | 24 ++--
> samples/rust/rust_debugfs.rs | 1 -
> samples/rust/rust_dma.rs | 3 +-
> samples/rust/rust_driver_auxiliary.rs | 4 +-
> samples/rust/rust_driver_i2c.rs | 3 -
> samples/rust/rust_driver_pci.rs | 11 +-
> samples/rust/rust_driver_platform.rs | 2 -
> samples/rust/rust_driver_usb.rs | 3 +-
> samples/rust/rust_i2c_client.rs | 2 -
> samples/rust/rust_soc.rs | 2 -
> 29 files changed, 178 insertions(+), 431 deletions(-)
I plan to pick this up soon. Please let me know in case there are any concerns
from the acpi, i2c, of, net or usb side of things.
Thanks,
Danilo
^ permalink raw reply
* Re: [RFC PATCH net-next v0 1/6] net: add GeoNetworking protocol
From: Andrew Lunn @ 2026-07-16 19:17 UTC (permalink / raw)
To: Simon Dietz
Cc: netdev, edumazet, davem, kuniyu, andrew+netdev, dietz23838,
linux-wireless, johannes
In-Reply-To: <20260716135902.2895237-2-simon.dietz@plantwatch.de>
On Thu, Jul 16, 2026 at 03:58:41PM +0200, Simon Dietz wrote:
> Implement the GeoNetworking / ETSI ITS-G5 ('net/gn') protocol which
> is based on 802.11p wifi and used for vehicle2x applications. It is
> standardized by the ETSI and used by some car manufacturers
> (especially in europe). It enables ad-hoc, multi-hop geographical
> communication and routing among vehicles (and road- or railside
> infrastructure).
I'm probably doing a deep dive too early, but ...
> +#ifdef CONFIG_PROC_FS
> +extern int gn_proc_init(void);
> +extern void gn_proc_exit(void);
> +#else
> +static inline int gn_proc_init(void)
> +{
> + return 0;
> +}
> +static inline void gn_proc_exit(void)
> +{
> +}
> +#endif /* CONFIG_PROC_FS */
Nothing new has been added to /proc for a long time. Please consider a
different interface. I've not yet looked to see what is there, but
networking now pretty much only uses netlink.
> +/* protocol-specific ioctls */
> +#define SIOCGNSPOSITION (SIOCPROTOPRIVATE + 0)
New IOCTL code is also very likely to be rejected. The functionality
should go through netlink.
> +static inline void __gn_insert_socket(struct sock *sk)
> +{
> + sk_add_node(sk, &gn_sockets);
> +}
> +
> +static inline void gn_remove_socket(struct sock *sk)
> +{
> + write_lock_bh(&gn_sockets_lock);
> + sk_del_node_init(sk);
> + write_unlock_bh(&gn_sockets_lock);
> +}
Generally, inline functions in a .c file are rejected. It is better to
let the compiler decide. The exception would be if you have a
benchmark which shows inline actually helps.
> +static struct gn_iface *gn_if_add_device(struct net_device *dev,
> + struct sockaddr_gn *sa)
> +{
> + bool was_empty;
> + struct gn_iface *gnif,
> + *new_gnif = kzalloc(sizeof(struct gn_iface), GFP_KERNEL);
> +
> + if (!new_gnif)
> + return NULL;
> +
> + new_gnif->address = sa->sgn_addr;
> + new_gnif->dev = dev;
> +
> + pr_info("Add interface %s with address %llx", dev->name,
> + new_gnif->address);
This seems like debug. At minimum, it should be _dbg(), but maybe it
should be removed altogether.
> +u32 gn_tai_to_gn(ktime_t tai_time)
> +{
> + /* unix timestamp of 01/01/2004 00:00:00 UTC and 32 leap seconds between TAI and UNIX*/
> + const ktime_t tai_offset = ms_to_ktime(1072915200000LLU + 32000LLU);
> +
> + WARN_ONCE(ktime_before(tai_time, tai_offset),
> + "timestamp %lld out of bounds", tai_time);
> + /* truncate timestamp (GN timestamp has 32 bits) */
> + return (u32)ktime_sub(tai_time, tai_offset);
I'm too lazy to do the work. When does this wrap around? Maybe add it
as a comment.
> +static int gn_autobind(struct sock *sock)
> +{
> + //BUG();
Commented out code is not something we want in the kernel.
Maybe one of your later patches fixes this. We might want to consider
squashing them, so the review is done on the final clean code.
> +static void gn_location_service_req(struct gn_iface *gnif, gn_address_t saddr,
> + gn_address_t daddr)
> +{
> + int size = 0;
> + struct sk_buff *skb;
> + struct gn_basic_header *gb_h;
> + struct gn_common_header *gc_h;
> + struct gn_ls_request_header *gls_h;
netdev uses reverse christmas tree, longest lines first, shortest
last. It should apply to all functions.
> +// table is * 1000 | p1 * 100 entry
> +static int cos_table[] = {
> + 100000, 99995, 99980, 99955, 99920, 99875, 99820, 99755, 99680,
> + 99595, 99500, 99396, 99281, 99156, 99022, 98877, 98723, 98558,
> + 98384, 98200, 98007, 97803, 97590, 97367, 97134, 96891, 96639,
> + 96377, 96106, 95824, 95534, 95233, 94924, 94604, 94275, 93937,
> + 93590, 93233, 92866, 92491, 92106, 91712, 91309, 90897, 90475,
> + 90045, 89605, 89157, 88699, 88233, 87758, 87274, 86782, 86281,
> + 85771, 85252, 84726, 84190, 83646, 83094, 82534, 81965, 81388,
> + 80803, 80210, 79608, 78999, 78382, 77757, 77125, 76484, 75836,
> + 75181, 74517, 73847, 73169, 72484, 71791, 71091, 70385, 69671,
> + 68950, 68222, 67488, 66746, 65998, 65244, 64483, 63715, 62941,
> + 62161, 61375, 60582, 59783, 58979, 58168, 57352, 56530, 55702,
> + 54869, 54030, 53186, 52337, 51482, 50622, 49757, 48887, 48012,
> + 47133, 46249, 45360, 44466, 43568, 42666, 41759, 40849, 39934,
> + 39015, 38092, 37166, 36236, 35302, 34365, 33424, 32480, 31532,
> + 30582, 29628, 28672, 27712, 26750, 25785, 24818, 23848, 22875,
> + 21901, 20924, 19945, 18964, 17981, 16997, 16010, 15023, 14033,
> + 13042, 12050, 11057, 10063, 9067, 8071, 7074, 6076, 5077,
> + 4079, 3079, 2079, 1080, 0, -920, -1920, -2920, -3919,
> + -4918, -5917, -6915, -7912, -8909, -9904, -10899, -11892, -12884,
> + -13875, -14865, -15853, -16840, -17825, -18808, -19789, -20768, -21745,
> + -22720, -23693, -24663, -25631, -26596, -27559, -28519, -29476, -30430,
> + -31381, -32329, -33274, -34215, -35153, -36087, -37018, -37945, -38868,
> + -39788, -40703, -41615, -42522, -43425, -44323, -45218, -46107, -46992,
> + -47873, -48748, -49619, -50485, -51345, -52201, -53051, -53896, -54736,
> + -55570, -56399, -57221, -58039, -58850, -59656, -60455, -61249, -62036,
> + -62817, -63592, -64361, -65123, -65879, -66628, -67370, -68106, -68834,
> + -69556, -70271, -70979, -71680, -72374, -73060, -73739, -74411, -75075,
> + -75732, -76382, -77023, -77657, -78283, -78901, -79512, -80114, -80709,
> + -81295, -81873, -82444, -83005, -83559, -84104, -84641, -85169, -85689,
> + -86200, -86703, -87197, -87682, -88158, -88626, -89085, -89534, -89975,
> + -90407, -90830, -91244, -91648, -92044, -92430, -92807, -93175, -93533,
> + -93883, -94222, -94553, -94873, -95185, -95486, -95779, -96061, -96334,
> + -96598, -96852, -97096, -97330, -97555, -97770, -97975, -98170, -98356,
> + -98531, -98697, -98853, -98999, -99135, -99262, -99378, -99484, -99581,
> + -99667, -99744, -99810, -99867, -99914, -99950, -99977, -99993, -100000
> +};
> +
> +/* icos() - look up in cos_table for a rad value.
> + * @rad : the rad value.* 10^7
> + *
> + * Return : the cosine value * 100000
> + */
> +static int icos(__s64 rad)
> +{
> + if (rad > PI)
> + rad = PI - (rad - PI);
> + return cos_table[rad / 100000];
> +}
> +
> +/* degree_to_rad() - convert a degree value to a rad value.
> +* @a : the degree value as 1/10 micro degree (10^7).
> +*
> +* Return : the rad value * 10^7.
> +*/
> +static __s64 degree_to_rad(__s64 a)
> +{
> + return (((RAD_PER_DEGREE * a) / 10000000ULL)) % (PI * 2ULL);
> +}
Not the sort of thing you normally see in the kernel. I've not looked
at the code enough to see the big picture, but generally, the kernel
routing table is static, and fed from a user space daemon. Should all
this code be in user space?
> +static void debug_loc_te(void)
> +{
> + struct loc_te *entry;
> + int bucket;
> +
> + spin_lock_bh(&gn_loc_t_lock);
> + if (hash_empty(gn_loc_t)) {
> + spin_unlock_bh(&gn_loc_t_lock);
> + return;
> + }
> +
> + pr_info("Printing location table");
> + hash_for_each(gn_loc_t, bucket, entry, hnode) {
> + pr_info("LOC_TE(%p) tst=%x addr=%llx ll_addr=%llx is_neighbour=%x ls_pending=%x",
> + entry, entry->tst_addr, be64_to_cpu(entry->addr),
> + be64_to_cpu(entry->ll_address), entry->is_neighbour,
> + entry->ls_pending);
> + }
> + spin_unlock_bh(&gn_loc_t_lock);
debugfs? a netlink dump operation?
Andrew
^ permalink raw reply
* Re: [PATCH net v3 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
From: Weiming Shi @ 2026-07-16 19:06 UTC (permalink / raw)
To: Tung Quang Nguyen
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Xiang Mei, linux-kernel@vger.kernel.org, Jon Maloy,
netdev@vger.kernel.org, tipc-discussion@lists.sourceforge.net
In-Reply-To: <GV1P189MB1988239A710C4D42F6DCA15EC6C72@GV1P189MB1988.EURP189.PROD.OUTLOOK.COM>
Tung Quang Nguyen <tung.quang.nguyen@est.tech> 于2026年7月16日周四 17:28写道:
>
> >named_distribute() ends by stamping the last_bulk flag on the tail skb via
> >buf_msg(skb_peek_tail(list)). When the publication list is empty no skb is
> >enqueued, skb_peek_tail() returns NULL, and buf_msg(NULL) is dereferenced.
> >
> >tipc_named_node_up() runs this on &nt->cluster_scope. With a node-id
> >configuration cluster_scope is populated only later by tipc_net_finalize(), so a
> >peer link that comes up first reaches named_distribute() with an empty list. It
> >is reachable by an unprivileged user (TIPC genl ops use
> >GENL_UNS_ADMIN_PERM) over a UDP bearer in a user+net namespace:
> >
> > KASAN: null-ptr-deref in range [0x00000000000000d8-0x00000000000000df]
> > RIP: 0010:tipc_named_node_up (net/tipc/name_distr.c:196)
> > tipc_named_node_up (net/tipc/name_distr.c:196 net/tipc/name_distr.c:221)
> > tipc_node_write_unlock (net/tipc/node.c:428)
> > tipc_rcv (net/tipc/node.c:2185)
> > tipc_udp_recv (net/tipc/udp_media.c:392) Kernel panic - not syncing: Fatal
> >exception in interrupt
> >
> >The peer holds back this node's later name updates until it sees a bulk with the
> >last_bulk flag, so simply skipping the empty bulk would stall it.
> >Emit an item-less bulk when the list is empty, and break out of the build loop
> >on allocation failure instead of returning, so the last_bulk flag is applied to the
> >last queued skb.
> >
> >Fixes: cad2929dc432 ("tipc: update a binding service via broadcast")
> >Reported-by: Xiang Mei <xmei5@asu.edu>
> >Assisted-by: Claude:claude-opus-4-8
> >Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> >---
> > net/tipc/name_distr.c | 16 +++++++++++++++-
> > 1 file changed, 15 insertions(+), 1 deletion(-)
> >
> >diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index
> >ba4f4906e13b..dbcfa965de34 100644
> >--- a/net/tipc/name_distr.c
> >+++ b/net/tipc/name_distr.c
> >@@ -165,7 +165,7 @@ static void named_distribute(struct net *net, struct
> >sk_buff_head *list,
> > dnode);
> > if (!skb) {
> > pr_warn("Bulk publication failure\n");
> >- return;
> >+ break;
> > }
> > hdr = buf_msg(skb);
> > msg_set_bc_ack_invalid(hdr, true);
> >@@ -192,6 +192,20 @@ static void named_distribute(struct net *net, struct
> >sk_buff_head *list,
> > skb_trim(skb, INT_H_SIZE + (msg_dsz - msg_rem));
> > __skb_queue_tail(list, skb);
> > }
> >+
> >+ if (skb_queue_empty(list)) {
> >+ skb = named_prepare_buf(net, PUBLICATION, 0, dnode);
> >+ if (!skb) {
> >+ pr_warn("Bulk publication failure\n");
> >+ return;
> >+ }
>
> This approach is wrong because:
> 1. When 'list' is empty, it is caused by memory allocation failure before. So, it is likely that 'skb' could be NULL again because of memory allocation failure.
> 2. Even if 'skb' is not NULL, allocation of non-data (zero-in-size) message will break the receiving peer when it handles this message.
>
> >+ hdr = buf_msg(skb);
> >+ msg_set_bc_ack_invalid(hdr, true);
> >+ msg_set_bulk(hdr);
> >+ msg_set_non_legacy(hdr);
> >+ __skb_queue_tail(list, skb);
> >+ }
> >+
> > hdr = buf_msg(skb_peek_tail(list));
> > msg_set_last_bulk(hdr);
> > msg_set_named_seqno(hdr, seqno);
> >--
> >2.43.0
>
Thanks for your review. Fixed and v4 sent.
^ permalink raw reply
* [PATCH net v4 2/2] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
From: Weiming Shi @ 2026-07-16 19:02 UTC (permalink / raw)
To: Jon Maloy, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: Hoang Huu Le, netdev, tipc-discussion, linux-kernel, xmei5,
Weiming Shi
In-Reply-To: <20260716190204.100895-2-bestswngs@gmail.com>
named_distribute() ends by stamping the last_bulk flag on the tail skb via
buf_msg(skb_peek_tail(list)). When the publication list is empty no skb is
enqueued, skb_peek_tail() returns NULL, and buf_msg(NULL) is dereferenced.
tipc_named_node_up() runs this on &nt->cluster_scope. With a node-id
configuration cluster_scope is populated only later by tipc_net_finalize(),
so a peer link that comes up first reaches named_distribute() with an empty
list. It is reachable by an unprivileged user (TIPC genl ops use
GENL_UNS_ADMIN_PERM) over a UDP bearer in a user+net namespace:
KASAN: null-ptr-deref in range [0x00000000000000d8-0x00000000000000df]
RIP: 0010:tipc_named_node_up (net/tipc/name_distr.c:196)
tipc_named_node_up (net/tipc/name_distr.c:196 net/tipc/name_distr.c:221)
tipc_node_write_unlock (net/tipc/node.c:428)
tipc_rcv (net/tipc/node.c:2185)
tipc_udp_recv (net/tipc/udp_media.c:392)
Kernel panic - not syncing: Fatal exception in interrupt
The peer holds back this node's later name updates until it sees a bulk
with the last_bulk flag, so simply skipping the send would stall it. Emit
an item-less bulk when the publication list is empty, so the peer still
receives the last_bulk flag and opens.
Fixes: cad2929dc432 ("tipc: update a binding service via broadcast")
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/tipc/name_distr.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index ba4f4906e13b..a8bb7bd101ea 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -192,6 +192,20 @@ static void named_distribute(struct net *net, struct sk_buff_head *list,
skb_trim(skb, INT_H_SIZE + (msg_dsz - msg_rem));
__skb_queue_tail(list, skb);
}
+
+ if (skb_queue_empty(list)) {
+ skb = named_prepare_buf(net, PUBLICATION, 0, dnode);
+ if (!skb) {
+ pr_warn("Bulk publication failure\n");
+ return;
+ }
+ hdr = buf_msg(skb);
+ msg_set_bc_ack_invalid(hdr, true);
+ msg_set_bulk(hdr);
+ msg_set_non_legacy(hdr);
+ __skb_queue_tail(list, skb);
+ }
+
hdr = buf_msg(skb_peek_tail(list));
msg_set_last_bulk(hdr);
msg_set_named_seqno(hdr, seqno);
--
2.43.0
^ permalink raw reply related
* [PATCH net v4 1/2] tipc: guard against empty list in tipc_node_xmit()
From: Weiming Shi @ 2026-07-16 19:02 UTC (permalink / raw)
To: Jon Maloy, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: Hoang Huu Le, netdev, tipc-discussion, linux-kernel, xmei5,
Weiming Shi
In-Reply-To: <20260716190204.100895-2-bestswngs@gmail.com>
tipc_node_xmit() passes @list to tipc_lxc_xmit(), which dereferences
buf_msg(skb_peek(list)) without checking, so an empty list causes a NULL
pointer dereference. named_distribute() can hand it an empty list when a
bulk allocation fails. tipc_link_xmit() was already guarded in commit
b77413446408 ("tipc: fix NULL deref in tipc_link_xmit()"); guard
tipc_node_xmit() itself so the tipc_lxc_xmit() path is covered too.
Fixes: f73b12812a3d ("tipc: improve throughput between nodes in netns")
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
net/tipc/node.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 97aa970a0d83..fc241e7b0c1f 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1695,6 +1695,9 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
int bearer_id;
int rc;
+ if (skb_queue_empty(list))
+ return 0;
+
if (in_own_node(net, dnode)) {
tipc_loopback_trace(net, list);
spin_lock_init(&list->lock);
--
2.43.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox