* [BUG] WARNING in i2c_mux_add_adapter
@ 2026-08-28 5:49 Farhad Alemi
2026-08-30 4:13 ` [PATCH] i2c: mux: avoid WARN on benign symlink creation failures Peter Rosin
0 siblings, 1 reply; 5+ messages in thread
From: Farhad Alemi @ 2026-08-28 5:49 UTC (permalink / raw)
To: Peter Rosin, Andi Shyti; +Cc: falemi, linux-i2c, linux-kernel
Hello,
As part of the kernel research at ASU's SEFCOM
lab, we hit the crash below. Crash reports can be found here:
https://github.com/farhad-alemi/public_bug_reports/tree/main/185-warning-in-i2c-mux-add-adapter/
can't create symlink to channel 0
WARNING: drivers/i2c/i2c-mux.c:403 at
i2c_mux_add_adapter+0xcd8/0xeb0 drivers/i2c/i2c-mux.c:401, CPU#0:
syz.1.250/13052
RIP: 0010:i2c_mux_add_adapter+0xcdc/0xeb0 drivers/i2c/i2c-mux.c:401
Call Trace:
i2c_mux_add_adapter+0xcdc/0xeb0 drivers/i2c/i2c-mux.c:401
cx231xx_dev_init+0x2fb/0x1260 drivers/media/usb/cx231xx/cx231xx-core.c:1334
cx231xx_init_dev drivers/media/usb/cx231xx/cx231xx-cards.c:1450 [inline]
cx231xx_usb_probe+0xc48/0x2140 drivers/media/usb/cx231xx/cx231xx-cards.c:1819
usb_probe_interface+0x657/0xc70 drivers/usb/core/driver.c:396
really_probe+0x267/0xaf0 drivers/base/dd.c:709
device_driver_attach+0xdc/0x1d0 drivers/base/dd.c:1206
bind_store+0x1d0/0x220 drivers/base/bus.c:267
kernfs_fop_write_iter+0x2fa/0x480 fs/kernfs/file.c:352
Our reproducer.c is available upon request.
Happy to test a patch if that would help.
Regards,
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] i2c: mux: avoid WARN on benign symlink creation failures
2026-08-28 5:49 [BUG] WARNING in i2c_mux_add_adapter Farhad Alemi
@ 2026-08-30 4:13 ` Peter Rosin
2026-08-30 19:13 ` Andi Shyti
0 siblings, 1 reply; 5+ messages in thread
From: Peter Rosin @ 2026-08-30 4:13 UTC (permalink / raw)
To: Farhad Alemi; +Cc: falemi, linux-i2c, linux-kernel, Peter Rosin
WARN() is a bit harsh and causes a crash for panic-on-warn users. Degrade
the error reporting to ordinary dev_err() calls.
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Link: https://lore.kernel.org/all/CA+0ovCij3QDLRzt8CwpjBy-BbJ5Zf5SV9w9QZXz8uD3Agws31g@mail.gmail.com/
Signed-off-by: Peter Rosin <peda@lysator.liu.se>
---
Hi Farhad,
I assume this patch helps?
Cheers,
Peter
drivers/i2c/i2c-mux.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 681a201c239b..52cd8cdf2307 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -393,14 +393,18 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
}
}
- WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
- "mux_device"),
- "can't create symlink to mux device\n");
+ ret = sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
+ "mux_device");
+ if (ret)
+ dev_err(muxc->dev, "can't create symlink to mux device\n");
snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id);
- WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
- symlink_name),
- "can't create symlink to channel %u\n", chan_id);
+ ret = sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
+ symlink_name);
+ if (ret)
+ dev_err(muxc->dev,
+ "can't create symlink to channel %u\n", chan_id);
+
dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
i2c_adapter_id(&priv->adap));
--
2.55.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] i2c: mux: avoid WARN on benign symlink creation failures
2026-08-30 4:13 ` [PATCH] i2c: mux: avoid WARN on benign symlink creation failures Peter Rosin
@ 2026-08-30 19:13 ` Andi Shyti
2026-08-30 21:14 ` Peter Rosin
0 siblings, 1 reply; 5+ messages in thread
From: Andi Shyti @ 2026-08-30 19:13 UTC (permalink / raw)
To: Peter Rosin; +Cc: Farhad Alemi, falemi, linux-i2c, linux-kernel
Hi Peter,
On Sun, Aug 30, 2026 at 06:13:03AM +0200, Peter Rosin wrote:
> WARN() is a bit harsh and causes a crash for panic-on-warn users. Degrade
> the error reporting to ordinary dev_err() calls.
>
> Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
> Link: https://lore.kernel.org/all/CA+0ovCij3QDLRzt8CwpjBy-BbJ5Zf5SV9w9QZXz8uD3Agws31g@mail.gmail.com/
> Signed-off-by: Peter Rosin <peda@lysator.liu.se>
> ---
>
> Hi Farhad,
>
> I assume this patch helps?
I sent this patch for a quick test:
https://lore.kernel.org/all/20260828135950.454799-1-andi.shyti@kernel.org/
Maybe they can be taken together, as I agree not to fire a WARN()
there.
Andi
>
> Cheers,
> Peter
>
> drivers/i2c/i2c-mux.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
> index 681a201c239b..52cd8cdf2307 100644
> --- a/drivers/i2c/i2c-mux.c
> +++ b/drivers/i2c/i2c-mux.c
> @@ -393,14 +393,18 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
> }
> }
>
> - WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
> - "mux_device"),
> - "can't create symlink to mux device\n");
> + ret = sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
> + "mux_device");
> + if (ret)
> + dev_err(muxc->dev, "can't create symlink to mux device\n");
>
> snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id);
> - WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
> - symlink_name),
> - "can't create symlink to channel %u\n", chan_id);
> + ret = sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
> + symlink_name);
> + if (ret)
> + dev_err(muxc->dev,
> + "can't create symlink to channel %u\n", chan_id);
> +
> dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
> i2c_adapter_id(&priv->adap));
>
> --
> 2.55.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i2c: mux: avoid WARN on benign symlink creation failures
2026-08-30 19:13 ` Andi Shyti
@ 2026-08-30 21:14 ` Peter Rosin
2026-09-08 4:23 ` Farhad Alemi
0 siblings, 1 reply; 5+ messages in thread
From: Peter Rosin @ 2026-08-30 21:14 UTC (permalink / raw)
To: Andi Shyti; +Cc: Farhad Alemi, falemi, linux-i2c, linux-kernel
Den Sun, Aug 30, 2026 at 09:13:24PM +0200, skrev Andi Shyti:
> Hi Peter,
>
> On Sun, Aug 30, 2026 at 06:13:03AM +0200, Peter Rosin wrote:
> > WARN() is a bit harsh and causes a crash for panic-on-warn users. Degrade
> > the error reporting to ordinary dev_err() calls.
> >
> > Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
> > Link: https://lore.kernel.org/all/CA+0ovCij3QDLRzt8CwpjBy-BbJ5Zf5SV9w9QZXz8uD3Agws31g@mail.gmail.com/
> > Signed-off-by: Peter Rosin <peda@lysator.liu.se>
> > ---
> >
> > Hi Farhad,
> >
> > I assume this patch helps?
>
> I sent this patch for a quick test:
>
> https://lore.kernel.org/all/20260828135950.454799-1-andi.shyti@kernel.org/
>
> Maybe they can be taken together, as I agree not to fire a WARN()
> there.
Hi Andi,
[sorry for droping you from cc, that was unintentional]
Yes, sure! And fixing the root cause is of course always nice, good one!
Cheers,
Peter
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] i2c: mux: avoid WARN on benign symlink creation failures
2026-08-30 21:14 ` Peter Rosin
@ 2026-09-08 4:23 ` Farhad Alemi
0 siblings, 0 replies; 5+ messages in thread
From: Farhad Alemi @ 2026-09-08 4:23 UTC (permalink / raw)
To: Peter Rosin; +Cc: Andi Shyti, falemi, linux-i2c, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1258 bytes --]
Apologies for the delay in response; upon our run, the patched kernel
(your 2 patches augmented & applied on 28924df2a08f) no longer panics
on the attached reproducer.
Thanks!
On Sun, Aug 30, 2026 at 2:14 PM Peter Rosin <peda@lysator.liu.se> wrote:
>
> Den Sun, Aug 30, 2026 at 09:13:24PM +0200, skrev Andi Shyti:
> > Hi Peter,
> >
> > On Sun, Aug 30, 2026 at 06:13:03AM +0200, Peter Rosin wrote:
> > > WARN() is a bit harsh and causes a crash for panic-on-warn users. Degrade
> > > the error reporting to ordinary dev_err() calls.
> > >
> > > Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
> > > Link: https://lore.kernel.org/all/CA+0ovCij3QDLRzt8CwpjBy-BbJ5Zf5SV9w9QZXz8uD3Agws31g@mail.gmail.com/
> > > Signed-off-by: Peter Rosin <peda@lysator.liu.se>
> > > ---
> > >
> > > Hi Farhad,
> > >
> > > I assume this patch helps?
> >
> > I sent this patch for a quick test:
> >
> > https://lore.kernel.org/all/20260828135950.454799-1-andi.shyti@kernel.org/
> >
> > Maybe they can be taken together, as I agree not to fire a WARN()
> > there.
>
> Hi Andi,
>
> [sorry for droping you from cc, that was unintentional]
>
> Yes, sure! And fixing the root cause is of course always nice, good one!
>
> Cheers,
> Peter
[-- Attachment #2: reproducer.c --]
[-- Type: application/octet-stream, Size: 7012 bytes --]
/*
* Reproducer for 185-warning-in-i2c-mux-add-adapter
*/
#define _GNU_SOURCE
#include <dirent.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/usb/ch9.h>
#include <linux/usb/raw_gadget.h>
#define EP0_MAX 4096
static int raw_gadget_fd;
static const uint8_t device_descriptor[18] = {
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40, 0x72, 0x05, 0xa2, 0x58,
0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
};
static const uint8_t config_descriptor[125] = {
0x09, 0x02, 0x7d, 0x00, 0x06, 0x01, 0x00, 0x80, 0x32, 0x09, 0x09, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x01, 0x05, 0xff, 0xff,
0xff, 0x00, 0x09, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x09,
0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x82, 0x02,
0x40, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x09, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x09,
0x04, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x84, 0x02,
0x40, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0x04, 0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x09, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x09,
0x04, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x86, 0x02,
0x40, 0x00, 0x00, 0x00, 0x00,
};
static void ep0_transfer(const void *data, uint32_t len)
{
uint8_t buf[sizeof(struct usb_raw_ep_io) + EP0_MAX];
struct usb_raw_ep_io *io = (void *)buf;
io->ep = 0;
io->flags = 0;
io->length = len;
if (data)
memcpy(io->data, data, len);
/* an OUT transfer is acknowledged with EP0_READ, not EP0_WRITE */
ioctl(raw_gadget_fd, data ? USB_RAW_IOCTL_EP0_WRITE : USB_RAW_IOCTL_EP0_READ, io);
}
static void handle_control_request(const struct usb_ctrlrequest *ctrl)
{
static uint8_t vendor_reply[EP0_MAX];
const uint8_t *reply = NULL;
uint32_t reply_len = 0;
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR &&
(ctrl->wValue >> 8) == USB_DT_DEVICE) {
reply = device_descriptor;
reply_len = sizeof(device_descriptor);
} else if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR &&
(ctrl->wValue >> 8) == USB_DT_CONFIG) {
reply = config_descriptor;
reply_len = sizeof(config_descriptor);
} else if (ctrl->bRequest == USB_REQ_SET_CONFIGURATION) {
ioctl(raw_gadget_fd, USB_RAW_IOCTL_CONFIGURE, 0);
ep0_transfer(NULL, 0);
return;
}
} else if (ctrl->bRequestType & USB_DIR_IN) {
memset(vendor_reply, 0, sizeof(vendor_reply));
/* BOARD_CFG_STAT: without this initialize_cx231xx() fails and
* probe returns before the i2c mux is ever registered */
if (ctrl->bRequest == 0x0d && ctrl->wIndex == 0x0000)
vendor_reply[0] = 0x81;
/* AFE SUP_BLK_PWRDN: the value the uncapped
* "while (afe_power_status != 0x18)" loops wait for */
else if (ctrl->wIndex == 0x0008)
vendor_reply[0] = 0x18;
reply = vendor_reply;
reply_len = ctrl->wLength > EP0_MAX ? EP0_MAX : ctrl->wLength;
} else {
ep0_transfer(NULL, 0);
return;
}
if (!reply) {
ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP0_STALL, 0);
return;
}
if (reply_len > ctrl->wLength)
reply_len = ctrl->wLength;
ep0_transfer(reply, reply_len);
}
static void *gadget_event_loop(void *unused)
{
uint8_t buf[sizeof(struct usb_raw_event) + EP0_MAX];
struct usb_raw_event *event = (void *)buf;
for (;;) {
event->type = 0;
event->length = EP0_MAX;
if (ioctl(raw_gadget_fd, USB_RAW_IOCTL_EVENT_FETCH, event) < 0) {
usleep(1000);
continue;
}
if (event->type == USB_RAW_EVENT_CONTROL)
handle_control_request((struct usb_ctrlrequest *)event->data);
}
return unused;
}
static void write_sysfs(const char *sysfs_path, const char *value)
{
int sysfs_fd = open(sysfs_path, O_WRONLY);
if (sysfs_fd < 0)
return;
write(sysfs_fd, value, strlen(value));
close(sysfs_fd);
}
/* udev runs v4l_id on the video node cx231xx registers; that open races the
* failing probe's teardown and panics on an unrelated use-after-free first */
static void freeze_udev_and_v4l_id(void)
{
DIR *proc_dir = opendir("/proc");
struct dirent *proc_ent;
char comm_path[64], comm[64];
int comm_fd, comm_len;
while (proc_dir && (proc_ent = readdir(proc_dir))) {
if (atoi(proc_ent->d_name) <= 1)
continue;
snprintf(comm_path, sizeof(comm_path), "/proc/%s/comm",
proc_ent->d_name);
comm_fd = open(comm_path, O_RDONLY);
if (comm_fd < 0)
continue;
comm_len = read(comm_fd, comm, sizeof(comm) - 1);
close(comm_fd);
if (comm_len <= 0)
continue;
comm[comm_len] = 0;
if (strstr(comm, "udevd") || strstr(comm, "v4l_id"))
kill(atoi(proc_ent->d_name), SIGSTOP);
}
if (proc_dir)
closedir(proc_dir);
}
/* vivid.n_devs=64 exhausts the 256 v4l2 minors, so cx231xx's vbi node fails
* to register and probe dies before the mux is left behind */
static void unbind_vivid_to_free_v4l2_minors(void)
{
DIR *vivid_dir = opendir("/sys/bus/platform/drivers/vivid");
struct dirent *vivid_ent;
while (vivid_dir && (vivid_ent = readdir(vivid_dir))) {
if (strncmp(vivid_ent->d_name, "vivid.", 6))
continue;
write_sysfs("/sys/bus/platform/drivers/vivid/unbind",
vivid_ent->d_name);
}
if (vivid_dir)
closedir(vivid_dir);
}
int main(void)
{
struct usb_raw_init init = { .speed = USB_SPEED_HIGH };
char cx231xx_intf[32], cx231xx_intf_path[64];
pthread_t gadget_thread;
DIR *udc_dir;
struct dirent *udc_ent;
char *udc_index;
int bind_fd, waited;
/* First UDC in /sys/class/udc, e.g. "dummy_udc.2" -> driver
* "dummy_udc". dummy_hcd.N owns USB bus N+1 and has one port, so the
* device lands on "<N+1>-1" and cx231xx binds its interface 1. */
udc_dir = opendir("/sys/class/udc");
while ((udc_ent = readdir(udc_dir)) && udc_ent->d_name[0] == '.')
;
if (!udc_ent)
return 1;
strcpy((char *)init.device_name, udc_ent->d_name);
strcpy((char *)init.driver_name, udc_ent->d_name);
closedir(udc_dir);
udc_index = strrchr((char *)init.driver_name, '.');
if (udc_index)
*udc_index = 0;
snprintf(cx231xx_intf, sizeof(cx231xx_intf), "%d-1:1.1",
atoi(udc_index ? udc_index + 1 : "0") + 1);
snprintf(cx231xx_intf_path, sizeof(cx231xx_intf_path),
"/sys/bus/usb/devices/%s", cx231xx_intf);
/* cx25840 requests firmware; with udevd frozen nothing answers the
* sysfs fallback, so cap its wait instead of blocking probe for 60s */
write_sysfs("/sys/class/firmware/timeout", "1");
freeze_udev_and_v4l_id();
unbind_vivid_to_free_v4l2_minors();
raw_gadget_fd = open("/dev/raw-gadget", O_RDWR);
ioctl(raw_gadget_fd, USB_RAW_IOCTL_INIT, &init);
ioctl(raw_gadget_fd, USB_RAW_IOCTL_RUN, 0);
pthread_create(&gadget_thread, NULL, gadget_event_loop, NULL);
for (waited = 0; waited < 200 && access(cx231xx_intf_path, F_OK); waited++)
usleep(50000);
if (waited == 200)
return 1;
sleep(2);
bind_fd = open("/sys/bus/usb/drivers/cx231xx/bind", O_WRONLY);
write(bind_fd, cx231xx_intf, strlen(cx231xx_intf) + 1);
return 0;
}
[-- Attachment #3: 185.patch --]
[-- Type: application/octet-stream, Size: 1367 bytes --]
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c 2026-09-07 20:37:29.899298822 -0700
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c 2026-09-07 20:37:29.925367165 -0700
@@ -1826,7 +1826,7 @@
retval = cx231xx_init_v4l2(dev, udev, interface, isoc_pipe);
if (retval)
- goto err_init;
+ goto err_video_alt;
if (dev->current_pcb_config.ts1_source != 0xff) {
/* compute alternate max packet sizes for TS1 */
--- a/drivers/i2c/i2c-mux.c 2026-09-07 20:38:37.342164915 -0700
+++ b/drivers/i2c/i2c-mux.c 2026-09-07 20:38:37.363805542 -0700
@@ -393,14 +393,18 @@
}
}
- WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
- "mux_device"),
- "can't create symlink to mux device\n");
+ ret = sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
+ "mux_device");
+ if (ret)
+ dev_err(muxc->dev, "can't create symlink to mux device\n");
snprintf(symlink_name, sizeof(symlink_name), "channel-%u", chan_id);
- WARN(sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
- symlink_name),
- "can't create symlink to channel %u\n", chan_id);
+ ret = sysfs_create_link(&muxc->dev->kobj, &priv->adap.dev.kobj,
+ symlink_name);
+ if (ret)
+ dev_err(muxc->dev,
+ "can't create symlink to channel %u\n", chan_id);
+
dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
i2c_adapter_id(&priv->adap));
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-08 4:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-28 5:49 [BUG] WARNING in i2c_mux_add_adapter Farhad Alemi
2026-08-30 4:13 ` [PATCH] i2c: mux: avoid WARN on benign symlink creation failures Peter Rosin
2026-08-30 19:13 ` Andi Shyti
2026-08-30 21:14 ` Peter Rosin
2026-09-08 4:23 ` Farhad Alemi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.