* [PATCH] ipc: fix hung task in copy_ipcs()
@ 2026-08-11 8:12 ` Changyu Li
0 siblings, 0 replies; 2+ messages in thread
From: Changyu Li via B4 Relay @ 2026-08-11 8:12 UTC (permalink / raw)
To: linux-kernel; +Cc: syzbot+97a62389c5611b0477f3, Changyu Li
From: Changyu Li <ihaveihaveihavea@gmail.com>
When the user_ns's UCOUNT_IPC_NAMESPACES limit is reached,
copy_ipcs eventually calls flush_work(&free_ipc_work) to wait for
in-flight work to reduce the number of ipc_namespaces so it can proceed.
Unfortunately flush_work() enters uninterruptible sleep and if there
are enough pending items to be freed by free_ipc_work then this would
trip hung task watchdog.
INFO: task blocked for more than 143 seconds.
Not tainted syzkaller #0
task:syz-executor845 state:D stack:27496 pid:5856
Call Trace:
<TASK>
__flush_work+0x9c2/0xd70 kernel/workqueue.c:4431
create_ipc_ns ipc/namespace.c:55 [inline]
copy_ipcs+0x19b/0x6c0 ipc/namespace.c:116
create_new_namespaces+0x210/0x6b0 kernel/nsproxy.c:112
unshare_nsproxy_namespaces+0x149/0x190 kernel/nsproxy.c:234
ksys_unshare+0x5a7/0x950 kernel/fork.c:3291
</TASK>
Replace the uninterruptible flush_work() with a polling loop that
checks if there's an in-flight free_ipc_work. If there is then wait
interruptibly a short interval for forward progress in free_ipc_work
and retry.
If free_ipc_work is not in-flight nothing will free up quota so bail
with -ENOSPC as before. Otherwise wait interruptibly to not trip hung
task watchdog.
Reported-by: syzbot+97a62389c5611b0477f3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=97a62389c5611b0477f3
Signed-off-by: Changyu Li <ihaveihaveihavea@gmail.com>
---
ipc/namespace.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 1e71353bdb..e8ea422d79 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -26,6 +26,8 @@
static void free_ipc(struct work_struct *unused);
static DECLARE_WORK(free_ipc_work, free_ipc);
+#define FREE_IPC_WAIT_JIFFIES 5
+
static struct ucounts *inc_ipc_namespaces(struct user_namespace *ns)
{
return inc_ucount(ns, current_euid(), UCOUNT_IPC_NAMESPACES);
@@ -49,12 +51,19 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
if (!ucounts) {
/*
* IPC namespaces are freed asynchronously, by free_ipc_work.
- * If frees were pending, flush_work will wait, and
- * return true. Fail the allocation if no frees are pending.
+ * If there is in flight free_ipc_work, we'll wait for it to
+ * make progress otherwise fail immediately.
*/
- if (flush_work(&free_ipc_work))
- goto again;
- goto fail;
+ if (!work_busy(&free_ipc_work))
+ goto fail;
+
+ schedule_timeout_interruptible(FREE_IPC_WAIT_JIFFIES);
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ goto fail;
+ }
+
+ goto again;
}
err = -ENOMEM;
---
base-commit: 3d08ff75a47a3e7e2ab45a3bcab6723b4d906422
change-id: 20260811-work-53289e81bd3f
Best regards,
--
Changyu Li <ihaveihaveihavea@gmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH] ipc: fix hung task in copy_ipcs()
@ 2026-08-11 8:12 ` Changyu Li
0 siblings, 0 replies; 2+ messages in thread
From: Changyu Li @ 2026-08-11 8:12 UTC (permalink / raw)
To: linux-kernel; +Cc: syzbot+97a62389c5611b0477f3, Changyu Li
When the user_ns's UCOUNT_IPC_NAMESPACES limit is reached,
copy_ipcs eventually calls flush_work(&free_ipc_work) to wait for
in-flight work to reduce the number of ipc_namespaces so it can proceed.
Unfortunately flush_work() enters uninterruptible sleep and if there
are enough pending items to be freed by free_ipc_work then this would
trip hung task watchdog.
INFO: task blocked for more than 143 seconds.
Not tainted syzkaller #0
task:syz-executor845 state:D stack:27496 pid:5856
Call Trace:
<TASK>
__flush_work+0x9c2/0xd70 kernel/workqueue.c:4431
create_ipc_ns ipc/namespace.c:55 [inline]
copy_ipcs+0x19b/0x6c0 ipc/namespace.c:116
create_new_namespaces+0x210/0x6b0 kernel/nsproxy.c:112
unshare_nsproxy_namespaces+0x149/0x190 kernel/nsproxy.c:234
ksys_unshare+0x5a7/0x950 kernel/fork.c:3291
</TASK>
Replace the uninterruptible flush_work() with a polling loop that
checks if there's an in-flight free_ipc_work. If there is then wait
interruptibly a short interval for forward progress in free_ipc_work
and retry.
If free_ipc_work is not in-flight nothing will free up quota so bail
with -ENOSPC as before. Otherwise wait interruptibly to not trip hung
task watchdog.
Reported-by: syzbot+97a62389c5611b0477f3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=97a62389c5611b0477f3
Signed-off-by: Changyu Li <ihaveihaveihavea@gmail.com>
---
ipc/namespace.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 1e71353bdb..e8ea422d79 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -26,6 +26,8 @@
static void free_ipc(struct work_struct *unused);
static DECLARE_WORK(free_ipc_work, free_ipc);
+#define FREE_IPC_WAIT_JIFFIES 5
+
static struct ucounts *inc_ipc_namespaces(struct user_namespace *ns)
{
return inc_ucount(ns, current_euid(), UCOUNT_IPC_NAMESPACES);
@@ -49,12 +51,19 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
if (!ucounts) {
/*
* IPC namespaces are freed asynchronously, by free_ipc_work.
- * If frees were pending, flush_work will wait, and
- * return true. Fail the allocation if no frees are pending.
+ * If there is in flight free_ipc_work, we'll wait for it to
+ * make progress otherwise fail immediately.
*/
- if (flush_work(&free_ipc_work))
- goto again;
- goto fail;
+ if (!work_busy(&free_ipc_work))
+ goto fail;
+
+ schedule_timeout_interruptible(FREE_IPC_WAIT_JIFFIES);
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ goto fail;
+ }
+
+ goto again;
}
err = -ENOMEM;
---
base-commit: 3d08ff75a47a3e7e2ab45a3bcab6723b4d906422
change-id: 20260811-work-53289e81bd3f
Best regards,
--
Changyu Li <ihaveihaveihavea@gmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-11 8:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 8:12 [PATCH] ipc: fix hung task in copy_ipcs() Changyu Li via B4 Relay
2026-08-11 8:12 ` Changyu Li
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.