[PATCH v3] kthread_worker: Prevent queuing delayed work from timer_fn when it is being canceled
From: Zqiang There is a small race window when a delayed work is being canceled and the work still might be queued from the timer_fn: CPU0CPU1 kthread_cancel_delayed_work_sync() __kthread_cancel_work_sync() __kthread_cancel_work() work->canceling++; kthread_delayed_work_timer_fn() kthread_insert_work(); BUG: kthread_insert_work() should not get called when work->canceling is set. Reviewed-by: Petr Mladek Signed-off-by: Zqiang --- v1->v2->v3: Change the description of the problem and add 'Reviewed-by' tags. kernel/kthread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 3edaa380dc7b..85a2c9b32049 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -897,7 +897,8 @@ void kthread_delayed_work_timer_fn(struct timer_list *t) /* Move the work from worker->delayed_work_list. */ WARN_ON_ONCE(list_empty(&work->node)); list_del_init(&work->node); - kthread_insert_work(worker, work, &worker->work_list); + if (!work->canceling) + kthread_insert_work(worker, work, &worker->work_list); raw_spin_unlock_irqrestore(&worker->lock, flags); } -- 2.17.1
[PATCH v2] kernel/kthread.c: kthread_worker: add work status check in timer_fn
From: Zqiang When queue delayed work to worker, at some point after that the timer_fn will be call, add work to worker's work_list, at this time, the work may be cancel, so add "work->canceling" check current work status. Signed-off-by: Zqiang --- v1->v2: Change description information. kernel/kthread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 3edaa380dc7b..85a2c9b32049 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -897,7 +897,8 @@ void kthread_delayed_work_timer_fn(struct timer_list *t) /* Move the work from worker->delayed_work_list. */ WARN_ON_ONCE(list_empty(&work->node)); list_del_init(&work->node); - kthread_insert_work(worker, work, &worker->work_list); + if (!work->canceling) + kthread_insert_work(worker, work, &worker->work_list); raw_spin_unlock_irqrestore(&worker->lock, flags); } -- 2.17.1
[PATCH] kernel/kthread.c: kthread_worker: add work status check in timer_fn
From: Zqiang When queue delayed work to worker, at some point after that the timer_fn will be call, add work to worker's work_list, at this time, the work may be cancel, so add "queuing_blocked" check current work status. Signed-off-by: Zqiang --- kernel/kthread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 3edaa380dc7b..85a2c9b32049 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -897,7 +897,8 @@ void kthread_delayed_work_timer_fn(struct timer_list *t) /* Move the work from worker->delayed_work_list. */ WARN_ON_ONCE(list_empty(&work->node)); list_del_init(&work->node); - kthread_insert_work(worker, work, &worker->work_list); + if (!work->canceling) + kthread_insert_work(worker, work, &worker->work_list); raw_spin_unlock_irqrestore(&worker->lock, flags); } -- 2.17.1
[PATCH v4] debugobjects: install CPU hotplug callback
From: Zqiang Due to CPU hotplug, it may never be online after it's offline, some objects in percpu pool is never free. in order to avoid this happening, install CPU hotplug callback, call this callback func to free objects in percpu pool when CPU going offline. Signed-off-by: Zqiang Acked-by: Waiman Long Cc: Andrew Morton Cc: "Joel Fernandes (Google)" Cc: Qian Cai --- v1->v2: Modify submission information. v2->v3: In CPU hotplug callback func, add clear percpu pool "obj_free" operation. capitalize 'CPU', and use shorter preprocessor sequence. v3->v4: Add Cc and Acked-by tags include/linux/cpuhotplug.h | 1 + lib/debugobjects.c | 24 2 files changed, 25 insertions(+) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 3215023d4852..0c39d57e5342 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -36,6 +36,7 @@ enum cpuhp_state { CPUHP_X86_MCE_DEAD, CPUHP_VIRT_NET_DEAD, CPUHP_SLUB_DEAD, + CPUHP_DEBUG_OBJ_DEAD, CPUHP_MM_WRITEBACK_DEAD, CPUHP_MM_VMSTAT_DEAD, CPUHP_SOFTIRQ_DEAD, diff --git a/lib/debugobjects.c b/lib/debugobjects.c index fe4557955d97..bb69a02c3e7b 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -433,6 +434,24 @@ static void free_object(struct debug_obj *obj) } } +#ifdef CONFIG_HOTPLUG_CPU +static int object_cpu_offline(unsigned int cpu) +{ + struct debug_percpu_free *percpu_pool; + struct hlist_node *tmp; + struct debug_obj *obj; + + percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); + hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { + hlist_del(&obj->node); + kmem_cache_free(obj_cache, obj); + } + percpu_pool->obj_free = 0; + + return 0; +} +#endif + /* * We run out of memory. That means we probably have tons of objects * allocated. @@ -1367,6 +1386,11 @@ void __init debug_objects_mem_init(void) } else debug_objects_selftest(); +#ifdef CONFIG_HOTPLUG_CPU + cpuhp_setup_state_nocalls(CPUHP_DEBUG_OBJ_DEAD, "object:offline", NULL, + object_cpu_offline); +#endif + /* * Increase the thresholds for allocating and freeing objects * according to the number of possible CPUs available in the system. -- 2.17.1
[PATCH v4] debugobjects: install CPU hotplug callback
From: Zqiang Due to CPU hotplug, it may never be online after it's offline, some objects in percpu pool is never free. in order to avoid this happening, install CPU hotplug callback, call this callback func to free objects in percpu pool when CPU going offline. Signed-off-by: Zqiang Acked-by: Waiman Long Cc: Andrew Morton Cc: "Joel Fernandes (Google)" Cc: Qian Cai --- v1->v2: Modify submission information. v2->v3: In CPU hotplug callback func, add clear percpu pool "obj_free" operation. capitalize 'CPU', and use shorter preprocessor sequence. v3->v4: Add Cc and Acked-by tags include/linux/cpuhotplug.h | 1 + lib/debugobjects.c | 24 2 files changed, 25 insertions(+) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 3215023d4852..0c39d57e5342 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -36,6 +36,7 @@ enum cpuhp_state { CPUHP_X86_MCE_DEAD, CPUHP_VIRT_NET_DEAD, CPUHP_SLUB_DEAD, + CPUHP_DEBUG_OBJ_DEAD, CPUHP_MM_WRITEBACK_DEAD, CPUHP_MM_VMSTAT_DEAD, CPUHP_SOFTIRQ_DEAD, diff --git a/lib/debugobjects.c b/lib/debugobjects.c index fe4557955d97..bb69a02c3e7b 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -433,6 +434,24 @@ static void free_object(struct debug_obj *obj) } } +#ifdef CONFIG_HOTPLUG_CPU +static int object_cpu_offline(unsigned int cpu) +{ + struct debug_percpu_free *percpu_pool; + struct hlist_node *tmp; + struct debug_obj *obj; + + percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); + hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { + hlist_del(&obj->node); + kmem_cache_free(obj_cache, obj); + } + percpu_pool->obj_free = 0; + + return 0; +} +#endif + /* * We run out of memory. That means we probably have tons of objects * allocated. @@ -1367,6 +1386,11 @@ void __init debug_objects_mem_init(void) } else debug_objects_selftest(); +#ifdef CONFIG_HOTPLUG_CPU + cpuhp_setup_state_nocalls(CPUHP_DEBUG_OBJ_DEAD, "object:offline", NULL, + object_cpu_offline); +#endif + /* * Increase the thresholds for allocating and freeing objects * according to the number of possible CPUs available in the system. -- 2.17.1
[PATCH] btrfs: Fix missing close devices
From: Zqiang When the btrfs fill super error, we should first close devices and then call deactivate_locked_super func to free fs_info. Signed-off-by: Zqiang --- fs/btrfs/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8840a4fa81eb..3bfd54e8f388 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1675,6 +1675,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); security_free_mnt_opts(&new_sec_opts); if (error) { + btrfs_close_devices(fs_devices); deactivate_locked_super(s); return ERR_PTR(error); } -- 2.17.1
[PATCH] btrfs: Fix missing close devices
From: Zqiang When the btrfs fill super error, we should first close devices and then call deactivate_locked_super func to free fs_info. Signed-off-by: Zqiang --- fs/btrfs/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8840a4fa81eb..3bfd54e8f388 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1675,6 +1675,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); security_free_mnt_opts(&new_sec_opts); if (error) { + btrfs_close_devices(fs_devices); deactivate_locked_super(s); return ERR_PTR(error); } -- 2.17.1
[PATCH v3] debugobjects: install CPU hotplug callback
From: Zqiang Due to CPU hotplug, it may never be online after it's offline, some objects in percpu pool is never free. in order to avoid this happening, install CPU hotplug callback, call this callback func to free objects in percpu pool when CPU going offline. Signed-off-by: Zqiang --- v1->v2: Modify submission information. v2->v3: In CPU hotplug callback func, add clear percpu pool "obj_free" operation. capitalize 'CPU', and use shorter preprocessor sequence. include/linux/cpuhotplug.h | 1 + lib/debugobjects.c | 24 2 files changed, 25 insertions(+) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 3215023d4852..0c39d57e5342 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -36,6 +36,7 @@ enum cpuhp_state { CPUHP_X86_MCE_DEAD, CPUHP_VIRT_NET_DEAD, CPUHP_SLUB_DEAD, + CPUHP_DEBUG_OBJ_DEAD, CPUHP_MM_WRITEBACK_DEAD, CPUHP_MM_VMSTAT_DEAD, CPUHP_SOFTIRQ_DEAD, diff --git a/lib/debugobjects.c b/lib/debugobjects.c index fe4557955d97..bb69a02c3e7b 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -433,6 +434,24 @@ static void free_object(struct debug_obj *obj) } } +#ifdef CONFIG_HOTPLUG_CPU +static int object_cpu_offline(unsigned int cpu) +{ + struct debug_percpu_free *percpu_pool; + struct hlist_node *tmp; + struct debug_obj *obj; + + percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); + hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { + hlist_del(&obj->node); + kmem_cache_free(obj_cache, obj); + } + percpu_pool->obj_free = 0; + + return 0; +} +#endif + /* * We run out of memory. That means we probably have tons of objects * allocated. @@ -1367,6 +1386,11 @@ void __init debug_objects_mem_init(void) } else debug_objects_selftest(); +#ifdef CONFIG_HOTPLUG_CPU + cpuhp_setup_state_nocalls(CPUHP_DEBUG_OBJ_DEAD, "object:offline", NULL, + object_cpu_offline); +#endif + /* * Increase the thresholds for allocating and freeing objects * according to the number of possible CPUs available in the system. -- 2.17.1
[PATCH v2] debugobjects: install cpu hotplug callback
From: Zqiang Due to cpu hotplug, it may never be online after it's offline, some objects in percpu pool is never free, in order to avoid this happening, install cpu hotplug callback, call this callback func to free objects in percpu pool when cpu going offline. Signed-off-by: Zqiang --- v1->v2: Modify submission information. include/linux/cpuhotplug.h | 1 + lib/debugobjects.c | 23 +++ 2 files changed, 24 insertions(+) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index a2710e654b64..2e77db655cfa 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -36,6 +36,7 @@ enum cpuhp_state { CPUHP_X86_MCE_DEAD, CPUHP_VIRT_NET_DEAD, CPUHP_SLUB_DEAD, + CPUHP_DEBUG_OBJ_DEAD, CPUHP_MM_WRITEBACK_DEAD, CPUHP_MM_VMSTAT_DEAD, CPUHP_SOFTIRQ_DEAD, diff --git a/lib/debugobjects.c b/lib/debugobjects.c index fe4557955d97..50e21ed0519e 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -433,6 +434,23 @@ static void free_object(struct debug_obj *obj) } } +#if defined(CONFIG_HOTPLUG_CPU) +static int object_cpu_offline(unsigned int cpu) +{ + struct debug_percpu_free *percpu_pool; + struct hlist_node *tmp; + struct debug_obj *obj; + + percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); + hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { + hlist_del(&obj->node); + kmem_cache_free(obj_cache, obj); + } + + return 0; +} +#endif + /* * We run out of memory. That means we probably have tons of objects * allocated. @@ -1367,6 +1385,11 @@ void __init debug_objects_mem_init(void) } else debug_objects_selftest(); +#if defined(CONFIG_HOTPLUG_CPU) + cpuhp_setup_state_nocalls(CPUHP_DEBUG_OBJ_DEAD, "object:offline", NULL, + object_cpu_offline); +#endif + /* * Increase the thresholds for allocating and freeing objects * according to the number of possible CPUs available in the system. -- 2.17.1
[PATCH] debugobjects: install cpu hotplug callback
From: Zqiang When a cpu going offline, we should free objects in "percpu_obj_pool" free_objs list which corresponding to this cpu. Signed-off-by: Zqiang --- include/linux/cpuhotplug.h | 1 + lib/debugobjects.c | 23 +++ 2 files changed, 24 insertions(+) diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index a2710e654b64..2e77db655cfa 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -36,6 +36,7 @@ enum cpuhp_state { CPUHP_X86_MCE_DEAD, CPUHP_VIRT_NET_DEAD, CPUHP_SLUB_DEAD, + CPUHP_DEBUG_OBJ_DEAD, CPUHP_MM_WRITEBACK_DEAD, CPUHP_MM_VMSTAT_DEAD, CPUHP_SOFTIRQ_DEAD, diff --git a/lib/debugobjects.c b/lib/debugobjects.c index fe4557955d97..50e21ed0519e 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -433,6 +434,23 @@ static void free_object(struct debug_obj *obj) } } +#if defined(CONFIG_HOTPLUG_CPU) +static int object_cpu_offline(unsigned int cpu) +{ + struct debug_percpu_free *percpu_pool; + struct hlist_node *tmp; + struct debug_obj *obj; + + percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu); + hlist_for_each_entry_safe(obj, tmp, &percpu_pool->free_objs, node) { + hlist_del(&obj->node); + kmem_cache_free(obj_cache, obj); + } + + return 0; +} +#endif + /* * We run out of memory. That means we probably have tons of objects * allocated. @@ -1367,6 +1385,11 @@ void __init debug_objects_mem_init(void) } else debug_objects_selftest(); +#if defined(CONFIG_HOTPLUG_CPU) + cpuhp_setup_state_nocalls(CPUHP_DEBUG_OBJ_DEAD, "object:offline", NULL, + object_cpu_offline); +#endif + /* * Increase the thresholds for allocating and freeing objects * according to the number of possible CPUs available in the system. -- 2.17.1
[PATCH] rcu: shrink each possible cpu krcp
From: Zqiang Due to cpu hotplug. some cpu may be offline after call "kfree_call_rcu" func, if the shrinker is triggered at this time, we should drain each possible cpu "krcp". Signed-off-by: Zqiang --- kernel/rcu/tree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 8ce77d9ac716..619ccbb3fe4b 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3443,7 +3443,7 @@ kfree_rcu_shrink_count(struct shrinker *shrink, struct shrink_control *sc) unsigned long count = 0; /* Snapshot count of all CPUs */ - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu); count += READ_ONCE(krcp->count); @@ -3458,7 +3458,7 @@ kfree_rcu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) int cpu, freed = 0; unsigned long flags; - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { int count; struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu); @@ -3491,7 +3491,7 @@ void __init kfree_rcu_scheduler_running(void) int cpu; unsigned long flags; - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu); raw_spin_lock_irqsave(&krcp->lock, flags); -- 2.17.1
[PATCH v2] libnvdimm: KASAN: global-out-of-bounds Read in internal_create_group
From: Zqiang Because the last member of the "nvdimm_firmware_attributes" array was not assigned a null ptr, when traversal of "grp->attrs" array is out of bounds in "create_files" func. func: create_files: ->for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) -> BUG: KASAN: global-out-of-bounds in create_files fs/sysfs/group.c:43 [inline] BUG: KASAN: global-out-of-bounds in internal_create_group+0x9d8/0xb20 fs/sysfs/group.c:149 Read of size 8 at addr 8a2e4cf0 by task kworker/u17:10/959 CPU: 2 PID: 959 Comm: kworker/u17:10 Not tainted 5.8.0-syzkaller #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 Workqueue: events_unbound async_run_entry_fn Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x18f/0x20d lib/dump_stack.c:118 print_address_description.constprop.0.cold+0x5/0x497 mm/kasan/report.c:383 __kasan_report mm/kasan/report.c:513 [inline] kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530 create_files fs/sysfs/group.c:43 [inline] internal_create_group+0x9d8/0xb20 fs/sysfs/group.c:149 internal_create_groups.part.0+0x90/0x140 fs/sysfs/group.c:189 internal_create_groups fs/sysfs/group.c:185 [inline] sysfs_create_groups+0x25/0x50 fs/sysfs/group.c:215 device_add_groups drivers/base/core.c:2024 [inline] device_add_attrs drivers/base/core.c:2178 [inline] device_add+0x7fd/0x1c40 drivers/base/core.c:2881 nd_async_device_register+0x12/0x80 drivers/nvdimm/bus.c:506 async_run_entry_fn+0x121/0x530 kernel/async.c:123 process_one_work+0x94c/0x1670 kernel/workqueue.c:2269 worker_thread+0x64c/0x1120 kernel/workqueue.c:2415 kthread+0x3b5/0x4a0 kernel/kthread.c:292 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294 The buggy address belongs to the variable: nvdimm_firmware_attributes+0x10/0x40 Reported-by: syzbot+1cf0ffe61aecf46f5...@syzkaller.appspotmail.com Signed-off-by: Zqiang --- v1->v2: Modify the description of the error. drivers/nvdimm/dimm_devs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 61374def5155..b59032e0859b 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -529,6 +529,7 @@ static DEVICE_ATTR_ADMIN_RW(activate); static struct attribute *nvdimm_firmware_attributes[] = { &dev_attr_activate.attr, &dev_attr_result.attr, + NULL, }; static umode_t nvdimm_firmware_visible(struct kobject *kobj, struct attribute *a, int n) -- 2.17.1
[PATCH] libnvdimm: KASAN: global-out-of-bounds Read in internal_create_group
From: Zqiang Because the last member of the "nvdimm_firmware_attributes" array was not assigned a null ptr, when traversal of "group" array is out of bounds in "internal_create_groups" func. internal_create_groups: ->for (i = 0; groups[i]; i++) ->... BUG: KASAN: global-out-of-bounds in create_files fs/sysfs/group.c:43 [inline] BUG: KASAN: global-out-of-bounds in internal_create_group+0x9d8/0xb20 fs/sysfs/group.c:149 Read of size 8 at addr 8a2e4cf0 by task kworker/u17:10/959 CPU: 2 PID: 959 Comm: kworker/u17:10 Not tainted 5.8.0-syzkaller #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 Workqueue: events_unbound async_run_entry_fn Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x18f/0x20d lib/dump_stack.c:118 print_address_description.constprop.0.cold+0x5/0x497 mm/kasan/report.c:383 __kasan_report mm/kasan/report.c:513 [inline] kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530 create_files fs/sysfs/group.c:43 [inline] internal_create_group+0x9d8/0xb20 fs/sysfs/group.c:149 internal_create_groups.part.0+0x90/0x140 fs/sysfs/group.c:189 internal_create_groups fs/sysfs/group.c:185 [inline] sysfs_create_groups+0x25/0x50 fs/sysfs/group.c:215 device_add_groups drivers/base/core.c:2024 [inline] device_add_attrs drivers/base/core.c:2178 [inline] device_add+0x7fd/0x1c40 drivers/base/core.c:2881 nd_async_device_register+0x12/0x80 drivers/nvdimm/bus.c:506 async_run_entry_fn+0x121/0x530 kernel/async.c:123 process_one_work+0x94c/0x1670 kernel/workqueue.c:2269 worker_thread+0x64c/0x1120 kernel/workqueue.c:2415 kthread+0x3b5/0x4a0 kernel/kthread.c:292 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294 The buggy address belongs to the variable: nvdimm_firmware_attributes+0x10/0x40 Reported-by: syzbot+1cf0ffe61aecf46f5...@syzkaller.appspotmail.com Signed-off-by: Zqiang --- drivers/nvdimm/dimm_devs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index 61374def5155..b59032e0859b 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -529,6 +529,7 @@ static DEVICE_ATTR_ADMIN_RW(activate); static struct attribute *nvdimm_firmware_attributes[] = { &dev_attr_activate.attr, &dev_attr_result.attr, + NULL, }; static umode_t nvdimm_firmware_visible(struct kobject *kobj, struct attribute *a, int n) -- 2.17.1
[PATCH] ALSA: seq: KASAN: use-after-free Read in delete_and_unsubscribe_port
From: Zhang Qiang There is a potential race window,when a task acquire "src->list_mutex" write sem,traverse the linked list to find "subs" objects through parameter "info" in snd_seq_port_disconnect and then release this write sem, before this task acquire write sem again,this write sem may be acquired by another task, and get the same "subs" object through the same "info" before, it could happen "use-after-free" later, so a simple solution is to delete the object from the linked list when it is found. BUG: KASAN: use-after-free in list_empty include/linux/list.h:282 [inline] BUG: KASAN: use-after-free in delete_and_unsubscribe_port+0x8b/0x450 sound/core/seq/seq_ports.c:530 Read of size 8 at addr 888098523060 by task syz-executor.0/7202 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1f0/0x31e lib/dump_stack.c:118 print_address_description+0x66/0x5a0 mm/kasan/report.c:383 __kasan_report mm/kasan/report.c:513 [inline] kasan_report+0x132/0x1d0 mm/kasan/report.c:530 list_empty include/linux/list.h:282 [inline] delete_and_unsubscribe_port+0x8b/0x450 sound/core/seq/seq_ports.c:530 snd_seq_port_disconnect+0x568/0x610 sound/core/seq/seq_ports.c:612 snd_seq_ioctl_unsubscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1525 snd_seq_oss_midi_close+0x397/0x620 sound/core/seq/oss/seq_oss_midi.c:405 snd_seq_oss_synth_reset+0x335/0x8b0 sound/core/seq/oss/seq_oss_synth.c:406 snd_seq_oss_reset+0x5b/0x250 sound/core/seq/oss/seq_oss_init.c:435 snd_seq_oss_ioctl+0x5c2/0x1090 sound/core/seq/oss/seq_oss_ioctl.c:93 odev_ioctl+0x51/0x70 sound/core/seq/oss/seq_oss.c:174 vfs_ioctl fs/ioctl.c:48 [inline] ksys_ioctl fs/ioctl.c:753 [inline] __do_sys_ioctl fs/ioctl.c:762 [inline] __se_sys_ioctl+0xf9/0x160 fs/ioctl.c:760 do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Allocated by task 7202: save_stack mm/kasan/common.c:48 [inline] set_track mm/kasan/common.c:56 [inline] __kasan_kmalloc+0x103/0x140 mm/kasan/common.c:494 kmem_cache_alloc_trace+0x234/0x300 mm/slab.c:3551 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] snd_seq_port_connect+0x66/0x460 sound/core/seq/seq_ports.c:553 snd_seq_ioctl_subscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1484 snd_seq_oss_midi_open+0x4db/0x830 sound/core/seq/oss/seq_oss_midi.c:364 snd_seq_oss_synth_setup_midi+0x108/0x510 sound/core/seq/oss/seq_oss_synth.c:269 snd_seq_oss_open+0x899/0xe90 sound/core/seq/oss/seq_oss_init.c:261 odev_open+0x5e/0x90 sound/core/seq/oss/seq_oss.c:125 chrdev_open+0x498/0x580 fs/char_dev.c:414 do_dentry_open+0x813/0x1070 fs/open.c:828 do_open fs/namei.c:3243 [inline] path_openat+0x278d/0x37f0 fs/namei.c:3360 do_filp_open+0x191/0x3a0 fs/namei.c:3387 do_sys_openat2+0x463/0x770 fs/open.c:1179 do_sys_open fs/open.c:1195 [inline] __do_sys_openat fs/open.c:1209 [inline] __se_sys_openat fs/open.c:1204 [inline] __x64_sys_openat+0x1c8/0x1f0 fs/open.c:1204 do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 7203: save_stack mm/kasan/common.c:48 [inline] set_track mm/kasan/common.c:56 [inline] kasan_set_free_info mm/kasan/common.c:316 [inline] __kasan_slab_free+0x114/0x170 mm/kasan/common.c:455 __cache_free mm/slab.c:3426 [inline] kfree+0x10a/0x220 mm/slab.c:3757 snd_seq_port_disconnect+0x570/0x610 sound/core/seq/seq_ports.c:614 snd_seq_ioctl_unsubscribe_port+0x349/0x6c0 sound/core/seq/seq_clientmgr.c:1525 snd_seq_oss_midi_close+0x397/0x620 sound/core/seq/oss/seq_oss_midi.c:405 snd_seq_oss_synth_reset+0x335/0x8b0 sound/core/seq/oss/seq_oss_synth.c:406 snd_seq_oss_reset+0x5b/0x250 sound/core/seq/oss/seq_oss_init.c:435 snd_seq_oss_ioctl+0x5c2/0x1090 sound/core/seq/oss/seq_oss_ioctl.c:93 odev_ioctl+0x51/0x70 sound/core/seq/oss/seq_oss.c:174 vfs_ioctl fs/ioctl.c:48 [inline] ksys_ioctl fs/ioctl.c:753 [inline] __do_sys_ioctl fs/ioctl.c:762 [inline] __se_sys_ioctl+0xf9/0x160 fs/ioctl.c:760 do_syscall_64+0x73/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 The buggy address belongs to the object at 888098523000 which belongs to the cache kmalloc-128 of size 128 The buggy address is located 96 bytes inside of 128-byte region [888098523000, 888098523080) The buggy address belongs to the page: page:ea00026148c0 refcount:1 mapcount:0 mapping: index:0x0 flags: 0xfffe000200(slab) raw: 00fffe000200 ea0002613988 ea000262c648 8880aa400700 raw: 888098523000 00010010 page dumped because: kasan: bad access detected Memory state around the buggy address: 888098522f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc 888098522f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >888098523000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ 888098523080: fc fc fc fc fc fc fc
[PATCH] mm/dmapool.c: add WARN_ON() in dma_pool_destroy
From: Zhang Qiang The pool is being destroyed, all page which in the pool, should be free. if some page is still be use by somebody, we should not just output error logs, also should also add a warning message. Signed-off-by: Zhang Qiang --- mm/dmapool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/dmapool.c b/mm/dmapool.c index f9fb9bbd733e..8f4dc53dde5b 100644 --- a/mm/dmapool.c +++ b/mm/dmapool.c @@ -285,7 +285,7 @@ void dma_pool_destroy(struct dma_pool *pool) struct dma_page *page; page = list_entry(pool->page_list.next, struct dma_page, page_list); - if (is_page_busy(page)) { + if (WARN_ON(is_page_busy(page))) { if (pool->dev) dev_err(pool->dev, "dma_pool_destroy %s, %p busy\n", -- 2.26.2
[PATCH v3] mm/slab.c: add node spinlock protect in __cache_free_alien
From: Zhang Qiang for example: node0 cpu0cpu1 slab_dead_cpu >mutex_lock(&slab_mutex) >cpuup_canceledslab_dead_cpu >mask = cpumask_of_node(node) >mutex_lock(&slab_mutex) >n = get_node(cachep0, node0) >spin_lock_irq(n&->list_lock) >if (!cpumask_empty(mask)) == true >spin_unlock_irq(&n->list_lock) >goto free_slab >mutex_unlock(&slab_mutex) >cpuup_canceled >mask = cpumask_of_node(node) kmem_cache_free(cachep0 )>n = get_node(cachep0, node0) >__cache_free_alien(cachep0 ) >>spin_lock_irq(n&->list_lock) >n = get_node(cachep0, node0) >if (!cpumask_empty(mask)) == false >if (n->alien && n->alien[page_node]) >alien = n->alien >alien = n->alien[page_node]>n->alien = NULL > >spin_unlock_irq(&n->list_lock) > Due to multiple cpu offline, The same cache in a node may be operated in parallel,the "n->alien" should be protect. Fixes: 6731d4f12315 ("slab: Convert to hotplug state machine") Signed-off-by: Zhang Qiang --- v1->v2->v3: change submission information and fixes tags. mm/slab.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index a89633603b2d..290523c90b4e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -759,8 +759,10 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, n = get_node(cachep, node); STATS_INC_NODEFREES(cachep); + spin_lock(&n->list_lock); if (n->alien && n->alien[page_node]) { alien = n->alien[page_node]; + spin_unlock(&n->list_lock); ac = &alien->ac; spin_lock(&alien->lock); if (unlikely(ac->avail == ac->limit)) { @@ -769,14 +771,15 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, } ac->entry[ac->avail++] = objp; spin_unlock(&alien->lock); - slabs_destroy(cachep, &list); } else { + spin_unlock(&n->list_lock); n = get_node(cachep, page_node); spin_lock(&n->list_lock); free_block(cachep, &objp, 1, page_node, &list); spin_unlock(&n->list_lock); - slabs_destroy(cachep, &list); } + + slabs_destroy(cachep, &list); return 1; } -- 2.26.2
[PATCH v2] mm/slab.c: add node spinlock protect in __cache_free_alien
From: Zhang Qiang Due to cpu hotplug, the "cpuup_canceled" func be called, it's currently manipulating the alien cache for the canceled cpu's node and this node may be the same as the node which node's alien cache being operated in the "__cache_free_alien" func, so we should add a protect for node's alien cache in "__cache_free_alien" func. Fixes: 6731d4f12315 ("slab: Convert to hotplug state machine") Signed-off-by: Zhang Qiang --- v1->v2: change submission information and fixes tags. mm/slab.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index a89633603b2d..290523c90b4e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -759,8 +759,10 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, n = get_node(cachep, node); STATS_INC_NODEFREES(cachep); + spin_lock(&n->list_lock); if (n->alien && n->alien[page_node]) { alien = n->alien[page_node]; + spin_unlock(&n->list_lock); ac = &alien->ac; spin_lock(&alien->lock); if (unlikely(ac->avail == ac->limit)) { @@ -769,14 +771,15 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, } ac->entry[ac->avail++] = objp; spin_unlock(&alien->lock); - slabs_destroy(cachep, &list); } else { + spin_unlock(&n->list_lock); n = get_node(cachep, page_node); spin_lock(&n->list_lock); free_block(cachep, &objp, 1, page_node, &list); spin_unlock(&n->list_lock); - slabs_destroy(cachep, &list); } + + slabs_destroy(cachep, &list); return 1; } -- 2.26.2
[PATCH] mm/slab.c: add node spinlock protect in __cache_free_alien
From: Zhang Qiang We should add node spinlock protect "n->alien" which may be assigned to NULL in cpuup_canceled func. cause address access exception. Fixes: 18bf854117c6 ("slab: use get_node() and kmem_cache_node() functions") Signed-off-by: Zhang Qiang --- mm/slab.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mm/slab.c b/mm/slab.c index a89633603b2d..290523c90b4e 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -759,8 +759,10 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, n = get_node(cachep, node); STATS_INC_NODEFREES(cachep); + spin_lock(&n->list_lock); if (n->alien && n->alien[page_node]) { alien = n->alien[page_node]; + spin_unlock(&n->list_lock); ac = &alien->ac; spin_lock(&alien->lock); if (unlikely(ac->avail == ac->limit)) { @@ -769,14 +771,15 @@ static int __cache_free_alien(struct kmem_cache *cachep, void *objp, } ac->entry[ac->avail++] = objp; spin_unlock(&alien->lock); - slabs_destroy(cachep, &list); } else { + spin_unlock(&n->list_lock); n = get_node(cachep, page_node); spin_lock(&n->list_lock); free_block(cachep, &objp, 1, page_node, &list); spin_unlock(&n->list_lock); - slabs_destroy(cachep, &list); } + + slabs_destroy(cachep, &list); return 1; } -- 2.26.2
[PATCH] ceph: KASAN: use-after-free Read in ceph_mdsc_destroy
From: Zhang Qiang When the mdsc ptr is free, we should assign "thefsc->mdsc" a null ptr, in ceph_mdsc_init func. CPU: 0 PID: 15653 Comm: syz-executor.3 Not tainted 5.8.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x18f/0x20d lib/dump_stack.c:118 print_address_description.constprop.0.cold+0xae/0x436 mm/kasan/report.c:383 __kasan_report mm/kasan/report.c:513 [inline] kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530 timer_is_static_object+0x7a/0x90 kernel/time/timer.c:611 debug_object_assert_init lib/debugobjects.c:866 [inline] debug_object_assert_init+0x1df/0x2e0 lib/debugobjects.c:841 debug_timer_assert_init kernel/time/timer.c:728 [inline] debug_assert_init kernel/time/timer.c:773 [inline] del_timer+0x6d/0x110 kernel/time/timer.c:1196 try_to_grab_pending kernel/workqueue.c:1249 [inline] __cancel_work_timer+0x12d/0x700 kernel/workqueue.c:3092 ceph_mdsc_stop fs/ceph/mds_client.c:4660 [inline] ceph_mdsc_destroy+0x50/0x140 fs/ceph/mds_client.c:4679 destroy_fs_client+0x13/0x200 fs/ceph/super.c:720 ceph_get_tree+0x9e5/0x1660 fs/ceph/super.c:1110 vfs_get_tree+0x89/0x2f0 fs/super.c:1547 do_new_mount fs/namespace.c:2875 [inline] do_mount+0x1592/0x1fe0 fs/namespace.c:3200 __do_sys_mount fs/namespace.c:3410 [inline] __se_sys_mount fs/namespace.c:3387 [inline] __x64_sys_mount+0x18f/0x230 fs/namespace.c:3387 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x45c1d9 Code: Bad RIP value. RSP: 002b:7f33d2bc0c78 EFLAGS: 0246 ORIG_RAX: 00a5 RAX: ffda RBX: 0001f400 RCX: 0045c1d9 RDX: 2140 RSI: 20c0 RDI: 25c0 RBP: 0078bf50 R08: R09: R10: R11: 0246 R12: 0078bf0c R13: 7fffaad3cc8f R14: 7f33d2bc19c0 R15: 0078bf0c Allocated by task 15653: save_stack+0x1b/0x40 mm/kasan/common.c:48 set_track mm/kasan/common.c:56 [inline] __kasan_kmalloc.constprop.0+0xc2/0xd0 mm/kasan/common.c:494 kmem_cache_alloc_trace+0x14f/0x2d0 mm/slab.c:3551 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] ceph_mdsc_init+0x47/0xf10 fs/ceph/mds_client.c:4351 ceph_get_tree+0x4fe/0x1660 fs/ceph/super.c:1063 vfs_get_tree+0x89/0x2f0 fs/super.c:1547 do_new_mount fs/namespace.c:2875 [inline] do_mount+0x1592/0x1fe0 fs/namespace.c:3200 __do_sys_mount fs/namespace.c:3410 [inline] __se_sys_mount fs/namespace.c:3387 [inline] __x64_sys_mount+0x18f/0x230 fs/namespace.c:3387 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Freed by task 15653: save_stack+0x1b/0x40 mm/kasan/common.c:48 set_track mm/kasan/common.c:56 [inline] kasan_set_free_info mm/kasan/common.c:316 [inline] __kasan_slab_free+0xf5/0x140 mm/kasan/common.c:455 __cache_free mm/slab.c:3426 [inline] kfree+0x103/0x2c0 mm/slab.c:3757 ceph_mdsc_init+0xc64/0xf10 fs/ceph/mds_client.c:4422 ceph_get_tree+0x4fe/0x1660 fs/ceph/super.c:1063 vfs_get_tree+0x89/0x2f0 fs/super.c:1547 do_new_mount fs/namespace.c:2875 [inline] do_mount+0x1592/0x1fe0 fs/namespace.c:3200 __do_sys_mount fs/namespace.c:3410 [inline] __se_sys_mount fs/namespace.c:3387 [inline] __x64_sys_mount+0x18f/0x230 fs/namespace.c:3387 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 The buggy address belongs to the object at 88809e482000 which belongs to the cache kmalloc-4k of size 4096 The buggy address is located 896 bytes inside of 4096-byte region [88809e482000, 88809e483000) The buggy address belongs to the page: page:ea0002792080 refcount:1 mapcount:0 mapping: index:0x0 head:ea0002792080 order:1 compound_mapcount:0 flags: 0xfffe010200(slab|head) raw: 00fffe010200 ea0002792008 ea000241dc08 8880aa002000 raw: 88809e482000 00010001 page dumped because: kasan: bad access detected Memory state around the buggy address: 88809e482280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 88809e482300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >88809e482380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ 88809e482400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 88809e482480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb Fixes: f9009efac49c ("ceph: add dentry lease metric support") Reported-by: syzbot+b57f46d8d6ea51960...@syzkaller.appspotmail.com Signed-off-by: Zhang Qiang --- fs/ceph/mds_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a50497142e59..6d819c285b05 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -4420,6 +4420,7 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) kfree(md
[PATCH] mm/dmapool.c: add lock protect in dma_pool_destroy
From: Zhang Qiang When traversing "pool->page" linked list, to prevent possible other path operations this list, causing it to be destroyed, we should add lock protect for this list in dma_pool_destroy func. Signed-off-by: Zhang Qiang --- mm/dmapool.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mm/dmapool.c b/mm/dmapool.c index f9fb9bbd733e..f7375b25af6c 100644 --- a/mm/dmapool.c +++ b/mm/dmapool.c @@ -267,6 +267,9 @@ static void pool_free_page(struct dma_pool *pool, struct dma_page *page) void dma_pool_destroy(struct dma_pool *pool) { bool empty = false; + LIST_HEAD(discard); + struct dma_page *page,*h; + unsigned long flags; if (unlikely(!pool)) return; @@ -281,8 +284,8 @@ void dma_pool_destroy(struct dma_pool *pool) device_remove_file(pool->dev, &dev_attr_pools); mutex_unlock(&pools_reg_lock); + spin_lock_irqsave(&pool->lock, flags); while (!list_empty(&pool->page_list)) { - struct dma_page *page; page = list_entry(pool->page_list.next, struct dma_page, page_list); if (is_page_busy(page)) { @@ -297,8 +300,12 @@ void dma_pool_destroy(struct dma_pool *pool) list_del(&page->page_list); kfree(page); } else - pool_free_page(pool, page); + list_move(&page->page_list, &discard); } + spin_unlock_irqrestore(&pool->lock, flags); + + list_for_each_entry_safe(page, h, &discard, page_list) + pool_free_page(pool, page); kfree(pool); } -- 2.26.2
[PATCH v2] tipc: Don't using smp_processor_id() in preemptible code
From: Zhang Qiang CPU: 0 PID: 6801 Comm: syz-executor201 Not tainted 5.8.0-rc4-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x18f/0x20d lib/dump_stack.c:118 check_preemption_disabled+0x128/0x130 lib/smp_processor_id.c:48 tipc_aead_tfm_next net/tipc/crypto.c:402 [inline] tipc_aead_encrypt net/tipc/crypto.c:639 [inline] tipc_crypto_xmit+0x80a/0x2790 net/tipc/crypto.c:1605 tipc_bearer_xmit_skb+0x180/0x3f0 net/tipc/bearer.c:523 tipc_enable_bearer+0xb1d/0xdc0 net/tipc/bearer.c:331 __tipc_nl_bearer_enable+0x2bf/0x390 net/tipc/bearer.c:995 __tipc_nl_compat_doit net/tipc/netlink_compat.c:361 [inline] tipc_nl_compat_doit+0x440/0x640 net/tipc/netlink_compat.c:383 tipc_nl_compat_handle net/tipc/netlink_compat.c:1268 [inline] tipc_nl_compat_recv+0x4ef/0xb40 net/tipc/netlink_compat.c:1311 genl_family_rcv_msg_doit net/netlink/genetlink.c:669 [inline] genl_family_rcv_msg net/netlink/genetlink.c:714 [inline] genl_rcv_msg+0x61d/0x980 net/netlink/genetlink.c:731 netlink_rcv_skb+0x15a/0x430 net/netlink/af_netlink.c:2469 genl_rcv+0x24/0x40 net/netlink/genetlink.c:742 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:672 sys_sendmsg+0x6e8/0x810 net/socket.c:2352 ___sys_sendmsg+0xf3/0x170 net/socket.c:2406 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2439 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x4476a9 Code: Bad RIP value. RSP: 002b:7fff2b6d5168 EFLAGS: 0246 ORIG_RAX: 002e RAX: ffda RBX: Fixes: fc1b6d6de2208 ("tipc: introduce TIPC encryption & authentication") Reported-by: syzbot+263f8c0d007dc09b2...@syzkaller.appspotmail.com Signed-off-by: Zhang Qiang --- v1->v2: add fixes tags. net/tipc/crypto.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index 8c47ded2edb6..520af0afe1b3 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -399,9 +399,10 @@ static void tipc_aead_users_set(struct tipc_aead __rcu *aead, int val) */ static struct crypto_aead *tipc_aead_tfm_next(struct tipc_aead *aead) { - struct tipc_tfm **tfm_entry = this_cpu_ptr(aead->tfm_entry); + struct tipc_tfm **tfm_entry = get_cpu_ptr(aead->tfm_entry); *tfm_entry = list_next_entry(*tfm_entry, list); + put_cpu_ptr(tfm_entry); return (*tfm_entry)->tfm; } -- 2.24.1
[PATCH] tipc: Don't using smp_processor_id() in preemptible code
From: Zhang Qiang CPU: 0 PID: 6801 Comm: syz-executor201 Not tainted 5.8.0-rc4-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x18f/0x20d lib/dump_stack.c:118 check_preemption_disabled+0x128/0x130 lib/smp_processor_id.c:48 tipc_aead_tfm_next net/tipc/crypto.c:402 [inline] tipc_aead_encrypt net/tipc/crypto.c:639 [inline] tipc_crypto_xmit+0x80a/0x2790 net/tipc/crypto.c:1605 tipc_bearer_xmit_skb+0x180/0x3f0 net/tipc/bearer.c:523 tipc_enable_bearer+0xb1d/0xdc0 net/tipc/bearer.c:331 __tipc_nl_bearer_enable+0x2bf/0x390 net/tipc/bearer.c:995 __tipc_nl_compat_doit net/tipc/netlink_compat.c:361 [inline] tipc_nl_compat_doit+0x440/0x640 net/tipc/netlink_compat.c:383 tipc_nl_compat_handle net/tipc/netlink_compat.c:1268 [inline] tipc_nl_compat_recv+0x4ef/0xb40 net/tipc/netlink_compat.c:1311 genl_family_rcv_msg_doit net/netlink/genetlink.c:669 [inline] genl_family_rcv_msg net/netlink/genetlink.c:714 [inline] genl_rcv_msg+0x61d/0x980 net/netlink/genetlink.c:731 netlink_rcv_skb+0x15a/0x430 net/netlink/af_netlink.c:2469 genl_rcv+0x24/0x40 net/netlink/genetlink.c:742 netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] netlink_unicast+0x533/0x7d0 net/netlink/af_netlink.c:1329 netlink_sendmsg+0x856/0xd90 net/netlink/af_netlink.c:1918 sock_sendmsg_nosec net/socket.c:652 [inline] sock_sendmsg+0xcf/0x120 net/socket.c:672 sys_sendmsg+0x6e8/0x810 net/socket.c:2352 ___sys_sendmsg+0xf3/0x170 net/socket.c:2406 __sys_sendmsg+0xe5/0x1b0 net/socket.c:2439 do_syscall_64+0x60/0xe0 arch/x86/entry/common.c:384 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x4476a9 Code: Bad RIP value. RSP: 002b:7fff2b6d5168 EFLAGS: 0246 ORIG_RAX: 002e RAX: ffda RBX: Reported-by: syzbot+263f8c0d007dc09b2...@syzkaller.appspotmail.com Signed-off-by: Zhang Qiang --- net/tipc/crypto.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index 8c47ded2edb6..520af0afe1b3 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -399,9 +399,10 @@ static void tipc_aead_users_set(struct tipc_aead __rcu *aead, int val) */ static struct crypto_aead *tipc_aead_tfm_next(struct tipc_aead *aead) { - struct tipc_tfm **tfm_entry = this_cpu_ptr(aead->tfm_entry); + struct tipc_tfm **tfm_entry = get_cpu_ptr(aead->tfm_entry); *tfm_entry = list_next_entry(*tfm_entry, list); + put_cpu_ptr(tfm_entry); return (*tfm_entry)->tfm; } -- 2.24.1
[PATCH v4] kthread: Work could not be queued when worker being destroyed
From: Zhang Qiang Before the work is put into the queue of the worker thread, the state of the worker thread needs to be detected,because the worker thread may be in the destruction state at this time. Signed-off-by: Zhang Qiang Suggested-by: Petr Mladek Reviewed-by: Petr Mladek --- v1->v2: Add warning information for condition "!worker->task". v2->v3: Modify submission information and add "Reviewed-by" tags. v3->v4: Fix spi controller register trigger Warning. when a spi controller register, a "kthread_worker_fn" worker is created through "kthread_run" instead of "kthread_create_worker" which in this func the "worker->task" will be initialized. and then the "spi_start_queue" func queue a work to worker queue, at this time, if the worker has not begin to running, the "!worker->task" will be true, so a warning is triggered. kernel/kthread.c | 5 + 1 file changed, 5 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index bfbfa481be3a..825bd4dcdb95 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -791,6 +791,11 @@ static inline bool queuing_blocked(struct kthread_worker *worker, { lockdep_assert_held(&worker->lock); + if (kthread_should_stop()) { + WARN_ON(1); + return true; + } + return !list_empty(&work->node) || work->canceling; } -- 2.24.1
[PATCH v4] usb: gadget: function: fix missing spinlock in f_uac1_legacy
From: Zhang Qiang Add a missing spinlock protection for play_queue, because the play_queue may be destroyed when the "playback_work" work func and "f_audio_out_ep_complete" callback func operate this paly_queue at the same time. Fixes: c6994e6f067cf ("USB: gadget: add USB Audio Gadget driver") Cc: stable Signed-off-by: Zhang Qiang --- v1->v2->v3->v4: Add changelog text and Cc tags, Fixes tags. drivers/usb/gadget/function/f_uac1_legacy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 349deae7cabd..e2d7f69128a0 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -336,7 +336,9 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) /* Copy buffer is full, add it to the play_queue */ if (audio_buf_size - copy_buf->actual < req->actual) { + spin_lock_irq(&audio->lock); list_add_tail(©_buf->list, &audio->play_queue); + spin_unlock_irq(&audio->lock); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(copy_buf)) -- 2.24.1
[PATCH v3] usb: gadget: function: fix missing spinlock in f_uac1_legacy
From: Zhang Qiang Add a missing spinlock protection for play_queue, because the play_queue may be destroyed when the "playback_work" work func and "f_audio_out_ep_complete" callback func operate this paly_queue at the same time. Cc: stable Signed-off-by: Zhang Qiang --- v1->v2->v3: Add changelog text and Cc tags. drivers/usb/gadget/function/f_uac1_legacy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 349deae7cabd..e2d7f69128a0 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -336,7 +336,9 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) /* Copy buffer is full, add it to the play_queue */ if (audio_buf_size - copy_buf->actual < req->actual) { + spin_lock_irq(&audio->lock); list_add_tail(©_buf->list, &audio->play_queue); + spin_unlock_irq(&audio->lock); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(copy_buf)) -- 2.24.1
[PATCH v2] usb: gadget: function: fix missing spinlock in f_uac1_legacy
From: Zhang Qiang Add a missing spinlock protection to the add operation of the play_queue in "f_audio_out_ep_complete" function. Signed-off-by: Zhang Qiang --- v1->v2: Add missing changelog. drivers/usb/gadget/function/f_uac1_legacy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 349deae7cabd..e2d7f69128a0 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -336,7 +336,9 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) /* Copy buffer is full, add it to the play_queue */ if (audio_buf_size - copy_buf->actual < req->actual) { + spin_lock_irq(&audio->lock); list_add_tail(©_buf->list, &audio->play_queue); + spin_unlock_irq(&audio->lock); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(copy_buf)) -- 2.24.1
[PATCH v2] usb: gadget: function: fix missing spinlock in f_uac1_legacy
From: Zhang Qiang Add a missing spinlock protection to the add operation of the "audio->play_queue" in "f_audio_out_ep_complete" function. Signed-off-by: Zhang Qiang --- v1->v2: Add changelog text. drivers/usb/gadget/function/f_uac1_legacy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 349deae7cabd..e2d7f69128a0 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -336,7 +336,9 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) /* Copy buffer is full, add it to the play_queue */ if (audio_buf_size - copy_buf->actual < req->actual) { + spin_lock_irq(&audio->lock); list_add_tail(©_buf->list, &audio->play_queue); + spin_unlock_irq(&audio->lock); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(copy_buf)) -- 2.24.1
[PATCH] usb: gadget: function: fix missing spinlock in f_uac1_legacy
From: Zhang Qiang Signed-off-by: Zhang Qiang --- drivers/usb/gadget/function/f_uac1_legacy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 349deae7cabd..e2d7f69128a0 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -336,7 +336,9 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) /* Copy buffer is full, add it to the play_queue */ if (audio_buf_size - copy_buf->actual < req->actual) { + spin_lock_irq(&audio->lock); list_add_tail(©_buf->list, &audio->play_queue); + spin_unlock_irq(&audio->lock); schedule_work(&audio->playback_work); copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(copy_buf)) -- 2.24.1
[PATCH v3] kthread: Work could not be queued when worker being destroyed
From: Zhang Qiang Before the work is put into the queue of the worker thread, the state of the worker thread needs to be detected,because the worker thread may be in the destruction state at this time. Signed-off-by: Zhang Qiang Suggested-by: Petr Mladek Reviewed-by: Petr Mladek --- v1->v2: Add warning information for condition "!worker->task". v2->v3: Modify submission information and add "Reviewed-by" tags. kernel/kthread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index bfbfa481be3a..cac5184ffd86 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -791,6 +791,9 @@ static inline bool queuing_blocked(struct kthread_worker *worker, { lockdep_assert_held(&worker->lock); + if (WARN_ON(!worker->task)) + return true; + return !list_empty(&work->node) || work->canceling; } -- 2.24.1
[PATCH v2] kthread: work could not be queued when worker being destroyed
From: Zhang Qiang The "queuing_blocked" func should print warning message and returns true when the worker being destroyed. Suggested-by: Petr Mladek Signed-off-by: Zhang Qiang --- v1->v2: Add warning information for condition "!worker->task" kernel/kthread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index bfbfa481be3a..cac5184ffd86 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -791,6 +791,9 @@ static inline bool queuing_blocked(struct kthread_worker *worker, { lockdep_assert_held(&worker->lock); + if (WARN_ON(!worker->task)) + return true; + return !list_empty(&work->node) || work->canceling; } -- 2.24.1
[PATCH] kthread: work could not be queued when worker being destroyed
From: Zhang Qiang The queuing_blocked func should returns true when the worker being destroyed. Signed-off-by: Zhang Qiang --- kernel/kthread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 1166f2043e67..2ca711d0e78a 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -791,7 +791,7 @@ static inline bool queuing_blocked(struct kthread_worker *worker, { lockdep_assert_held(&worker->lock); - return !list_empty(&work->node) || work->canceling; + return !list_empty(&work->node) || work->canceling || !worker->task; } static void kthread_insert_work_sanity_check(struct kthread_worker *worker, -- 2.24.1
[PATCH] kthread: Don't cancel a work that is being cancelled
From: Zhang Qiang When canceling a work, if it is found that the work is in the cancelling state, we should directly exit the cancelled operation. Signed-off-by: Zhang Qiang --- kernel/kthread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index bfbfa481be3a..1166f2043e67 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -1103,6 +1103,9 @@ static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); + if (work->canceling) + goto out_fast; + ret = __kthread_cancel_work(work, is_dwork, &flags); if (worker->current_work != work) -- 2.24.1
[PATCH] kthread: Don't cancel a work that is being cancelled
From: Zhang Qiang When canceling a work, if it is found that the work is in the cancelling state, we should directly exit the cancelled operation. Signed-off-by: Zhang Qiang --- kernel/kthread.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/kthread.c b/kernel/kthread.c index bfbfa481be3a..1166f2043e67 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -1103,6 +1103,9 @@ static bool __kthread_cancel_work_sync(struct kthread_work *work, bool is_dwork) /* Work must not be used with >1 worker, see kthread_queue_work(). */ WARN_ON_ONCE(work->worker != worker); + if (work->canceling) + goto out_fast; + ret = __kthread_cancel_work(work, is_dwork, &flags); if (worker->current_work != work) -- 2.24.1
[PATCH] locking/percpu-rwsem: Remove WQ_FLAG_EXCLUSIVE flags
From: Zqiang Remove WQ_FLAG_EXCLUSIVE from "wq_entry.flags", using function __add_wait_queue_entry_tail_exclusive substitution. Signed-off-by: Zqiang --- kernel/locking/percpu-rwsem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c index 8bbafe3e5203..48e1c55c2e59 100644 --- a/kernel/locking/percpu-rwsem.c +++ b/kernel/locking/percpu-rwsem.c @@ -148,8 +148,8 @@ static void percpu_rwsem_wait(struct percpu_rw_semaphore *sem, bool reader) */ wait = !__percpu_rwsem_trylock(sem, reader); if (wait) { - wq_entry.flags |= WQ_FLAG_EXCLUSIVE | reader * WQ_FLAG_CUSTOM; - __add_wait_queue_entry_tail(&sem->waiters, &wq_entry); + wq_entry.flags |= reader * WQ_FLAG_CUSTOM; + __add_wait_queue_entry_tail_exclusive(&sem->waiters, &wq_entry); } spin_unlock_irq(&sem->waiters.lock); -- 2.24.1
[PATCH] usb: gadget: function: printer: The device interface is reset and should return error code
From: Zqiang After the device is disconnected from the host side, the interface of the device is reset. If the userspace operates the device again, an error code should be returned. Signed-off-by: Zqiang --- drivers/usb/gadget/function/f_printer.c | 36 + 1 file changed, 36 insertions(+) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 9c7ed2539ff7..2b45a61e4213 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -338,6 +338,11 @@ printer_open(struct inode *inode, struct file *fd) spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + return -ENODEV; + } + if (!dev->printer_cdev_open) { dev->printer_cdev_open = 1; fd->private_data = dev; @@ -430,6 +435,12 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -ENODEV; + } + /* We will use this flag later to check if a printer reset happened * after we turn interrupts back on. */ @@ -561,6 +572,12 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -ENODEV; + } + /* Check if a printer reset happens while we have interrupts on */ dev->reset_printer = 0; @@ -667,6 +684,13 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) inode_lock(inode); spin_lock_irqsave(&dev->lock, flags); + + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + inode_unlock(inode); + return -ENODEV; + } + tx_list_empty = (likely(list_empty(&dev->tx_reqs))); spin_unlock_irqrestore(&dev->lock, flags); @@ -689,6 +713,13 @@ printer_poll(struct file *fd, poll_table *wait) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return EPOLLERR | EPOLLHUP; + } + setup_rx_reqs(dev); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); @@ -722,6 +753,11 @@ printer_ioctl(struct file *fd, unsigned int code, unsigned long arg) spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + return -ENODEV; + } + switch (code) { case GADGET_GET_PRINTER_STATUS: status = (int)dev->printer_status; -- 2.24.1
[PATCH] usb: gadget: function: printer: Add gadget dev interface status judgment
From: Zqiang After the interface of gadget printer device was disabled, We should not continue operate the device. Signed-off-by: Zqiang --- drivers/usb/gadget/function/f_printer.c | 36 + 1 file changed, 36 insertions(+) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 9c7ed2539ff7..2b45a61e4213 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -338,6 +338,11 @@ printer_open(struct inode *inode, struct file *fd) spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + return -ENODEV; + } + if (!dev->printer_cdev_open) { dev->printer_cdev_open = 1; fd->private_data = dev; @@ -430,6 +435,12 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -ENODEV; + } + /* We will use this flag later to check if a printer reset happened * after we turn interrupts back on. */ @@ -561,6 +572,12 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return -ENODEV; + } + /* Check if a printer reset happens while we have interrupts on */ dev->reset_printer = 0; @@ -667,6 +684,13 @@ printer_fsync(struct file *fd, loff_t start, loff_t end, int datasync) inode_lock(inode); spin_lock_irqsave(&dev->lock, flags); + + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + inode_unlock(inode); + return -ENODEV; + } + tx_list_empty = (likely(list_empty(&dev->tx_reqs))); spin_unlock_irqrestore(&dev->lock, flags); @@ -689,6 +713,13 @@ printer_poll(struct file *fd, poll_table *wait) mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); + + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + mutex_unlock(&dev->lock_printer_io); + return EPOLLERR | EPOLLHUP; + } + setup_rx_reqs(dev); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); @@ -722,6 +753,11 @@ printer_ioctl(struct file *fd, unsigned int code, unsigned long arg) spin_lock_irqsave(&dev->lock, flags); + if (dev->interface < 0) { + spin_unlock_irqrestore(&dev->lock, flags); + return -ENODEV; + } + switch (code) { case GADGET_GET_PRINTER_STATUS: status = (int)dev->printer_status; -- 2.24.1
[PATCH v3] usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect
From: Zqiang BUG: memory leak unreferenced object 0x888055046e00 (size 256): comm "kworker/2:9", pid 2570, jiffies 4294942129 (age 1095.500s) hex dump (first 32 bytes): 00 70 04 55 80 88 ff ff 18 bb 5a 81 ff ff ff ff .p.U..Z. f5 96 78 81 ff ff ff ff 37 de 8e 81 ff ff ff ff ..x.7... backtrace: [] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [ ] slab_post_alloc_hook mm/slab.h:586 [inline] [ ] slab_alloc_node mm/slub.c:2786 [inline] [ ] slab_alloc mm/slub.c:2794 [inline] [ ] kmem_cache_alloc_trace+0x15e/0x2d0 mm/slub.c:2811 [<5c3c3381>] kmalloc include/linux/slab.h:555 [inline] [<5c3c3381>] usbtest_probe+0x286/0x19d0 drivers/usb/misc/usbtest.c:2790 [<1cec6910>] usb_probe_interface+0x2bd/0x870 drivers/usb/core/driver.c:361 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 [<3ef66004>] __device_attach_driver+0x1b6/0x240 drivers/base/dd.c:831 [ ] bus_for_each_drv+0x14e/0x1e0 drivers/base/bus.c:431 [ ] __device_attach+0x1f9/0x350 drivers/base/dd.c:897 [<838b324a>] device_initial_probe+0x1a/0x20 drivers/base/dd.c:944 [<30d501c1>] bus_probe_device+0x1e1/0x280 drivers/base/bus.c:491 [<5bd7adef>] device_add+0x131d/0x1c40 drivers/base/core.c:2504 [ ] usb_set_configuration+0xe84/0x1ab0 drivers/usb/core/message.c:2030 [ ] generic_probe+0x6a/0xe0 drivers/usb/core/generic.c:210 [<98ade0f1>] usb_probe_device+0x90/0xd0 drivers/usb/core/driver.c:266 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 Acked-by: Alan Stern Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- v1->v2: Remove Fixes field. v2->v3: Add Acked-by tags. drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 98ada1a3425c..bae88893ee8e 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2873,6 +2873,7 @@ static void usbtest_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); dev_dbg(&intf->dev, "disconnect\n"); + kfree(dev->buf); kfree(dev); } -- 2.24.1
[PATCH v2] usb: gadget: function: printer: fix use-after-free in __lock_acquire
From: Zqiang Increase the reference count of the printer dev through kref to avoid being released by other tasks when in use. BUG: KASAN: use-after-free in __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 Read of size 8 at addr 8880683b0018 by task syz-executor.0/3377 CPU: 1 PID: 3377 Comm: syz-executor.0 Not tainted 5.6.11 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x131/0x1b0 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:641 __asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135 __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 lock_acquire+0x127/0x350 kernel/locking/lockdep.c:4488 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159 printer_ioctl+0x4a/0x110 drivers/usb/gadget/function/f_printer.c:723 vfs_ioctl fs/ioctl.c:47 [inline] ksys_ioctl+0xfb/0x130 fs/ioctl.c:763 __do_sys_ioctl fs/ioctl.c:772 [inline] __se_sys_ioctl fs/ioctl.c:770 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:770 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4531a9 Code: ed 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 bb 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:7fd14ad72c78 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 0073bfa8 RCX: 004531a9 RDX: fff9 RSI: 009e RDI: 0003 RBP: 0003 R08: R09: R10: R11: 0246 R12: 004bbd61 R13: 004d0a98 R14: 7fd14ad736d4 R15: Allocated by task 2393: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] __kasan_kmalloc.constprop.3+0xa7/0xd0 mm/kasan/common.c:515 kasan_kmalloc+0x9/0x10 mm/kasan/common.c:529 kmem_cache_alloc_trace+0xfa/0x2d0 mm/slub.c:2813 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] gprinter_alloc+0xa1/0x870 drivers/usb/gadget/function/f_printer.c:1416 usb_get_function+0x58/0xc0 drivers/usb/gadget/functions.c:61 config_usb_cfg_link+0x1ed/0x3e0 drivers/usb/gadget/configfs.c:444 configfs_symlink+0x527/0x11d0 fs/configfs/symlink.c:202 vfs_symlink+0x33d/0x5b0 fs/namei.c:4201 do_symlinkat+0x11b/0x1d0 fs/namei.c:4228 __do_sys_symlinkat fs/namei.c:4242 [inline] __se_sys_symlinkat fs/namei.c:4239 [inline] __x64_sys_symlinkat+0x73/0xb0 fs/namei.c:4239 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 3368: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] kasan_set_free_info mm/kasan/common.c:337 [inline] __kasan_slab_free+0x135/0x190 mm/kasan/common.c:476 kasan_slab_free+0xe/0x10 mm/kasan/common.c:485 slab_free_hook mm/slub.c:1444 [inline] slab_free_freelist_hook mm/slub.c:1477 [inline] slab_free mm/slub.c:3034 [inline] kfree+0xf7/0x410 mm/slub.c:3995 gprinter_free+0x49/0xd0 drivers/usb/gadget/function/f_printer.c:1353 usb_put_function+0x38/0x50 drivers/usb/gadget/functions.c:87 config_usb_cfg_unlink+0x2db/0x3b0 drivers/usb/gadget/configfs.c:485 configfs_unlink+0x3b9/0x7f0 fs/configfs/symlink.c:250 vfs_unlink+0x287/0x570 fs/namei.c:4073 do_unlinkat+0x4f9/0x620 fs/namei.c:4137 __do_sys_unlink fs/namei.c:4184 [inline] __se_sys_unlink fs/namei.c:4182 [inline] __x64_sys_unlink+0x42/0x50 fs/namei.c:4182 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at 8880683b which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 24 bytes inside of 1024-byte region [8880683b, 8880683b0400) The buggy address belongs to the page: page:ea0001a0ec00 refcount:1 mapcount:0 mapping:88806c00e300 index:0x8880683b1800 compound_mapcount: 0 flags: 0x1010200(slab|head) raw: 01010200 00060001 88806c00e300 raw: 8880683b1800 801a 0001 page dumped because: kasan: bad access detected Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- v1->v2: Commit information modification. drivers/usb/gadget/function/f_printer.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 9c7ed2539ff7..8ed1295d7e35 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -31,6 +31,7 @@ #include #include #include +#include
[PATCH] usb: gadget: function: printer: fix use-after-free in __lock_acquire
From: Zqiang Fix this by increase object reference count. BUG: KASAN: use-after-free in __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 Read of size 8 at addr 8880683b0018 by task syz-executor.0/3377 CPU: 1 PID: 3377 Comm: syz-executor.0 Not tainted 5.6.11 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x131/0x1b0 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:641 __asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135 __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 lock_acquire+0x127/0x350 kernel/locking/lockdep.c:4488 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159 printer_ioctl+0x4a/0x110 drivers/usb/gadget/function/f_printer.c:723 vfs_ioctl fs/ioctl.c:47 [inline] ksys_ioctl+0xfb/0x130 fs/ioctl.c:763 __do_sys_ioctl fs/ioctl.c:772 [inline] __se_sys_ioctl fs/ioctl.c:770 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:770 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4531a9 Code: ed 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 bb 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:7fd14ad72c78 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 0073bfa8 RCX: 004531a9 RDX: fff9 RSI: 009e RDI: 0003 RBP: 0003 R08: R09: R10: R11: 0246 R12: 004bbd61 R13: 004d0a98 R14: 7fd14ad736d4 R15: Allocated by task 2393: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] __kasan_kmalloc.constprop.3+0xa7/0xd0 mm/kasan/common.c:515 kasan_kmalloc+0x9/0x10 mm/kasan/common.c:529 kmem_cache_alloc_trace+0xfa/0x2d0 mm/slub.c:2813 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] gprinter_alloc+0xa1/0x870 drivers/usb/gadget/function/f_printer.c:1416 usb_get_function+0x58/0xc0 drivers/usb/gadget/functions.c:61 config_usb_cfg_link+0x1ed/0x3e0 drivers/usb/gadget/configfs.c:444 configfs_symlink+0x527/0x11d0 fs/configfs/symlink.c:202 vfs_symlink+0x33d/0x5b0 fs/namei.c:4201 do_symlinkat+0x11b/0x1d0 fs/namei.c:4228 __do_sys_symlinkat fs/namei.c:4242 [inline] __se_sys_symlinkat fs/namei.c:4239 [inline] __x64_sys_symlinkat+0x73/0xb0 fs/namei.c:4239 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 3368: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] kasan_set_free_info mm/kasan/common.c:337 [inline] __kasan_slab_free+0x135/0x190 mm/kasan/common.c:476 kasan_slab_free+0xe/0x10 mm/kasan/common.c:485 slab_free_hook mm/slub.c:1444 [inline] slab_free_freelist_hook mm/slub.c:1477 [inline] slab_free mm/slub.c:3034 [inline] kfree+0xf7/0x410 mm/slub.c:3995 gprinter_free+0x49/0xd0 drivers/usb/gadget/function/f_printer.c:1353 usb_put_function+0x38/0x50 drivers/usb/gadget/functions.c:87 config_usb_cfg_unlink+0x2db/0x3b0 drivers/usb/gadget/configfs.c:485 configfs_unlink+0x3b9/0x7f0 fs/configfs/symlink.c:250 vfs_unlink+0x287/0x570 fs/namei.c:4073 do_unlinkat+0x4f9/0x620 fs/namei.c:4137 __do_sys_unlink fs/namei.c:4184 [inline] __se_sys_unlink fs/namei.c:4182 [inline] __x64_sys_unlink+0x42/0x50 fs/namei.c:4182 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at 8880683b which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 24 bytes inside of 1024-byte region [8880683b, 8880683b0400) The buggy address belongs to the page: page:ea0001a0ec00 refcount:1 mapcount:0 mapping:88806c00e300 index:0x8880683b1800 compound_mapcount: 0 flags: 0x1010200(slab|head) raw: 01010200 00060001 88806c00e300 raw: 8880683b1800 801a 0001 page dumped because: kasan: bad access detected Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- drivers/usb/gadget/function/f_printer.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 9c7ed2539ff7..8ed1295d7e35 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ struct printer_dev { struct usb_gadget *gadget; s8
[PATCH] usb: gadget: function: printer: fix use-after-free in __lock_acquire
From: Zqiang Fix this by increase object reference count. BUG: KASAN: use-after-free in __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 Read of size 8 at addr 8880683b0018 by task syz-executor.0/3377 CPU: 1 PID: 3377 Comm: syz-executor.0 Not tainted 5.6.11 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xce/0x128 lib/dump_stack.c:118 print_address_description.constprop.4+0x21/0x3c0 mm/kasan/report.c:374 __kasan_report+0x131/0x1b0 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:641 __asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135 __lock_acquire+0x3fd4/0x4180 kernel/locking/lockdep.c:3831 lock_acquire+0x127/0x350 kernel/locking/lockdep.c:4488 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159 printer_ioctl+0x4a/0x110 drivers/usb/gadget/function/f_printer.c:723 vfs_ioctl fs/ioctl.c:47 [inline] ksys_ioctl+0xfb/0x130 fs/ioctl.c:763 __do_sys_ioctl fs/ioctl.c:772 [inline] __se_sys_ioctl fs/ioctl.c:770 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:770 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x4531a9 Code: ed 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 bb 60 fc ff c3 66 2e 0f 1f 84 00 00 00 00 RSP: 002b:7fd14ad72c78 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 0073bfa8 RCX: 004531a9 RDX: fff9 RSI: 009e RDI: 0003 RBP: 0003 R08: R09: R10: R11: 0246 R12: 004bbd61 R13: 004d0a98 R14: 7fd14ad736d4 R15: Allocated by task 2393: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] __kasan_kmalloc.constprop.3+0xa7/0xd0 mm/kasan/common.c:515 kasan_kmalloc+0x9/0x10 mm/kasan/common.c:529 kmem_cache_alloc_trace+0xfa/0x2d0 mm/slub.c:2813 kmalloc include/linux/slab.h:555 [inline] kzalloc include/linux/slab.h:669 [inline] gprinter_alloc+0xa1/0x870 drivers/usb/gadget/function/f_printer.c:1416 usb_get_function+0x58/0xc0 drivers/usb/gadget/functions.c:61 config_usb_cfg_link+0x1ed/0x3e0 drivers/usb/gadget/configfs.c:444 configfs_symlink+0x527/0x11d0 fs/configfs/symlink.c:202 vfs_symlink+0x33d/0x5b0 fs/namei.c:4201 do_symlinkat+0x11b/0x1d0 fs/namei.c:4228 __do_sys_symlinkat fs/namei.c:4242 [inline] __se_sys_symlinkat fs/namei.c:4239 [inline] __x64_sys_symlinkat+0x73/0xb0 fs/namei.c:4239 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 3368: save_stack+0x21/0x90 mm/kasan/common.c:72 set_track mm/kasan/common.c:80 [inline] kasan_set_free_info mm/kasan/common.c:337 [inline] __kasan_slab_free+0x135/0x190 mm/kasan/common.c:476 kasan_slab_free+0xe/0x10 mm/kasan/common.c:485 slab_free_hook mm/slub.c:1444 [inline] slab_free_freelist_hook mm/slub.c:1477 [inline] slab_free mm/slub.c:3034 [inline] kfree+0xf7/0x410 mm/slub.c:3995 gprinter_free+0x49/0xd0 drivers/usb/gadget/function/f_printer.c:1353 usb_put_function+0x38/0x50 drivers/usb/gadget/functions.c:87 config_usb_cfg_unlink+0x2db/0x3b0 drivers/usb/gadget/configfs.c:485 configfs_unlink+0x3b9/0x7f0 fs/configfs/symlink.c:250 vfs_unlink+0x287/0x570 fs/namei.c:4073 do_unlinkat+0x4f9/0x620 fs/namei.c:4137 __do_sys_unlink fs/namei.c:4184 [inline] __se_sys_unlink fs/namei.c:4182 [inline] __x64_sys_unlink+0x42/0x50 fs/namei.c:4182 do_syscall_64+0x9e/0x510 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe The buggy address belongs to the object at 8880683b which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 24 bytes inside of 1024-byte region [8880683b, 8880683b0400) The buggy address belongs to the page: page:ea0001a0ec00 refcount:1 mapcount:0 mapping:88806c00e300 index:0x8880683b1800 compound_mapcount: 0 flags: 0x1010200(slab|head) raw: 01010200 00060001 88806c00e300 raw: 8880683b1800 801a 0001 page dumped because: kasan: bad access detected Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- drivers/usb/gadget/function/f_printer.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 9c7ed2539ff7..8ed1295d7e35 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ struct printer_dev { struct usb_gadget *gadget; s8
[PATCH v2] usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect
From: Zqiang BUG: memory leak unreferenced object 0x888055046e00 (size 256): comm "kworker/2:9", pid 2570, jiffies 4294942129 (age 1095.500s) hex dump (first 32 bytes): 00 70 04 55 80 88 ff ff 18 bb 5a 81 ff ff ff ff .p.U..Z. f5 96 78 81 ff ff ff ff 37 de 8e 81 ff ff ff ff ..x.7... backtrace: [] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [ ] slab_post_alloc_hook mm/slab.h:586 [inline] [ ] slab_alloc_node mm/slub.c:2786 [inline] [ ] slab_alloc mm/slub.c:2794 [inline] [ ] kmem_cache_alloc_trace+0x15e/0x2d0 mm/slub.c:2811 [<5c3c3381>] kmalloc include/linux/slab.h:555 [inline] [<5c3c3381>] usbtest_probe+0x286/0x19d0 drivers/usb/misc/usbtest.c:2790 [<1cec6910>] usb_probe_interface+0x2bd/0x870 drivers/usb/core/driver.c:361 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 [<3ef66004>] __device_attach_driver+0x1b6/0x240 drivers/base/dd.c:831 [ ] bus_for_each_drv+0x14e/0x1e0 drivers/base/bus.c:431 [ ] __device_attach+0x1f9/0x350 drivers/base/dd.c:897 [<838b324a>] device_initial_probe+0x1a/0x20 drivers/base/dd.c:944 [<30d501c1>] bus_probe_device+0x1e1/0x280 drivers/base/bus.c:491 [<5bd7adef>] device_add+0x131d/0x1c40 drivers/base/core.c:2504 [ ] usb_set_configuration+0xe84/0x1ab0 drivers/usb/core/message.c:2030 [ ] generic_probe+0x6a/0xe0 drivers/usb/core/generic.c:210 [<98ade0f1>] usb_probe_device+0x90/0xd0 drivers/usb/core/driver.c:266 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- v1->v2: Remove Fixes field. drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 98ada1a3425c..bae88893ee8e 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2873,6 +2873,7 @@ static void usbtest_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); dev_dbg(&intf->dev, "disconnect\n"); + kfree(dev->buf); kfree(dev); } -- 2.24.1
[PATCH] usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect
From: Zqiang BUG: memory leak unreferenced object 0x888055046e00 (size 256): comm "kworker/2:9", pid 2570, jiffies 4294942129 (age 1095.500s) hex dump (first 32 bytes): 00 70 04 55 80 88 ff ff 18 bb 5a 81 ff ff ff ff .p.U..Z. f5 96 78 81 ff ff ff ff 37 de 8e 81 ff ff ff ff ..x.7... backtrace: [] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [ ] slab_post_alloc_hook mm/slab.h:586 [inline] [ ] slab_alloc_node mm/slub.c:2786 [inline] [ ] slab_alloc mm/slub.c:2794 [inline] [ ] kmem_cache_alloc_trace+0x15e/0x2d0 mm/slub.c:2811 [<5c3c3381>] kmalloc include/linux/slab.h:555 [inline] [<5c3c3381>] usbtest_probe+0x286/0x19d0 drivers/usb/misc/usbtest.c:2790 [<1cec6910>] usb_probe_interface+0x2bd/0x870 drivers/usb/core/driver.c:361 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 [<3ef66004>] __device_attach_driver+0x1b6/0x240 drivers/base/dd.c:831 [ ] bus_for_each_drv+0x14e/0x1e0 drivers/base/bus.c:431 [ ] __device_attach+0x1f9/0x350 drivers/base/dd.c:897 [<838b324a>] device_initial_probe+0x1a/0x20 drivers/base/dd.c:944 [<30d501c1>] bus_probe_device+0x1e1/0x280 drivers/base/bus.c:491 [<5bd7adef>] device_add+0x131d/0x1c40 drivers/base/core.c:2504 [ ] usb_set_configuration+0xe84/0x1ab0 drivers/usb/core/message.c:2030 [ ] generic_probe+0x6a/0xe0 drivers/usb/core/generic.c:210 [<98ade0f1>] usb_probe_device+0x90/0xd0 drivers/usb/core/driver.c:266 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 Fixes: fabbf2196d0d ("USB: usbtest fix coding style") Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 98ada1a3425c..bae88893ee8e 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2873,6 +2873,7 @@ static void usbtest_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); dev_dbg(&intf->dev, "disconnect\n"); + kfree(dev->buf); kfree(dev); } -- 2.24.1
[PATCH] usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect
From: Zqiang BUG: memory leak unreferenced object 0x888055046e00 (size 256): comm "kworker/2:9", pid 2570, jiffies 4294942129 (age 1095.500s) hex dump (first 32 bytes): 00 70 04 55 80 88 ff ff 18 bb 5a 81 ff ff ff ff .p.U..Z. f5 96 78 81 ff ff ff ff 37 de 8e 81 ff ff ff ff ..x.7... backtrace: [] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [ ] slab_post_alloc_hook mm/slab.h:586 [inline] [ ] slab_alloc_node mm/slub.c:2786 [inline] [ ] slab_alloc mm/slub.c:2794 [inline] [ ] kmem_cache_alloc_trace+0x15e/0x2d0 mm/slub.c:2811 [<5c3c3381>] kmalloc include/linux/slab.h:555 [inline] [<5c3c3381>] usbtest_probe+0x286/0x19d0 drivers/usb/misc/usbtest.c:2790 [<1cec6910>] usb_probe_interface+0x2bd/0x870 drivers/usb/core/driver.c:361 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 [<3ef66004>] __device_attach_driver+0x1b6/0x240 drivers/base/dd.c:831 [ ] bus_for_each_drv+0x14e/0x1e0 drivers/base/bus.c:431 [ ] __device_attach+0x1f9/0x350 drivers/base/dd.c:897 [<838b324a>] device_initial_probe+0x1a/0x20 drivers/base/dd.c:944 [<30d501c1>] bus_probe_device+0x1e1/0x280 drivers/base/bus.c:491 [<5bd7adef>] device_add+0x131d/0x1c40 drivers/base/core.c:2504 [ ] usb_set_configuration+0xe84/0x1ab0 drivers/usb/core/message.c:2030 [ ] generic_probe+0x6a/0xe0 drivers/usb/core/generic.c:210 [<98ade0f1>] usb_probe_device+0x90/0xd0 drivers/usb/core/driver.c:266 [<7806c118>] really_probe+0x48d/0x8f0 drivers/base/dd.c:551 [ ] driver_probe_device+0xfc/0x2a0 drivers/base/dd.c:724 Fixes: fabbf2196d0d ("USB: usbtest fix coding style") Reported-by: Kyungtae Kim Signed-off-by: Zqiang --- drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 98ada1a3425c..bae88893ee8e 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2873,6 +2873,7 @@ static void usbtest_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); dev_dbg(&intf->dev, "disconnect\n"); + kfree(dev->buf); kfree(dev); } -- 2.24.1
[PATCH v7] workqueue: Remove unnecessary kfree() call in rcu_free_wq()
From: Zhang Qiang The data structure member "wq->rescuer" was reset to a null pointer in one if branch. It was passed to a call of the function "kfree" in the callback function "rcu_free_wq" (which was eventually executed). The function "kfree" does not perform more meaningful data processing for a passed null pointer (besides immediately returning from such a call). Thus delete this function call which became unnecessary with the referenced software update. Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()") Co-developed-by: Markus Elfring Signed-off-by: Markus Elfring Co-developed-by: Lai Jiangshan Signed-off-by: Lai Jiangshan Signed-off-by: Zhang Qiang --- v1->v2->v3->v4->v5->v6->v7: Modify weakly submitted information and tag. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH v6] workqueue: Remove unnecessary kfree() call in rcu_free_wq()
From: Zhang Qiang The data structure member "wq->rescuer" was reset to a null pointer in one if branch. It was passed to a call of the function "kfree" in the callback function "rcu_free_wq" (which was eventually executed). The function "kfree" does not perform more meaningful data processing for a passed null pointer (besides immediately returning from such a call). Thus delete this function call which became unnecessary with the referenced software update. Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()") Co-developed-by: Markus Elfring Signed-off-by: Zhang Qiang --- v1->v2->v3->v4->v5->v6: Modify weakly submitted information and tag. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH v5] workqueue: Remove unnecessary kfree() call in rcu_free_wq()
From: Zhang Qiang The data structure member "wq->rescuer" was reset to a null pointer in one if branch. It was passed to a call of the function "kfree" in the callback function "rcu_free_wq" (which was eventually executed). The function "kfree" does not perform more meaningful data processing for a passed null pointer (besides immediately returning from such a call). Thus delete this function call which became unnecessary with the referenced software update. Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()") Co-developed-by: Markus Elfring Signed-off-by: Zhang Qiang --- v1->v2->v3->v4->v5: Modify weakly submitted information. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH v5] workqueue: Remove unnecessary kfree() call in rcu_free_wq()
From: Zhang Qiang The data structure member "wq->rescuer" was reset to a null pointer in one if branch. It was passed to a call of the function "kfree" in the callback function "rcu_free_wq" (which was eventually executed). The function "kfree" does not perform more meaningful data processing for a passed null pointer (besides immediately returning from such a call). Thus delete this function call which became unnecessary with the referenced software update. Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()") Suggested-by: Markus Elfring Signed-off-by: Zhang Qiang --- v1->v2->v3->v4->v5: Modify weakly submitted information. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH v4] workqueue: Remove unnecessary kfree(NULL)
From: Zhang Qiang The callback function "rcu_free_wq" could be called after memory was released for "wq->rescuer" already and assignment is empty. so remove unnecessary kfree(NULL). Fixes: def98c84b6cd ("workqueue: Fix spurious sanity check failures in destroy_workqueue()") Fixes: 8efe1223d73c ("workqueue: Fix missing kfree(rescuer) in destroy_workqueue()") Signed-off-by: Zhang Qiang --- v1->v2->v3->v4: Modify wrong submission information. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH v3] workqueue: Fix double kfree for rescuer
From: Zhang Qiang The callback function "rcu_free_wq" could be called after memory was released for "rescuer" already, Thus delete a misplaced call of the function "kfree". Fixes: 6ba94429c8e7 ("workqueue: Reorder sysfs code") Signed-off-by: Zhang Qiang --- v1->v2->v3: Only commit information modification. kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH] workqueue: Fix double kfree for rescuer
From: Zhang Qiang The duplicate memory release should be deleted from the implementation of the callback function "rcu_free_wq". Fixes: 6ba94429c8e7 ("workqueue: Reorder sysfs code") Signed-off-by: Zhang Qiang --- kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.24.1
[PATCH] workqueue: Fix double kfree(rescuer) in destroy_workqueue()
From: Zhang Qiang When destroy_workqueue if rescuer worker exist,wq->rescuer pointer be kfree. if sanity checks passed. the func call_rcu(&wq->rcu, rcu_free_wq) will be called if the wq->flags & WQ_UNBOUND is false,in rcu_free_wq func wq->rescuer pointer was kfree again. Signed-off-by: Zhang Qiang --- kernel/workqueue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 891ccad5f271..a2451cdcd503 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3491,7 +3491,6 @@ static void rcu_free_wq(struct rcu_head *rcu) else free_workqueue_attrs(wq->unbound_attrs); - kfree(wq->rescuer); kfree(wq); } -- 2.17.0
[PATCH] kernel/hung_task: Use task_pid_nr function to get pid
From: Zhang Qiang Use task_pid_nr(t) function instead of t->pid when printing task pid. Signed-off-by: Zhang Qiang --- kernel/hung_task.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 14a625c16cb3..0a77f6af6909 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -128,7 +128,8 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) if (sysctl_hung_task_warnings > 0) sysctl_hung_task_warnings--; pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", - t->comm, t->pid, (jiffies - t->last_switch_time) / HZ); + t->comm, task_pid_nr(t), + (jiffies - t->last_switch_time) / HZ); pr_err(" %s %s %.*s\n", print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), -- 2.24.1
[PATCH] kernel/hung_task: Use task_pid_nr function to get pid
From: Zhang Qiang Use task_pid_nr(t) function instead of t->pid when printing task pid Signed-off-by: Zhang Qiang --- kernel/hung_task.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 14a625c16cb3..f397beb8c9e1 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c @@ -128,7 +128,7 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) if (sysctl_hung_task_warnings > 0) sysctl_hung_task_warnings--; pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", - t->comm, t->pid, (jiffies - t->last_switch_time) / HZ); + t->comm, task_pid_nr(t), (jiffies - t->last_switch_time) / HZ); pr_err(" %s %s %.*s\n", print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), -- 2.24.1
[PATCH] sched/rt: Add borrowing time condition
From: Zhang Qiang Add priority judgment to determine whether to borrow time from neighbors, ensure that the rt_runntime of rt_rq with higher priority tasks is not reduced Signed-off-by: Zhang Qiang --- kernel/sched/rt.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 4043abe45459..d2a1acad6687 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -711,8 +711,10 @@ static void do_balance_runtime(struct rt_rq *rt_rq) diff = div_u64((u64)diff, weight); if (rt_rq->rt_runtime + diff > rt_period) diff = rt_period - rt_rq->rt_runtime; - iter->rt_runtime -= diff; - rt_rq->rt_runtime += diff; + if (rt_rq->highest_prio.curr < iter->highest_prio.curr) { + iter->rt_runtime -= diff; + rt_rq->rt_runtime += diff; + } if (rt_rq->rt_runtime == rt_period) { raw_spin_unlock(&iter->rt_runtime_lock); break; -- 2.17.0