Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4468217pxf; Tue, 16 Mar 2021 14:27:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx6iTRTKY1A/8F5u4/lfvRfefKSu9YRvHAGgfCzb7DXCol9falHez0+0EMPptMK5r95uwoh X-Received: by 2002:a17:906:2710:: with SMTP id z16mr32290700ejc.176.1615930045529; Tue, 16 Mar 2021 14:27:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1615930045; cv=none; d=google.com; s=arc-20160816; b=dJdhUcum3KiQsfw5VSoforKtKYc8xd3Af9nfeB8KuPZht9M++0ZK8SEwoIak1f4WZR MLRbMTDGJkv6h9lx4FeoHwXbBcf76ryzxTG7M3wO+y7WLjJkd8jmae+5uB7ci+9JNskz hCX4y2Wz0K/wQFg/SVTDUJTBkjFQOvfATtrlFquEYil4nOvamK5JxOwYgsS60JKJBB6N rAneKfhJFwbQ9V3s8dQQgAX22aquGFiI7BLc/ChaqKpEJPoWtRH0YP2zXReNacOf6FnG FqAL2CuRXUGC7uwG7HJGHtd9NMnpgnzVO2N7/inFyHbdIV1HJYMh8S3r97i02nqDkF29 +l5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=Pi6I3Ms1kzM+xJLe+117BPbYFV3mzVYuAi3CbQB7FMY=; b=IWnyvWtpxr5CreoOORRUdlcE6x8cUQFMjjXV4PVjH9LM7xPNcW00Xn36UFwz+6QwGO CibN36AMdzdpAm/i/qbAXOASdUOsMcSFVKxa518KtgizjcQByTJ/jLhDYlr/3DD3oFMK PqMcCtBIEBvG49OoaH2TvaMzoHMQH+Um5il5Dvg+lIkvOMMZmRAI8r9Yqa8dnX0aOwC8 eAqFl5DL9cfgl62ntskByGUPScYHz1806/m0f10VOE75/QonjR/eUPVqEMR2WQJHoadN DE3yoPSnRd2uiJjixdSMPh9Xu+XyfEf8DQcYr3f38gDUyYiwBlaFITTMXadWyO1HyHqc kYtg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a3si14409529ejd.167.2021.03.16.14.27.03; Tue, 16 Mar 2021 14:27:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231965AbhCPUvn (ORCPT + 99 others); Tue, 16 Mar 2021 16:51:43 -0400 Received: from www62.your-server.de ([213.133.104.62]:57708 "EHLO www62.your-server.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231435AbhCPUvR (ORCPT ); Tue, 16 Mar 2021 16:51:17 -0400 Received: from sslproxy06.your-server.de ([78.46.172.3]) by www62.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92.3) (envelope-from ) id 1lMGek-000CJR-NX; Tue, 16 Mar 2021 21:51:10 +0100 Received: from [85.7.101.30] (helo=pc-9.home) by sslproxy06.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lMGek-000UAH-Gk; Tue, 16 Mar 2021 21:51:10 +0100 Subject: Re: [PATCH v2] bpf: Fix memory leak in copy_process() To: qiang.zhang@windriver.com, ast@kernel.org, andrii@kernel.org Cc: dvyukov@google.com, linux-kernel@vger.kernel.org, syzbot+44908bb56d2bfe56b28e@syzkaller.appspotmail.com, bpf@vger.kernel.org References: <20210315085816.21413-1-qiang.zhang@windriver.com> From: Daniel Borkmann Message-ID: Date: Tue, 16 Mar 2021 21:51:10 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <20210315085816.21413-1-qiang.zhang@windriver.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.102.4/26110/Tue Mar 16 12:05:23 2021) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 3/15/21 9:58 AM, qiang.zhang@windriver.com wrote: > From: Zqiang nit: I presume it should be s/Zqiang/Qiang Zhang/ as real name for 'From' instead of abbreviation? > The syzbot report a memleak follow: > BUG: memory leak > unreferenced object 0xffff888101b41d00 (size 120): > comm "kworker/u4:0", pid 8, jiffies 4294944270 (age 12.780s) > backtrace: > [] alloc_pid+0x66/0x560 > [] copy_process+0x1465/0x25e0 > [] kernel_clone+0xf3/0x670 > [] kernel_thread+0x61/0x80 > [] call_usermodehelper_exec_work > [] call_usermodehelper_exec_work+0xc4/0x120 > [] process_one_work+0x2c9/0x600 > [] worker_thread+0x59/0x5d0 > [] kthread+0x178/0x1b0 > [] ret_from_fork+0x1f/0x30 > > unreferenced object 0xffff888110ef5c00 (size 232): > comm "kworker/u4:0", pid 8414, jiffies 4294944270 (age 12.780s) > backtrace: > [] kmem_cache_zalloc > [] __alloc_file+0x1f/0xf0 > [] alloc_empty_file+0x69/0x120 > [] alloc_file+0x33/0x1b0 > [] alloc_file_pseudo+0xb2/0x140 > [] create_pipe_files+0x138/0x2e0 > [] umd_setup+0x33/0x220 > [] call_usermodehelper_exec_async+0xb4/0x1b0 > [] ret_from_fork+0x1f/0x30 > > after the UMD process exits, the pipe_to_umh/pipe_from_umh and tgid > need to be release. > > Fixes: d71fa5c9763c ("bpf: Add kernel module with user mode driver that populates bpffs.") > Reported-by: syzbot+44908bb56d2bfe56b28e@syzkaller.appspotmail.com > Signed-off-by: Zqiang nit: Ditto > --- > v1->v2: > Judge whether the pointer variable tgid is valid. > > kernel/bpf/preload/bpf_preload_kern.c | 24 ++++++++++++++++++++---- > 1 file changed, 20 insertions(+), 4 deletions(-) > > diff --git a/kernel/bpf/preload/bpf_preload_kern.c b/kernel/bpf/preload/bpf_preload_kern.c > index 79c5772465f1..5009875f01d3 100644 > --- a/kernel/bpf/preload/bpf_preload_kern.c > +++ b/kernel/bpf/preload/bpf_preload_kern.c > @@ -4,6 +4,7 @@ > #include > #include > #include > +#include > #include > #include "bpf_preload.h" > > @@ -20,6 +21,14 @@ static struct bpf_preload_ops umd_ops = { > .owner = THIS_MODULE, > }; > > +static void bpf_preload_umh_cleanup(struct umd_info *info) > +{ > + fput(info->pipe_to_umh); > + fput(info->pipe_from_umh); > + put_pid(info->tgid); > + info->tgid = NULL; > +} The above is pretty much a reimplementation of ... static void umd_cleanup(struct subprocess_info *info) { struct umd_info *umd_info = info->data; /* cleanup if umh_setup() was successful but exec failed */ if (info->retval) { fput(umd_info->pipe_to_umh); fput(umd_info->pipe_from_umh); put_pid(umd_info->tgid); umd_info->tgid = NULL; } } ... so if there are ever changes to umd_cleanup() for additional resource cleanup, we'd be missing those easily in bpf_preload_umh_cleanup(). I'd suggest to refactor a common helper inside kernel/usermode_driver.c that is then exported as symbol which the driver here can use. > static int preload(struct bpf_preload_info *obj) > { > int magic = BPF_PRELOAD_START; > @@ -61,8 +70,10 @@ static int finish(void) > if (n != sizeof(magic)) > return -EPIPE; > tgid = umd_ops.info.tgid; > - wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); > - umd_ops.info.tgid = NULL; > + if (tgid) { > + wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); > + bpf_preload_umh_cleanup(&umd_ops.info); > + } > return 0; > } > > @@ -80,10 +91,15 @@ static int __init load_umd(void) > > static void __exit fini_umd(void) > { > + struct pid *tgid; > bpf_preload_ops = NULL; > /* kill UMD in case it's still there due to earlier error */ > - kill_pid(umd_ops.info.tgid, SIGKILL, 1); > - umd_ops.info.tgid = NULL; > + tgid = umd_ops.info.tgid; > + if (tgid) { > + kill_pid(tgid, SIGKILL, 1); > + wait_event(tgid->wait_pidfd, thread_group_exited(tgid)); > + bpf_preload_umh_cleanup(&umd_ops.info); > + } > umd_unload_blob(&umd_ops.info); > } > late_initcall(load_umd); >