From: Jens Axboe <axboe@kernel.dk>
To: Paul Moore <paul@paul-moore.com>, Peilin Ye <yepeilin.cs@gmail.com>
Cc: Pavel Begunkov <asml.silence@gmail.com>,
Eric Paris <eparis@redhat.com>,
Peilin Ye <peilin.ye@bytedance.com>,
io-uring@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-audit@redhat.com
Subject: Re: [PATCH] audit, io_uring, io-wq: Fix memory leak in io_sq_thread() and io_wqe_worker()
Date: Wed, 3 Aug 2022 13:39:08 -0600 [thread overview]
Message-ID: <54d7ec45-3f69-294b-7036-b9350cb1ab4c@kernel.dk> (raw)
In-Reply-To: <CAHC9VhRYGgCLiWx5LCoqgTj_RW_iQRLrzivWci7_UneN_=rwmw@mail.gmail.com>
On 8/3/22 1:28 PM, Paul Moore wrote:
> On Wed, Aug 3, 2022 at 9:16 AM Paul Moore <paul@paul-moore.com> wrote:
>> On Wed, Aug 3, 2022 at 1:03 AM Peilin Ye <yepeilin.cs@gmail.com> wrote:
>>>
>>> Currently @audit_context is allocated twice for io_uring workers:
>>>
>>> 1. copy_process() calls audit_alloc();
>>> 2. io_sq_thread() or io_wqe_worker() calls audit_alloc_kernel() (which
>>> is effectively audit_alloc()) and overwrites @audit_context,
>>> causing:
>>>
>>> BUG: memory leak
>>> unreferenced object 0xffff888144547400 (size 1024):
>>> <...>
>>> hex dump (first 32 bytes):
>>> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
>>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
>>> backtrace:
>>> [<ffffffff8135cfc3>] audit_alloc+0x133/0x210
>>> [<ffffffff81239e63>] copy_process+0xcd3/0x2340
>>> [<ffffffff8123b5f3>] create_io_thread+0x63/0x90
>>> [<ffffffff81686604>] create_io_worker+0xb4/0x230
>>> [<ffffffff81686f68>] io_wqe_enqueue+0x248/0x3b0
>>> [<ffffffff8167663a>] io_queue_iowq+0xba/0x200
>>> [<ffffffff816768b3>] io_queue_async+0x113/0x180
>>> [<ffffffff816840df>] io_req_task_submit+0x18f/0x1a0
>>> [<ffffffff816841cd>] io_apoll_task_func+0xdd/0x120
>>> [<ffffffff8167d49f>] tctx_task_work+0x11f/0x570
>>> [<ffffffff81272c4e>] task_work_run+0x7e/0xc0
>>> [<ffffffff8125a688>] get_signal+0xc18/0xf10
>>> [<ffffffff8111645b>] arch_do_signal_or_restart+0x2b/0x730
>>> [<ffffffff812ea44e>] exit_to_user_mode_prepare+0x5e/0x180
>>> [<ffffffff844ae1b2>] syscall_exit_to_user_mode+0x12/0x20
>>> [<ffffffff844a7e80>] do_syscall_64+0x40/0x80
>>>
>>> Then,
>>>
>>> 3. io_sq_thread() or io_wqe_worker() frees @audit_context using
>>> audit_free();
>>> 4. do_exit() eventually calls audit_free() again, which is okay
>>> because audit_free() does a NULL check.
>>>
>>> Free the old @audit_context first in audit_alloc_kernel(), and delete
>>> the redundant calls to audit_free() for less confusion.
>>>
>>> Fixes: 5bd2182d58e9 ("audit,io_uring,io-wq: add some basic audit support to io_uring")
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
>>> ---
>>> Hi all,
>>>
>>> A better way to fix this memleak would probably be checking
>>> @args->io_thread in copy_process()? Something like:
>>>
>>> if (args->io_thread)
>>> retval = audit_alloc_kernel();
>>> else
>>> retval = audit_alloc();
>>>
>>> But I didn't want to add another if to copy_process() for this bugfix.
>>> Please suggest, thanks!
>>
>> Thanks for the report and patch! I'll take a closer look at this
>> today and get back to you.
>
> I think the best solution to this is simply to remove the calls to
> audit_alloc_kernel() in the io_uring and io-wq code, as well as the
> audit_alloc_kernel() function itself. As long as create_io_thread()
> ends up calling copy_process to create the new kernel thread the
> audit_context should be allocated correctly. Peilin Ye, are you able
> to draft a patch to do that and give it a test?
>
> For those that may be wondering how this happened (I definitely was!),
> it looks like when I first started working on the LSM/audit support
> for io_uring it was before the v5.12-rc1 release when
> create_io_thread() was introduced. Prior to create_io_thread() it
> appears that io_uring/io-wq wasn't calling into copy_process() and
> thus was not getting an audit_context allocated in the kernel thread's
> task_struct; the solution for those original development drafts was to
> add a call to a new audit_alloc_kernel() which would handle the
> audit_context allocation. Unfortunately, I didn't notice the move to
> create_io_thread() during development and the redundant
> audit_alloc_kernel() calls remained :/
I agree with your analysis and suggested solution. Post the native io-wq
workers create_io_thread() -> copy_process() is always used for io-wq
(and sqpoll, for that matter).
--
Jens Axboe
WARNING: multiple messages have this Message-ID (diff)
From: Jens Axboe <axboe@kernel.dk>
To: Paul Moore <paul@paul-moore.com>, Peilin Ye <yepeilin.cs@gmail.com>
Cc: linux-kernel@vger.kernel.org, Eric Paris <eparis@redhat.com>,
io-uring@vger.kernel.org, linux-audit@redhat.com,
Peilin Ye <peilin.ye@bytedance.com>,
Pavel Begunkov <asml.silence@gmail.com>
Subject: Re: [PATCH] audit, io_uring, io-wq: Fix memory leak in io_sq_thread() and io_wqe_worker()
Date: Wed, 3 Aug 2022 13:39:08 -0600 [thread overview]
Message-ID: <54d7ec45-3f69-294b-7036-b9350cb1ab4c@kernel.dk> (raw)
In-Reply-To: <CAHC9VhRYGgCLiWx5LCoqgTj_RW_iQRLrzivWci7_UneN_=rwmw@mail.gmail.com>
On 8/3/22 1:28 PM, Paul Moore wrote:
> On Wed, Aug 3, 2022 at 9:16 AM Paul Moore <paul@paul-moore.com> wrote:
>> On Wed, Aug 3, 2022 at 1:03 AM Peilin Ye <yepeilin.cs@gmail.com> wrote:
>>>
>>> Currently @audit_context is allocated twice for io_uring workers:
>>>
>>> 1. copy_process() calls audit_alloc();
>>> 2. io_sq_thread() or io_wqe_worker() calls audit_alloc_kernel() (which
>>> is effectively audit_alloc()) and overwrites @audit_context,
>>> causing:
>>>
>>> BUG: memory leak
>>> unreferenced object 0xffff888144547400 (size 1024):
>>> <...>
>>> hex dump (first 32 bytes):
>>> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................
>>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
>>> backtrace:
>>> [<ffffffff8135cfc3>] audit_alloc+0x133/0x210
>>> [<ffffffff81239e63>] copy_process+0xcd3/0x2340
>>> [<ffffffff8123b5f3>] create_io_thread+0x63/0x90
>>> [<ffffffff81686604>] create_io_worker+0xb4/0x230
>>> [<ffffffff81686f68>] io_wqe_enqueue+0x248/0x3b0
>>> [<ffffffff8167663a>] io_queue_iowq+0xba/0x200
>>> [<ffffffff816768b3>] io_queue_async+0x113/0x180
>>> [<ffffffff816840df>] io_req_task_submit+0x18f/0x1a0
>>> [<ffffffff816841cd>] io_apoll_task_func+0xdd/0x120
>>> [<ffffffff8167d49f>] tctx_task_work+0x11f/0x570
>>> [<ffffffff81272c4e>] task_work_run+0x7e/0xc0
>>> [<ffffffff8125a688>] get_signal+0xc18/0xf10
>>> [<ffffffff8111645b>] arch_do_signal_or_restart+0x2b/0x730
>>> [<ffffffff812ea44e>] exit_to_user_mode_prepare+0x5e/0x180
>>> [<ffffffff844ae1b2>] syscall_exit_to_user_mode+0x12/0x20
>>> [<ffffffff844a7e80>] do_syscall_64+0x40/0x80
>>>
>>> Then,
>>>
>>> 3. io_sq_thread() or io_wqe_worker() frees @audit_context using
>>> audit_free();
>>> 4. do_exit() eventually calls audit_free() again, which is okay
>>> because audit_free() does a NULL check.
>>>
>>> Free the old @audit_context first in audit_alloc_kernel(), and delete
>>> the redundant calls to audit_free() for less confusion.
>>>
>>> Fixes: 5bd2182d58e9 ("audit,io_uring,io-wq: add some basic audit support to io_uring")
>>> Cc: stable@vger.kernel.org
>>> Signed-off-by: Peilin Ye <peilin.ye@bytedance.com>
>>> ---
>>> Hi all,
>>>
>>> A better way to fix this memleak would probably be checking
>>> @args->io_thread in copy_process()? Something like:
>>>
>>> if (args->io_thread)
>>> retval = audit_alloc_kernel();
>>> else
>>> retval = audit_alloc();
>>>
>>> But I didn't want to add another if to copy_process() for this bugfix.
>>> Please suggest, thanks!
>>
>> Thanks for the report and patch! I'll take a closer look at this
>> today and get back to you.
>
> I think the best solution to this is simply to remove the calls to
> audit_alloc_kernel() in the io_uring and io-wq code, as well as the
> audit_alloc_kernel() function itself. As long as create_io_thread()
> ends up calling copy_process to create the new kernel thread the
> audit_context should be allocated correctly. Peilin Ye, are you able
> to draft a patch to do that and give it a test?
>
> For those that may be wondering how this happened (I definitely was!),
> it looks like when I first started working on the LSM/audit support
> for io_uring it was before the v5.12-rc1 release when
> create_io_thread() was introduced. Prior to create_io_thread() it
> appears that io_uring/io-wq wasn't calling into copy_process() and
> thus was not getting an audit_context allocated in the kernel thread's
> task_struct; the solution for those original development drafts was to
> add a call to a new audit_alloc_kernel() which would handle the
> audit_context allocation. Unfortunately, I didn't notice the move to
> create_io_thread() during development and the redundant
> audit_alloc_kernel() calls remained :/
I agree with your analysis and suggested solution. Post the native io-wq
workers create_io_thread() -> copy_process() is always used for io-wq
(and sqpoll, for that matter).
--
Jens Axboe
--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit
next prev parent reply other threads:[~2022-08-03 19:39 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-03 5:02 [PATCH] audit, io_uring, io-wq: Fix memory leak in io_sq_thread() and io_wqe_worker() Peilin Ye
2022-08-03 5:02 ` Peilin Ye
2022-08-03 13:16 ` Paul Moore
2022-08-03 13:16 ` Paul Moore
2022-08-03 19:28 ` Paul Moore
2022-08-03 19:28 ` Paul Moore
2022-08-03 19:39 ` Jens Axboe [this message]
2022-08-03 19:39 ` Jens Axboe
2022-08-03 20:24 ` Peilin Ye
2022-08-03 20:24 ` Peilin Ye
2022-08-03 22:23 ` [PATCH v2] " Peilin Ye
2022-08-03 22:23 ` Peilin Ye
2022-08-04 13:51 ` Paul Moore
2022-08-04 13:51 ` Paul Moore
2022-08-04 14:32 ` Jens Axboe
2022-08-04 14:32 ` Jens Axboe
2022-08-04 14:44 ` Paul Moore
2022-08-04 14:44 ` Paul Moore
2022-08-04 14:36 ` Jens Axboe
2022-08-04 14:36 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54d7ec45-3f69-294b-7036-b9350cb1ab4c@kernel.dk \
--to=axboe@kernel.dk \
--cc=asml.silence@gmail.com \
--cc=eparis@redhat.com \
--cc=io-uring@vger.kernel.org \
--cc=linux-audit@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=peilin.ye@bytedance.com \
--cc=yepeilin.cs@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is 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.