From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 47378381C4 for ; Thu, 5 Feb 2026 04:45:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770266723; cv=none; b=HUTwDaaDgflRth3wbw7PYlpadwazRhwbUnF/YvLgYKXF2nxUtMpH3ta4X2DJRbyOa/g0d6u0qK12/TFAWNc+bpgZw7bADm0/8pI+0VPmdOU6sJJXFlu6Oa+BGJat9wvqAlqNQ77x2V532KltbdKbAKAqW8raMXvoKhZ6OR8rQls= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770266723; c=relaxed/simple; bh=+huLvsHnEPNe+COSmu1uEIg9G8zeseh4VCf73AbemIQ=; h=From:Message-ID:Date:MIME-Version:Subject:To:Cc:References: In-Reply-To:Content-Type; b=jkbivF9oPptwF7Qcez3x5yYvtwvgYKR/LMnV1SBezvHRL/2dOut5T3JTn/Y7G++YyKjhHZmOHcfu3wJFFqVbwlGSQf78szuoNr2Tww64ThXSE9a8556DK3wOCZnyGkGfrtam3oEM6knIAm73WDY2RZTAMWGeJo9UNZ8q/l3HVwA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LC7hlak9; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=mjPewZJJ; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LC7hlak9"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="mjPewZJJ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770266722; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=10MUqzroLzmxLSL4NYapveobUZJ+rjSHt7evnfwhT9M=; b=LC7hlak9UtQKH8RCa+Wv0O+yvRKV6F7EIHrWDYfABEmSIV8xxA2bgFbUVUoqO8ubmCMRJj 8QIeotU6lfOCLxtQRBJasCu3eKsBWadidnxHQ/Xx/6ykAaK6JsKu1LrlRlCGlneRMbPX5A Seasq7530JQfzDgrn9cO0RTECuFMBmk= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-274-7PldeVMdNKeqNXbmuEG_CQ-1; Wed, 04 Feb 2026 23:45:20 -0500 X-MC-Unique: 7PldeVMdNKeqNXbmuEG_CQ-1 X-Mimecast-MFC-AGG-ID: 7PldeVMdNKeqNXbmuEG_CQ_1770266720 Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-8c6a87029b6so149680385a.1 for ; Wed, 04 Feb 2026 20:45:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1770266720; x=1770871520; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:user-agent:mime-version:date:message-id:from:from:to :cc:subject:date:message-id:reply-to; bh=10MUqzroLzmxLSL4NYapveobUZJ+rjSHt7evnfwhT9M=; b=mjPewZJJUpeQkpyr/wvhz5huXabPFzhp5xemlw5Phpu/Dy7POv/IVhLEmmYmw7iDS/ s8g29oTkk7TWs9vWTqvZfBmTDX0WC9uVE56mdwjwmfHQzaA7eRyiW8tHALxtPIFaJaEI flIAXMl8UjYU3W3aqS3ChNZmV0NXpUHe/QABTII+m0+DM39w2fZR3tHbOqzfr2qnjSja aTxxK68/g0QRnFvOu677pnOcq4PUFuqDxQACN3aMt7nefibCASmC3eJ/cbGWGq71EuoI eDXnyKiSvqooqMvv/akKgBFXpZ4KpgJuYtH26C7Qw2tcQwt75VTaqS1dj5g1RWRfY/Op HVAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770266720; x=1770871520; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:user-agent:mime-version:date:message-id:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=10MUqzroLzmxLSL4NYapveobUZJ+rjSHt7evnfwhT9M=; b=cFbAS+of5YC4GC0BoKReFAGsed6E0XkE9H6NqGWeyCGV5+fMk7568vHr6/IkbTXwX6 f/fmTQ9JboXiKCUgn9PG1uZaZEBG2EylMb5L9QTaHQMZQS5X4kyF+CqK+BecIZaYHW9L t1tkAtDWzhaha2nZTCPr+bYymW9V1vG5oJuwvwLabZ5zqNyk7Z5+f0dvzxTUBav4CL1w 7uwj9zn/LlwxpqJMUxydl80oNmmgYDRuIef2wjc9qWkpB64e8bDGQDAqJN61VdC1KbD0 Op5NAX1djvc0a2MGkDBDnX9QPnKLF7168//rmYEfLaCqr9s2gFp/13JYeRnJFj5HSsTZ qhzg== X-Forwarded-Encrypted: i=1; AJvYcCV3kcDfqcbVoz6VV9Sx6R2j3OK1s6+GLPgpJoNkiZbK7dUi+3LdTHaBAk6lxASa0zb0wy9vOHSFGfUB6Bw=@vger.kernel.org X-Gm-Message-State: AOJu0Yxgg67gfLlUpnZGO/g7AGC5wVO36qJxQZetgAj1I2VyW4o/KTJ3 PANiJIuHaRblUQe9K6RHOcOvexBQ05fQX/HN2QyI7qWx6vdyVyo5pK5poNv8jMAi/cUi/U80kgA 3CxJOqPxYCAcYok+m1bOwigu2rc9vqjx8OI+5ZD5KoW/3h4kJ70lZZHsGgJtLthfYNg== X-Gm-Gg: AZuq6aJviOI0HpY6WsQJJetdfm6plm5XN7CVZfVLoyTO+Ry+8dJXn025ylAnFg/vbVI tsNv+xsTd9/bDxzRhCiZO8zxkEK0K/WBEk5t0CPoGmufv8qffeHaJHPf1V0m2cT0l47ziUwT/DL lcrIQ/eyDtjlq3h4/jEP//t3xHOIuVIQ0eRYwZ5lnNSS314XVTtT1s0+bjwvCZ38u3ffVa33kXv NqYSe9yiL7E7bsSnb3tcptAl54XxsDNsjnlZPTh1rFuluLW6/i4I8CX/DiQRhyWt8Y1EDOxTvp/ ZCFpHJlWsGvkbAVnxEaW8EgGPIzQ68Bd1/1ZCS2+gUWsPypjabtcnHYT6OO0zy9dpWOMDur4r7B cmIGNYGk2SHuqtBEMmmISMmNXuJcK7JthJxsuBlabog8o0PuBcLrhYhgS X-Received: by 2002:a05:620a:40c8:b0:8c6:d2ca:1d0e with SMTP id af79cd13be357-8ca2f81cb4dmr673615485a.11.1770266719851; Wed, 04 Feb 2026 20:45:19 -0800 (PST) X-Received: by 2002:a05:620a:40c8:b0:8c6:d2ca:1d0e with SMTP id af79cd13be357-8ca2f81cb4dmr673613785a.11.1770266719387; Wed, 04 Feb 2026 20:45:19 -0800 (PST) Received: from ?IPV6:2601:188:c102:b180:1f8b:71d0:77b1:1f6e? ([2601:188:c102:b180:1f8b:71d0:77b1:1f6e]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-89521d1338fsm33633226d6.41.2026.02.04.20.45.17 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 04 Feb 2026 20:45:18 -0800 (PST) From: Waiman Long X-Google-Original-From: Waiman Long Message-ID: <50054d23-0a89-41ec-b28b-b1ed77d93b00@redhat.com> Date: Wed, 4 Feb 2026 23:45:17 -0500 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2] audit: Avoid excessive dput/dget in audit_context setup and reset paths To: Waiman Long , Al Viro Cc: Paul Moore , Eric Paris , Christian Brauner , linux-kernel@vger.kernel.org, audit@vger.kernel.org, Richard Guy Briggs , Ricardo Robaina References: <20260203194433.1738162-1-longman@redhat.com> <20260203200505.GH3183987@ZenIV> <590a36e6-8d11-411a-8fcd-d93eef96f0e9@redhat.com> <20260203215002.GI3183987@ZenIV> <20260203232634.GJ3183987@ZenIV> <6661f966-5235-49ca-bf1f-d1ae2ae32f0d@redhat.com> <20260204062614.GK3183987@ZenIV> <46d5c480-87d0-4f6a-bcc2-6c936c87e216@redhat.com> <20260204201815.GP3183987@ZenIV> Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 2/4/26 10:03 PM, Waiman Long wrote: > On 2/4/26 3:18 PM, Al Viro wrote: >> On Wed, Feb 04, 2026 at 01:16:15PM -0500, Waiman Long wrote: >> >> >>> Thanks for the detailed explanation. I am thinking about something like >>> the code diff below. Of course, there are other corner cases like >>> unshare(2) >>> that still needs to be handled. Do you think something like this is >>> viable? >> Deadlocks aside, the immediate problem here is that consensus number >> is too >> low.  Take three threads sharing the same fs_struct instance. The >> first one >> calls your get_fs_pwd_share(); then the remaining two threads call >> set_fs_pwd() >> (e.g. by calling chdir(2) in userland code).  The reference stored into >> fs->pwd_waiter by the first of those two gets overwritten by that stored >> by the second.  When the caller of get_fs_pwd_share() gets to >> put_fs_pwd_share(), >> only one of the sleepers gets woken up... >> >> And it's very easy to end up with something as simple as chdir("foo") >> deadlocking - >> we start with resolving the relative pathname we'd been given, audit >> wants to >> record the current directory, on the theory that relative pathname is >> none too >> useful in logs without knowing what had it been relative to. Then, in >> the >> same thread, you call set_fs_pwd() - after all, that's the main >> effect of chdir(2). >> Deadlock... >> >> IOW, it's not just unshare(2) that needs to be taken care of - >> chdir(2) would need >> to be treated differently. > > Now I realize that there is indeed a deadlock problem. Scrap that. Now > I have a simpler idea that shouldn't have this type of deadlock > problem. So what do you think about the sample code below? Well, a complete change log is as follows. Cheers, Longman =======================[ Cut here ]================================ diff --git a/fs/fs_struct.c b/fs/fs_struct.c index b8c46c5a38a0..67e08d8db058 100644 --- a/fs/fs_struct.c +++ b/fs/fs_struct.c @@ -32,15 +32,19 @@ void set_fs_root(struct fs_struct *fs, const struct path *p>  void set_fs_pwd(struct fs_struct *fs, const struct path *path)  {         struct path old_pwd; +       int count;         path_get(path);         write_seqlock(&fs->seq);         old_pwd = fs->pwd;         fs->pwd = *path; +       count = fs->pwd_xrefs + 1; +       fs->pwd_xrefs = 0;         write_sequnlock(&fs->seq);         if (old_pwd.dentry) -               path_put(&old_pwd); +               while (count--) +                       path_put(&old_pwd);  }  static inline int replace_path(struct path *p, const struct path *old, const s> @@ -70,6 +74,8 @@ void chroot_fs_refs(const struct path *old_root, const struct>                                 count++;                                 path_get(new_root);                         } +                       count += fs->pwd_xrefs; +                       fs->pwd_xrefs = 0;                         write_sequnlock(&fs->seq);                 }                 task_unlock(p); @@ -81,8 +87,11 @@ void chroot_fs_refs(const struct path *old_root, const struc>  void free_fs_struct(struct fs_struct *fs)  { +       int count = fs->pwd_xrefs + 1; +         path_put(&fs->root); -       path_put(&fs->pwd); +       while (count--) +               path_put(&fs->pwd);         kmem_cache_free(fs_cachep, fs);  } @@ -110,6 +119,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)         if (fs) {                 fs->users = 1;                 fs->in_exec = 0; +               fs->pwd_xrefs = 0;                 seqlock_init(&fs->seq);                 fs->umask = old->umask; diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 0070764b790a..0d79d51de240 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -8,10 +8,11 @@  #include  struct fs_struct { -       int users;         seqlock_t seq; +       int users;         int umask;         int in_exec; +       int pwd_xrefs;  /* Extra references of pwd */         struct path root, pwd;  } __randomize_layout; @@ -40,6 +41,31 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct p>         read_sequnlock_excl(&fs->seq);  } +static inline void get_fs_pwd_share(struct fs_struct *fs, struct path *pwd) +{ +       read_seqlock_excl(&fs->seq); +       *pwd = fs->pwd; +       if (fs->pwd_xrefs) +               fs->pwd_xrefs--; +       else +               path_get(pwd); +       read_sequnlock_excl(&fs->seq); +} + +static inline void put_fs_pwd_share(struct fs_struct *fs, struct path *pwd) +{ +       bool put = false; + +       read_seqlock_excl(&fs->seq); +       if ((fs->pwd.dentry == pwd->dentry) && (fs->pwd.mnt == pwd->mnt)) +               fs->pwd_xrefs++; +       else +               put = true; +       read_sequnlock_excl(&fs->seq); +       if (put) +               path_put(pwd); +} +  extern bool current_chrooted(void);  static inline int current_umask(void)