From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f177.google.com (mail-oi1-f177.google.com [209.85.167.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93A6221146C for ; Fri, 24 Apr 2026 01:06:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776992794; cv=none; b=QotEXkMtmXxAHQJ53dG96hsRIY0Ed3IPG5cm5i2ybFYLeh1r6omxUR2H0PMLC5IhUBNZb69Qjnl5FUjJCkYGkhI5wBpJD4e3XqSdi8vH/F9513s19h1aI3vTcL+lkD9XPDm/C/mAxcivBK1eKwYCoheW5kGrQDcfzqrhIqXkbCc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776992794; c=relaxed/simple; bh=7LMM95UMg7yP38DZK0skWWp8cJR2GRO6hI/cI7m0eOM=; h=Mime-Version:Content-Type:Date:Message-Id:Cc:Subject:From:To: References:In-Reply-To; b=I6lmPNKxOD7wXdgHx+c4asfdW5h9xK7LNBGY/09dJK189UpBkxMrXKMkBbIG1m6w4T3GC8Yi24rrkRntTrtqVJNYO0AYe5kBFlGCY3A8f+ghPoq2nbRbHFv+0ZJjWmLDhfjtNJO6xxvK2yvmzrRPCBchkMfThVdhqs3ZSYTTzfE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=H/MRQZlh; arc=none smtp.client-ip=209.85.167.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="H/MRQZlh" Received: by mail-oi1-f177.google.com with SMTP id 5614622812f47-479d68a90a7so2780453b6e.2 for ; Thu, 23 Apr 2026 18:06:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776992791; x=1777597591; darn=vger.kernel.org; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=xh3t/bv0nfHgOMhcW4p/qplYnwzHag4a5ofsHvIRt9Q=; b=H/MRQZlhZdxgZmS1uhYvIyrTsc/5ZZ4ueMxuW8CJKMQFlhxq5ZuB6rVV7exasUzdG2 atmaa0Zdhu0YzKin4nZz28Wer7V/BD4SOaU7O276MdkaSofkO0duHV+pTdUBb9mDahDv kIPn3sDfADPnhCRHUCVuIKEsOxk4XPg0N/RzO24gUZsL/MIaI5emSqrHVORt2vrS5Cci 4WVgs9R2xQyAA6d32FeF1oaKBgCLG+xvaq6tucrRQDUzRRClshuMZj+d2u7SsC0yoDJu a8SZfkTlnbDDEqFAY6KML738qHoEnzkh7FHVpB5+9plGlVjhd+hh5fmcAkBvExlmiWrL e2uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776992791; x=1777597591; h=in-reply-to:references:to:from:subject:cc:message-id:date :content-transfer-encoding:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=xh3t/bv0nfHgOMhcW4p/qplYnwzHag4a5ofsHvIRt9Q=; b=brTJqRlcLRA8BZpEL1ws4x69wajM++O3uFxvLMKU75C2lsHffUinWlOqIsEEPDXRis V+VW+AS9x5kaIlcDAvqNyuZV7S5oDiRSDE0n985XF04gDSsbmMuJpQX5LgZfKcj0grg5 RLmDbOQcnZau/ZSesSkkVHpUFX8xGrw40OcnsvxcDjmqOZJfOAHUsufgeNIWDP1vRI6r ZbbEnK9eZMOucxv0Ju/gyaHwXzH3E8Ex9abMaD11k/QJp1bav+qe69Rc/OYT3bDG7HvR uE1hIDNsz8RTYaItWF0HdTGhZRGDeIJwLw3HcaRL07yPhdsRZP6GKzPpaB8xMOOkkenD OtwA== X-Forwarded-Encrypted: i=1; AFNElJ+Ij6M4gr+CoW/Evn5QwCbfBuJhQ/Q4Run0v/s3/Jz2lJTXyn8NHynnDLEH54FryQ3aI1nPKLMwlvBJRow=@vger.kernel.org X-Gm-Message-State: AOJu0YyILbP9u7Ul8kNwNqvvdfpN5Le1tm44E8JdPMWd66oFCBxBcHeA yADPxw5kJ9oo2WQ/Rg9DzmP9OOCqCy84NhXpK0dpnfNhZ7gEKCV1iABu X-Gm-Gg: AeBDietAkfRtLVRsB0JtSdXNV2WWY87IJd/MpWGx/S8uwkH7cPznply/HsiKX7XM5yk vSLjcGbqFkpPrfnz4JhpmUzMt+XBNLqyAYUnErB7bY/xnoa1+mo2sxgst0gKstZFhXMCS4ZpZ0i rZvIuXUHONqxRWe1g9du0/kls60BGdtlLffzgCjueN9Mc5a4IwtVIEvLvsrVTUD9QxKzOkbO9D3 LJvEXx5ims7Q0vJQh8B6uCJnb/XexNsqfgsRy4E0g7AbhjSk/2xz6BIEK5h7TtLBwjY7MrSEFyL zpXa5l4rn+CPBFRrHnZi3Z1w6qj+X9+IC0/RYs8CyuhTv7GvaF+zWrMZtbx+cs4/rKLZiRKObes uWFXueJjVHr7xhY57vXJhFg8DarVv2lQB5jE8gG75ZfTxj0TG0eNrJS9SeesXmJf1BmPqKQLhwY J7Z8MPqgjJ9Bw0VX4oilYZZEuV4hzY+uE6IY12IHMYs8hLKJpzqyQSrAAI3iWLahSS2n7wSMgtg PMiEBBB2YkuBTvJ66VYzTku+NoGyd0KkO8ZQA== X-Received: by 2002:a05:6808:c151:b0:467:5f1:fc93 with SMTP id 5614622812f47-4799c91872fmr14412173b6e.9.1776992791471; Thu, 23 Apr 2026 18:06:31 -0700 (PDT) Received: from localhost ([2a03:2880:10ff:1::]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-42f090b1de9sm8378833fac.6.2026.04.23.18.06.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 23 Apr 2026 18:06:30 -0700 (PDT) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 Date: Thu, 23 Apr 2026 18:06:28 -0700 Message-Id: Cc: , , , , , , "Alexei Starovoitov" , "KaFai Wan" , "Yonghong Song" , , "Al Viro" Subject: Re: [BUG] KASAN: slab-use-after-free in link_path_walk From: "Alexei Starovoitov" To: "Al Viro" , "Eulgyu Kim" X-Mailer: aerc References: <20260423013916.1589029-1-eulgyukim@snu.ac.kr> <20260423043906.GN3518998@ZenIV> In-Reply-To: <20260423043906.GN3518998@ZenIV> On Wed Apr 22, 2026 at 9:39 PM PDT, Al Viro wrote: > On Thu, Apr 23, 2026 at 10:39:16AM +0900, Eulgyu Kim wrote: > >> We suspect there is a race condition between vfs_rmdir() and may_lookup(= ) >> on the BPF pseudo filesystem. It seems that while link_path_walk() is wa= lking >> a path, its call to may_lookup() checks permissions on the current direc= tory >> inode through nd->inode, and vfs_rmdir() can remove that same directory = and >> trigger inode destruction, leading to a use-after-free. > > Not really. What happens is that bpf does prompt freeing of struct inode= , instead > of having it done with RCU delay. Everything else is a result of that. > > What's going on there? It used to be in ->free_inode(); who had moved th= at into > ->destroy_inode(), why had that been done, who had ACKed that and how hav= e I > missed the discussions on fsdevel? > > > > commit 4f375ade6aa9f37fd72d7a78682f639772089eed > Author: KaFai Wan > Date: Wed Oct 8 18:26:26 2025 +0800 > =20 > bpf: Avoid RCU context warning when unpinning htab with internal str= ucts > > [blocking stuff done from RCU-delayed callback, so let's make everything = prompt, > whaddya mean, what was the delay for?] > > Reported-by: Le Chen > Closes: https://lore.kernel.org/all/1444123482.1827743.1750996347470.Java= Mail.zimbra@sjtu.edu.cn/ > Fixes: 68134668c17f ("bpf: Add map side support for bpf timers.") > Suggested-by: Alexei Starovoitov > Signed-off-by: KaFai Wan > Acked-by: Yonghong Song > Link: https://lore.kernel.org/r/20251008102628.808045-2-kafai.wan@linux.d= ev > Signed-off-by: Alexei Starovoitov > > OK, that answers some of that... > To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, > martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org, > yonghong.song@linux.dev, john.fastabend@gmail.com, > kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com, > jolsa@kernel.org, shuah@kernel.org, kafai.wan@linux.dev, > toke@redhat.com, linux-kernel@vger.kernel.org, > bpf@vger.kernel.org, linux-kselftest@vger.kernel.org > > ... right, that probably answers the last one. Incidentally, that commit= has > brought back the old bug with cached symlink bodies getting freed without= RCU delay. > It is possible that it was discussed on fsdevel at some point and I'd mis= sed it > there, but... > > Folks, the rules are simple: > * anything that might be accessed in RCU mode (inode very much included > for objects that are visible in the tree) must be freed after RCU delay; = that's > what ->free_inode() is for. > * anything that can't be freed in such context should either be > dealt with in ->destroy_inode() (if it isn't needed for RCU-exposed metho= ds) > or, if it really is needed for those, done via schedule_work() or equival= ent > done by ->destroy_inode(). > > Seeing that bpffs has the grand total of zero RCU-exposed methods (no ->d= _compare(), > no ->d_hash(), no ->permission(), no ->d_revalidate(), no ->get_link()) I= would > guess that it's the case of "have your bpf_any_put() done promptly, leave= freeing > the inode and cached symlink body RCU-delayed". Something like the delta= below > (completely untested): > > diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c > index 25c06a011825..bd052a8e89a9 100644 > --- a/kernel/bpf/inode.c > +++ b/kernel/bpf/inode.c > @@ -762,14 +762,26 @@ static int bpf_show_options(struct seq_file *m, str= uct dentry *root) > return 0; > } > =20 > +// this is done promptly > static void bpf_destroy_inode(struct inode *inode) > { > enum bpf_type type; > =20 > - if (S_ISLNK(inode->i_mode)) > - kfree(inode->i_link); > + // better done here, since it's blocking and we'd need > + // to use something like schedule_work() to do it from > + // ->free_inode(); since this stuff doesn't need to > + // be delayed, doing it here is less headache. > if (!bpf_inode_type(inode, &type)) > bpf_any_put(inode->i_private, type); > +} > + > +// ... and this is done with RCU delay; anything that might be accessed > +// by RCU pathwalk (like, you know, inode and symlink contents) should b= e > +// dealt with here > +static void bpf_free_inode(struct inode *inode) > +{ > + if (S_ISLNK(inode->i_mode)) > + kfree(inode->i_link); > free_inode_nonrcu(inode); > } > =20 > @@ -778,6 +790,7 @@ const struct super_operations bpf_super_ops =3D { > .drop_inode =3D inode_just_drop, > .show_options =3D bpf_show_options, > .destroy_inode =3D bpf_destroy_inode, > + .free_inode =3D bpf_free_inode, > }; Thanks for the fix. Feel free to take it into your tree directly.