From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 1662cea4623f75d8251adf07370bbaa958f0355d ]
Inject fault while loading module, kset_register() may fail. If it fails, the kset.kobj.name allocated by kobject_set_name() which must be called before a call to kset_register() may be leaked, since refcount of kobj was set in kset_init().
To mitigate this, we free the name in kset_register() when an error is encountered, i.e. when kset_register() returns an error.
A kset may be embedded in a larger structure which may be dynamically allocated in callers, it needs to be freed in ktype.release() or error path in callers, in this case, we can not call kset_put() in kset_register(), or it will cause double free, so just call kfree_const() to free the name and set it to NULL to avoid accessing bad pointer in callers.
With this fix, the callers don't need care about freeing the name and may call kset_put() if kset_register() fails.
Suggested-by: Luben Tuikov luben.tuikov@amd.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: luben.tuikov@amd.com Link: https://lore.kernel.org/r/20221025071549.1280528-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kobject.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/kobject.c b/lib/kobject.c index bbbb067de8ec..be01d49abb62 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -806,6 +806,9 @@ EXPORT_SYMBOL_GPL(kobj_sysfs_ops); /** * kset_register - initialize and add a kset. * @k: kset. + * + * NOTE: On error, the kset.kobj.name allocated by() kobj_set_name() + * is freed, it can not be used any more. */ int kset_register(struct kset *k) { @@ -816,8 +819,12 @@ int kset_register(struct kset *k)
kset_init(k); err = kobject_add_internal(&k->kobj); - if (err) + if (err) { + kfree_const(k->kobj.name); + /* Set it to NULL to avoid accessing bad pointer in callers. */ + k->kobj.name = NULL; return err; + } kobject_uevent(&k->kobj, KOBJ_ADD); return 0; }
From: Sascha Hauer s.hauer@pengutronix.de
[ Upstream commit 321b59870f850a10dbb211ecd2bd87b41497ea6f ]
The UDC is not a suitable parent of the net device as the UDC can change or vanish during the lifecycle of the ethernet gadget. This can be illustrated with the following:
mkdir -p /sys/kernel/config/usb_gadget/mygadget cd /sys/kernel/config/usb_gadget/mygadget mkdir -p configs/c.1/strings/0x409 echo "C1:Composite Device" > configs/c.1/strings/0x409/configuration mkdir -p functions/ecm.usb0 ln -s functions/ecm.usb0 configs/c.1/ echo "dummy_udc.0" > UDC rmmod dummy_hcd
The 'rmmod' removes the UDC from the just created gadget, leaving the still existing net device with a no longer existing parent.
Accessing the ethernet device with commands like:
ip --details link show usb0
will result in a KASAN splat:
================================================================== BUG: KASAN: use-after-free in if_nlmsg_size+0x3e8/0x528 Read of size 4 at addr c5c84754 by task ip/357
CPU: 3 PID: 357 Comm: ip Not tainted 6.1.0-rc3-00013-gd14953726b24-dirty #324 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x58/0x70 dump_stack_lvl from print_report+0x134/0x4d4 print_report from kasan_report+0x78/0x10c kasan_report from if_nlmsg_size+0x3e8/0x528 if_nlmsg_size from rtnl_getlink+0x2b4/0x4d0 rtnl_getlink from rtnetlink_rcv_msg+0x1f4/0x674 rtnetlink_rcv_msg from netlink_rcv_skb+0xb4/0x1f8 netlink_rcv_skb from netlink_unicast+0x294/0x478 netlink_unicast from netlink_sendmsg+0x328/0x640 netlink_sendmsg from ____sys_sendmsg+0x2a4/0x3b4 ____sys_sendmsg from ___sys_sendmsg+0xc8/0x12c ___sys_sendmsg from sys_sendmsg+0xa0/0x120 sys_sendmsg from ret_fast_syscall+0x0/0x1c
Solve this by not setting the parent of the ethernet device.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de Link: https://lore.kernel.org/r/20221104131031.850850-2-s.hauer@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/u_ether.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 5d72872310e7..3c8dab71ba47 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -796,7 +796,6 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, net->ethtool_ops = &ops;
dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type);
status = register_netdev(net); @@ -864,8 +863,6 @@ int gether_register_netdev(struct net_device *net) struct sockaddr sa; int status;
- if (!net->dev.parent) - return -EINVAL; dev = netdev_priv(net); g = dev->gadget; status = register_netdev(net); @@ -901,7 +898,6 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g)
dev = netdev_priv(net); dev->gadget = g; - SET_NETDEV_DEV(net, &g->dev); } EXPORT_SYMBOL_GPL(gether_set_gadget);
From: Shuah Khan skhan@linuxfoundation.org
[ Upstream commit dd65a243a915ca319ed5fee9161a168c836fa2f2 ]
Fix v_recv_cmd_submit() to use PIPE_BULK define instead of hard coded values. This also fixes the following signed integer overflow error reported by cppcheck. This is not an issue since pipe is unsigned int. However, this change improves the code to use proper define.
drivers/usb/usbip/vudc_rx.c:152:26: error: Signed integer overflow for expression '3<<30'. [integerOverflow] urb_p->urb->pipe &= ~(3 << 30);
In addition, add a build time check for PIPE_BULK != 3 as the code path depends on PIPE_BULK = 3.
Signed-off-by: Shuah Khan skhan@linuxfoundation.org Link: https://lore.kernel.org/r/20221110194738.38514-1-skhan@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/usbip/vudc_rx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c index d020e72b3122..7c5d09ee3ef8 100644 --- a/drivers/usb/usbip/vudc_rx.c +++ b/drivers/usb/usbip/vudc_rx.c @@ -161,7 +161,9 @@ static int v_recv_cmd_submit(struct vudc *udc, urb_p->urb->status = -EINPROGRESS;
/* FIXME: more pipe setup to please usbip_common */ - urb_p->urb->pipe &= ~(3 << 30); + BUILD_BUG_ON_MSG(PIPE_BULK != 3, "PIPE_* doesn't range from 0 to 3"); + + urb_p->urb->pipe &= ~(PIPE_BULK << 30); switch (urb_p->ep->type) { case USB_ENDPOINT_XFER_BULK: urb_p->urb->pipe |= (PIPE_BULK << 30);
From: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com
[ Upstream commit 7dfb216eda99bbfc2a8c3b03d2eec63314f52b3c ]
In our tests we get UBSAN warning coming from ACPI parser. This is caused by trying to resolve operands when there is none.
[ 0.000000] Linux version 5.15.0-rc3chromeavsrel1.0.184+ (root@...) (gcc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1 SMP PREEMPT Sat Oct 16 00:08:27 UTC 2021 ... [ 14.719508] ================================================================================ [ 14.719551] UBSAN: array-index-out-of-bounds in /.../linux/drivers/acpi/acpica/dswexec.c:401:12 [ 14.719594] index -1 is out of range for type 'acpi_operand_object *[9]' [ 14.719621] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.15.0-rc3chromeavsrel1.0.184+ #1 [ 14.719657] Hardware name: Intel Corp. Geminilake/GLK RVP2 LP4SD (07), BIOS GELKRVPA.X64.0214.B50.2009111159 09/11/2020 [ 14.719694] Call Trace: [ 14.719712] dump_stack_lvl+0x38/0x49 [ 14.719749] dump_stack+0x10/0x12 [ 14.719775] ubsan_epilogue+0x9/0x45 [ 14.719801] __ubsan_handle_out_of_bounds.cold+0x44/0x49 [ 14.719835] acpi_ds_exec_end_op+0x1d7/0x6b5 [ 14.719870] acpi_ps_parse_loop+0x942/0xb34 ...
Problem happens because WalkState->NumOperands is 0 and it is used when trying to access into operands table. Actual code is: WalkState->Operands [WalkState->NumOperands -1] which causes out of bound access. Improve the check before above access to check if ACPI opcode should have any arguments (operands) at all.
Link: https://github.com/acpica/acpica/pull/745 Signed-off-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Reviewed-by: Cezary Rojewski cezary.rojewski@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpica/dswexec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 438597cf6cc5..7ddaa5ef9b3f 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -416,9 +416,11 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
/* * All opcodes require operand resolution, with the only exceptions - * being the object_type and size_of operators. + * being the object_type and size_of operators as well as opcodes that + * take no arguments. */ - if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) { + if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE) && + (walk_state->op_info->flags & AML_HAS_ARGS)) {
/* Resolve all operands */
linux-stable-mirror@lists.linaro.org