Re: [PATCH] ipconfig: fix use-after-free of device list after ic_close_devs()

From: Eric Dumazet

Date: Fri Oct 09 2026 - 04:04:41 EST


Le ven. 9 oct. 2026 à 09:45, Henry Martin <bsdhenrymartin@xxxxxxxxx> a écrit :
>
> ic_close_devs() kfree()s every ic_device node but leaves the static
> ic_first_dev and ic_dev pointers dangling behind. When a DHCP reply
> consists of an OFFER that is never followed by an ACK (a misbehaving
> or lossy DHCP server, or a network that drops the ACK), the boot-time
> autoconfiguration loop becomes vulnerable:
>
> 1. ic_bootp_recv() accepts the OFFER and records ic_dev = <list
> node> ("We have a winner!" state);
> 2. the retransmit round times out in ic_dynamic(), so
> ic_close_devs() frees the whole list — node included;
> 3. the dynamic retry path (try_try_again) runs ic_open_devs() and
> ic_dynamic() again; on failure it falls through ic_close_devs()
> once more, where the entry point evaluates
>
> struct net_device *selected_dev = ic_dev ? ic_dev->dev : NULL;
>
> — an 8-byte use-after-free read against the freed ic_device.
>
>
> NULL both pointers after the free loop so subsequent retry rounds
> take the clean empty-list path instead of acting on freed entries.
>
> This vulnerability was discovered by Tencent CodeBuddy Security.

This is __init code, on a boot that already failed to get a lease.
I would not call it a vulnerability.

>
> Cc: stable@xxxxxxxxxxxxxxx
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")

Wrong tag. In 2.6.12 ic_dev was a 'struct net_device *' that was only
compared, never dereferenced. The dereference came in v5.12 with:

Fixes: 46acf7bdbc72 ("Revert "net: ipv4: handle DSA enabled master
network devices"")

> Signed-off-by: Henry Martin <bsdhenrymartin@xxxxxxxxx>
> ---
> net/ipv4/ipconfig.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
> index 1b8585404a41..ac4851e59c3b 100644
> --- a/net/ipv4/ipconfig.c
> +++ b/net/ipv4/ipconfig.c
> @@ -346,6 +346,13 @@ static void __init ic_close_devs(void)
> kfree(d);
> }
> rtnl_unlock();
> +
> + /* The whole ic_device list was just kfree()'d above; clear the
> + * static pointers so retry rounds (e.g. dynamic retry after an
> + * OFFER without ACK) don't dereference them (use-after-free).
> + */
> + ic_first_dev = NULL;
> + ic_dev = NULL;
> }

The change looks correct, but the comment is not needed.

Please send a V2 (in more than 24 hours) targeting the net tree
([PATCH net v2]).

Thanks.

pw-bot: cr