From: Roman Gushchin <roman.gushchin@linux.dev>
To: Yosry Ahmed <yosryahmed@google.com>
Cc: linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
Johannes Weiner <hannes@cmpxchg.org>,
Michal Hocko <mhocko@kernel.org>,
Shakeel Butt <shakeelb@google.com>,
Muchun Song <muchun.song@linux.dev>,
linux-kernel@vger.kernel.org,
syzbot+774c29891415ab0fd29d@syzkaller.appspotmail.com,
Dmitry Vyukov <dvyukov@google.com>
Subject: Re: [PATCH] mm: kmem: fix a NULL pointer dereference in obj_stock_flush_required()
Date: Fri, 21 Apr 2023 15:55:28 -0700 [thread overview]
Message-ID: <ZEMUYCcUtqDFSYXH@P9FQF9L96D> (raw)
In-Reply-To: <CAJD7tkZRLsubybPesf65t1ATEksTtif8uztAFZ-gVmYCnjw0Bg@mail.gmail.com>
On Fri, Apr 21, 2023 at 03:16:02PM -0700, Yosry Ahmed wrote:
> On Fri, Apr 21, 2023 at 10:41 AM Roman Gushchin
> <roman.gushchin@linux.dev> wrote:
> >
> > KCSAN found an issue in obj_stock_flush_required():
> > stock->cached_objcg can be reset between the check and dereference:
> >
> > ==================================================================
> > BUG: KCSAN: data-race in drain_all_stock / drain_obj_stock
> >
> > write to 0xffff888237c2a2f8 of 8 bytes by task 19625 on cpu 0:
> > drain_obj_stock+0x408/0x4e0 mm/memcontrol.c:3306
> > refill_obj_stock+0x9c/0x1e0 mm/memcontrol.c:3340
> > obj_cgroup_uncharge+0xe/0x10 mm/memcontrol.c:3408
> > memcg_slab_free_hook mm/slab.h:587 [inline]
> > __cache_free mm/slab.c:3373 [inline]
> > __do_kmem_cache_free mm/slab.c:3577 [inline]
> > kmem_cache_free+0x105/0x280 mm/slab.c:3602
> > __d_free fs/dcache.c:298 [inline]
> > dentry_free fs/dcache.c:375 [inline]
> > __dentry_kill+0x422/0x4a0 fs/dcache.c:621
> > dentry_kill+0x8d/0x1e0
> > dput+0x118/0x1f0 fs/dcache.c:913
> > __fput+0x3bf/0x570 fs/file_table.c:329
> > ____fput+0x15/0x20 fs/file_table.c:349
> > task_work_run+0x123/0x160 kernel/task_work.c:179
> > resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
> > exit_to_user_mode_loop+0xcf/0xe0 kernel/entry/common.c:171
> > exit_to_user_mode_prepare+0x6a/0xa0 kernel/entry/common.c:203
> > __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline]
> > syscall_exit_to_user_mode+0x26/0x140 kernel/entry/common.c:296
> > do_syscall_64+0x4d/0xc0 arch/x86/entry/common.c:86
> > entry_SYSCALL_64_after_hwframe+0x63/0xcd
> >
> > read to 0xffff888237c2a2f8 of 8 bytes by task 19632 on cpu 1:
> > obj_stock_flush_required mm/memcontrol.c:3319 [inline]
> > drain_all_stock+0x174/0x2a0 mm/memcontrol.c:2361
> > try_charge_memcg+0x6d0/0xd10 mm/memcontrol.c:2703
> > try_charge mm/memcontrol.c:2837 [inline]
> > mem_cgroup_charge_skmem+0x51/0x140 mm/memcontrol.c:7290
> > sock_reserve_memory+0xb1/0x390 net/core/sock.c:1025
> > sk_setsockopt+0x800/0x1e70 net/core/sock.c:1525
> > udp_lib_setsockopt+0x99/0x6c0 net/ipv4/udp.c:2692
> > udp_setsockopt+0x73/0xa0 net/ipv4/udp.c:2817
> > sock_common_setsockopt+0x61/0x70 net/core/sock.c:3668
> > __sys_setsockopt+0x1c3/0x230 net/socket.c:2271
> > __do_sys_setsockopt net/socket.c:2282 [inline]
> > __se_sys_setsockopt net/socket.c:2279 [inline]
> > __x64_sys_setsockopt+0x66/0x80 net/socket.c:2279
> > do_syscall_x64 arch/x86/entry/common.c:50 [inline]
> > do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
> > entry_SYSCALL_64_after_hwframe+0x63/0xcd
> >
> > value changed: 0xffff8881382d52c0 -> 0xffff888138893740
> >
> > Reported by Kernel Concurrency Sanitizer on:
> > CPU: 1 PID: 19632 Comm: syz-executor.0 Not tainted 6.3.0-rc2-syzkaller-00387-g534293368afa #0
> > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/02/2023
> >
> > Fix it by reading the cached_objcg with READ_ONCE().
>
> IIUC reading an outdated objcg is fine here, and the real problem is a
> potential NULL dereference, which isn't shown by this report. Is this
> correct?
My understanding of the problem:
1) we are reading stock->cached_objcg and checking for being NULL, it's not NULL.
2) we're reading it again and dereferencing it without a check.
If stock->cached_objcg is zeroed between 1) and 2), we're in trouble.
The fix makes sure we're dereferencing exactly what we check.
>
> >
> > Fixes: bf4f059954dc ("mm: memcg/slab: obj_cgroup API")
> > Reported-by: syzbot+774c29891415ab0fd29d@syzkaller.appspotmail.com
> > Reported-by: Dmitry Vyukov <dvyukov@google.com>
> > Link: https://lore.kernel.org/linux-mm/CACT4Y+ZfucZhM60YPphWiCLJr6+SGFhT+jjm8k1P-a_8Kkxsjg@mail.gmail.com/T/#t
> > Signed-off-by: Roman Gushchin <roman.gushchin@linux.dev>
> > ---
> > mm/memcontrol.c | 5 +++--
> > 1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > index 5abffe6f8389..9426a1ddc190 100644
> > --- a/mm/memcontrol.c
> > +++ b/mm/memcontrol.c
> > @@ -3314,10 +3314,11 @@ static struct obj_cgroup *drain_obj_stock(struct memcg_stock_pcp *stock)
> > static bool obj_stock_flush_required(struct memcg_stock_pcp *stock,
> > struct mem_cgroup *root_memcg)
> > {
> > + struct obj_cgroup *objcg = READ_ONCE(stock->cached_objcg);
> > struct mem_cgroup *memcg;
> >
> > - if (stock->cached_objcg) {
> > - memcg = obj_cgroup_memcg(stock->cached_objcg);
> > + if (objcg) {
> > + memcg = obj_cgroup_memcg(objcg);
> > if (memcg && mem_cgroup_is_descendant(memcg, root_memcg))
> > return true;
> > }
> > --
> > 2.40.0
> >
> >
next prev parent reply other threads:[~2023-04-21 22:55 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-21 14:32 [syzbot] [cgroups?] [mm?] KCSAN: data-race in drain_all_stock / drain_obj_stock (4) syzbot
2023-04-21 14:32 ` syzbot
2023-04-21 14:38 ` Dmitry Vyukov
2023-04-21 14:38 ` Dmitry Vyukov
2023-04-21 17:40 ` [PATCH] mm: kmem: fix a NULL pointer dereference in obj_stock_flush_required() Roman Gushchin
2023-04-21 22:16 ` Yosry Ahmed
2023-04-21 22:55 ` Roman Gushchin [this message]
2023-04-22 6:57 ` Yosry Ahmed
2023-04-23 2:25 ` Muchun Song
2023-04-24 6:51 ` Dmitry Vyukov
2023-04-24 9:12 ` Yosry Ahmed
2023-04-24 17:10 ` Shakeel Butt
2023-04-24 21:10 ` Yosry Ahmed
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=ZEMUYCcUtqDFSYXH@P9FQF9L96D \
--to=roman.gushchin@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=dvyukov@google.com \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@kernel.org \
--cc=muchun.song@linux.dev \
--cc=shakeelb@google.com \
--cc=syzbot+774c29891415ab0fd29d@syzkaller.appspotmail.com \
--cc=yosryahmed@google.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.