From: Liu Chao <liuc63@xiaopeng.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
khtsai@google.com, fangxy@xiaopeng.com,
Randy Dunlap <rdunlap@infradead.org>,
dbrownell@users.sourceforge.net, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: [PATCH v2 2/2] usb: gadget: u_ether: fix out-of-bounds read in get_ether_addr
Date: Wed, 4 Nov 2026 10:50:58 +0800 [thread overview]
Message-ID: <20261104025058.2650911-3-liuc63@xiaopeng.com> (raw)
In-Reply-To: <20261104025058.2650911-1-liuc63@xiaopeng.com>
get_ether_addr() walks the MAC address string with a fixed six iteration
loop, calling hex_to_bin() twice per iteration, and never checks for the
terminating NUL. A short string therefore makes it read past the end of
the buffer. The dev_addr and host_addr module parameters of the legacy
gadget drivers are copied into their own kmalloc'ed buffer by
param_set_charp(), so the overrun crosses a slab boundary and KASAN
reports it at insmod time:
# insmod g_ether.ko dev_addr=ab
BUG: KASAN: slab-out-of-bounds in get_ether_addr+0x1ec/0x230
Read of size 1 at addr ffff888009f91f53 by task insmod/70
...
get_ether_addr+0x1ec/0x230
gether_set_dev_addr+0x6b/0x180
eth_bind+0xfd/0x3b0 [g_ether]
composite_bind+0x1bb/0x7b0
gadget_bind_driver+0x229/0xb00
...
Allocated by task 70:
__kmalloc_noprof+0x1d1/0x4a0
param_set_charp+0x4a/0x220
parse_args+0x267/0x5c0
load_module+0x4f6a/0x6600
...
The buggy address is located 0 bytes to the right of
allocated 19-byte region [ffff888009f91f40, ffff888009f91f53)
Besides reading past the end of the string, the loop ignores what
hex_to_bin() returns: it yields -1 for a character that is not a hex
digit, and that value is shifted and OR'ed into dev_addr unchecked, so a
malformed address can be accepted as a valid one and the interface comes
up with an address that nobody asked for:
# insmod g_ether.ko dev_addr=aazz:cc:dd:ee:ff
# cat /sys/class/net/usb0/address
aa:ff:cc:dd:ee:ff
The configfs dev_addr and host_addr attributes of the ECM and NCM
functions reach the same parser through gether_set_dev_addr() and
gether_set_host_addr(). Their store handler passes the page-sized
configfs buffer straight on, so an overrun there stays inside the same
object and is never reported, but a malformed address is silently
accepted all the same.
Replace the open coded loop with parse_mac_pton(), which checks the
length and every digit before writing anything to dev_addr, and keep the
existing eth_random_addr() fallback for all failures.
Note that this makes the accepted syntax stricter: the old loop also took
a separator-less string such as "aabbccddeeff" and the Cisco notation
"aabb.ccdd.eeff", both of which parse_mac_pton() rejects, so such input
now falls back to a random address instead of being parsed.
Select GENERIC_NET_UTILS so that parse_mac_pton() is built in.
Fixes: 2b3d942c4878 ("usb ethernet gadget: split out network core")
Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Liu Chao <liuc63@xiaopeng.com>
---
v2: rework on top of parse_mac_pton() instead of open coding the bounds
drivers/usb/gadget/Kconfig | 1 +
drivers/usb/gadget/function/u_ether.c | 14 +++-----------
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 76521555e3c1..b83c42be686b 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,7 @@ config USB_U_SERIAL
config USB_U_ETHER
tristate
+ select GENERIC_NET_UTILS
config USB_U_AUDIO
tristate
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 59d85d6a84a8..26471cb086b3 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -686,18 +686,10 @@ static int eth_stop(struct net_device *net)
static int get_ether_addr(const char *str, u8 *dev_addr)
{
if (str) {
- unsigned i;
+ bool valid;
- for (i = 0; i < 6; i++) {
- unsigned char num;
-
- if ((*str == '.') || (*str == ':'))
- str++;
- num = hex_to_bin(*str++) << 4;
- num |= hex_to_bin(*str++);
- dev_addr [i] = num;
- }
- if (is_valid_ether_addr(dev_addr))
+ valid = parse_mac_pton(str, dev_addr, ".:");
+ if (valid && is_valid_ether_addr(dev_addr))
return 0;
}
eth_random_addr(dev_addr);
--
2.50.1
prev parent reply other threads:[~2026-11-04 2:51 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 2:50 [PATCH v2 0/2] " Liu Chao
2026-11-04 2:50 ` [PATCH v2 1/2] lib/net_utils: allow mac_pton() to take a custom delimiter Liu Chao
2026-11-04 2:50 ` Liu Chao [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104025058.2650911-3-liuc63@xiaopeng.com \
--to=liuc63@xiaopeng.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@intel.com \
--cc=davem@davemloft.net \
--cc=dbrownell@users.sourceforge.net \
--cc=edumazet@kernel.org \
--cc=fangxy@xiaopeng.com \
--cc=gregkh@linuxfoundation.org \
--cc=horms@kernel.org \
--cc=khtsai@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=rdunlap@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®