Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp2206469ybp; Sat, 5 Oct 2019 07:38:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqwooyoepilJhvJn0XDAUSrAv5EiQ/sOeR8PBmfmd+98v8y7YypdFo0f/+ndbp1zb33qMzhZ X-Received: by 2002:a50:b685:: with SMTP id d5mr20916300ede.258.1570286327201; Sat, 05 Oct 2019 07:38:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570286327; cv=none; d=google.com; s=arc-20160816; b=QkxQuKyvQQvJUA/ASjRrtrJmf4Y5uuhES7VLpujMirU8zWHlOxvGD6ezRPceR1fMip Rc6EBkBFMdARBX3PqQkeYOXx1fGUyoysyX071bypleHBO2dXrDUKwuGYQ1lstWw4C7Pa agFr0UmvjO/xBqjg6ulH/T/DnKffVekp9m/DC6UuTHwqJF+QBKsSGfKWVNstWWAPfMKd UnuPWwvDi02rddHdO7PXGtYybv6VEOPWvMONE+lUd4aF63u63NRTjeKwGH4EtdO46irx CuBQKH6ORrvIGCtlYJF5WX5S1aXth+tYtBlgUMnJfCPMONfcdH4MJaWoDAIdevMNpEbw Ak3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=M9slP3iKnAm63U3tuy9xEZJOMuCJBhoA1BolBatTclo=; b=g1iGHst5COBqp84a3MHMaTLMbRwcPu6f0YY7onq0OL3rvRwSbNJmPmCciHDi+Pcnbs Dxq+PQyA9lNNh0MV3/WMUV/VCuXtTSxqR8+QSa5Dc+bL0CnAYz2RCJY65MhefxVjkxsV VWIjrqV3wPmMLuNwcdso2Xm31JtaC7T930cbAYFjrukSXeQ/RhwxosQi75OG6H8Lxodl 0JwKaCc9TiF/ReD2V0hHL4xy/JeITDtUVn5n7FwrX4Sd6flDXT+Cb7WtrMfezaXyXyxn iSF2Mae+n+lBe2jMp5YCSvMCoCISwGio1+yrJ87HckY254BEuMYcvKlSWaHWxLIkzSJA KviA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=GPw8ZMaM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l15si4556828eja.290.2019.10.05.07.38.23; Sat, 05 Oct 2019 07:38:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=GPw8ZMaM; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728598AbfJEOef (ORCPT + 99 others); Sat, 5 Oct 2019 10:34:35 -0400 Received: from mail-ot1-f68.google.com ([209.85.210.68]:37236 "EHLO mail-ot1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726076AbfJEOef (ORCPT ); Sat, 5 Oct 2019 10:34:35 -0400 Received: by mail-ot1-f68.google.com with SMTP id k32so7637102otc.4 for ; Sat, 05 Oct 2019 07:34:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=M9slP3iKnAm63U3tuy9xEZJOMuCJBhoA1BolBatTclo=; b=GPw8ZMaMVaviw/cMPN6lH4cnGgCi+CWse4O9XJySKkr9jsyd+q9Z4nuRCHa7oNRRwr qgUL7dnweYwzG21Dm2QqiWfym5LoO93rVE25IBWjHOqOfIvr9/FzF+26FewaoZB2OZlh Y/adls+5weFB9FVLk8VKECXYOBFPOnRxXyu/in4xn4NMvabDokBKI+vVlh7VDXP/Tugx b3w0K/VGTSgbpyCQ/2No1RhVXhmBrQ1hn7vndZOgbEb6YBWtm/TJfGwxjU8oeAhN5d4r pT3BxJpuKtNFzrLkO7TYSAHxwqiu0yVmW8XKzIoIZWGhApRyTrgq6PR2fHu//T6XhZyw XtyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=M9slP3iKnAm63U3tuy9xEZJOMuCJBhoA1BolBatTclo=; b=t7L2DoexSJHaqhdaP6erzgJcsbxDB/BJL1y5gCuH5tyv9HKYfwKaxV0BrIaq4/GLyc WXRTrvwoQflyXFIJUJc05mokhsXX1KhuS/p3f1G10uwOy46Ij6KSzX5s74l+rPtuJiGb U+TCqqyhI0sQyKLeA/nb6bQFpk4P9a11xsQMNCeXc3rELCqsi8/7hE7SeoFn864noJKj WIcNUVzhwG8ITUPURGlBX3vG2yrrD11goPTG7imtWYhHhCT9yqrZnYc8yu9XNcBSBIt0 E60/jKRokMgkPwuwSjn/68EDYQxRGIppZI7tptLtmvOves3m0SxVWb1Y3taE/GyMzEvC dPkw== X-Gm-Message-State: APjAAAWP6i9vIVJ/81r1GX/o7VxF7Sy69xnzXmlVzNSwP0G+o53/u+Yi kavxbjM8zW7SdxqfRRARBlwb5Tw36MXrf4wBJsN80w== X-Received: by 2002:a05:6830:101:: with SMTP id i1mr15041173otp.233.1570286073978; Sat, 05 Oct 2019 07:34:33 -0700 (PDT) MIME-Version: 1.0 References: <0000000000009b403005942237bf@google.com> <20191005112806.13960-1-christian.brauner@ubuntu.com> <20191005141523.kog6il27seucy2f4@wittgenstein> In-Reply-To: <20191005141523.kog6il27seucy2f4@wittgenstein> From: Marco Elver Date: Sat, 5 Oct 2019 16:34:22 +0200 Message-ID: Subject: Re: [PATCH] taskstats: fix data-race To: Christian Brauner Cc: syzbot+c5d03165a1bd1dead0c1@syzkaller.appspotmail.com, bsingharora@gmail.com, LKML , syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, 5 Oct 2019 at 16:15, Christian Brauner wrote: > > On Sat, Oct 05, 2019 at 03:33:07PM +0200, Marco Elver wrote: > > On Sat, 5 Oct 2019 at 13:28, Christian Brauner > > wrote: > > > > > > When assiging and testing taskstats in taskstats > > > taskstats_exit() there's a race around writing and reading sig->stats. > > > > > > cpu0: > > > task calls exit() > > > do_exit() > > > -> taskstats_exit() > > > -> taskstats_tgid_alloc() > > > The task takes sighand lock and assigns new stats to sig->stats. > > > > > > cpu1: > > > task catches signal > > > do_exit() > > > -> taskstats_tgid_alloc() > > > -> taskstats_exit() > > > The tasks reads sig->stats __without__ holding sighand lock seeing > > > garbage. > > > > Is the task seeing garbage reading the data pointed to by stats, or is > > this just the pointer that would be garbage? > > I expect the pointer to be garbage. > > > > > My only observation here is that the previous version was trying to do > > double-checked locking, to avoid taking the lock if sig->stats was > > already set. The obvious problem with the previous version is plain > > read/write and missing memory ordering: the write inside the critical > > section should be smp_store_release and there should only be one > > smp_load_acquire at the start. > > > > Maybe I missed something somewhere, but maybe my suggestion below > > would be an equivalent fix without always having to take the lock to > > assign the pointer? If performance is not critical here, then it's > > probably not worth it. > > The only point of contention is when the whole thread-group exits (e.g. > via exit_group(2) since threads in a thread-group share signal struct). > The reason I didn't do memory barriers was because we need to take the > spinlock for the actual list manipulation anyway. > But I don't mind incorporating the acquire/release. Thanks for the clarification. Since you no longer do double-checked locking, explicit memory barriers shouldn't be needed because spin_lock/unlock already provides acquire/release ordering. -- Marco > Christian > > > > > Thanks, > > -- Marco > > > > diff --git a/kernel/taskstats.c b/kernel/taskstats.c > > index 13a0f2e6ebc2..f58dd285a44b 100644 > > --- a/kernel/taskstats.c > > +++ b/kernel/taskstats.c > > @@ -554,25 +554,31 @@ static int taskstats_user_cmd(struct sk_buff > > *skb, struct genl_info *info) > > static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) > > { > > struct signal_struct *sig = tsk->signal; > > - struct taskstats *stats; > > + struct taskstats *stats_new, *stats; > > > > - if (sig->stats || thread_group_empty(tsk)) > > + /* acquire load to make pointed-to data visible */ > > + stats = smp_load_acquire(&sig->stats); > > + if (stats || thread_group_empty(tsk)) > > goto ret; > > > > /* No problem if kmem_cache_zalloc() fails */ > > - stats = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); > > + stats_new = kmem_cache_zalloc(taskstats_cache, GFP_KERNEL); > > > > spin_lock_irq(&tsk->sighand->siglock); > > - if (!sig->stats) { > > - sig->stats = stats; > > - stats = NULL; > > + stats = sig->stats; > > + if (!stats) { > > + stats = stats_new; > > + /* release store to order zalloc before */ > > + smp_store_release(&sig->stats, stats_new); > > + stats_new = NULL; > > } > > spin_unlock_irq(&tsk->sighand->siglock); > > > > - if (stats) > > - kmem_cache_free(taskstats_cache, stats); > > + if (stats_new) > > + kmem_cache_free(taskstats_cache, stats_new); > > + > > ret: > > - return sig->stats; > > + return stats; > > } > > > > /* Send pid data out on exit */