From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) (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 A6BFF191 for ; Fri, 15 May 2026 00:04:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.169 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778803499; cv=none; b=BmJabwALPdGFEkyCpifv3mEdksIgHWd/EOTWpby4zMSsOI9YepHBgy2+efvltj5W2Rd4B4ubO9Mlb2br9qLVwt/jgfW6GSIu4K8bRap3nSpXB30bqBe+r7S3lzp5zCTEyfDYFHJbTfEVyHACowQEdo+ImZXrQtVd2ovCKP6P63I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778803499; c=relaxed/simple; bh=vdNgZCZdWt63/Sx4w68lGBiH5zzyjB7gRto9jnmGZKM=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=F7GMeVLBCqguGjVi+yzOWB2DRBOada0OMPEQ3oMQa4XouByfwL9hu3eiNJEKxL8a/yIGlOSLwIn3pN+hU2FAAPkqRs8stlmtkziYv3jzl6jPtTaHHq5JvWTE6JHf9ULmEEiD0jzEI0ocJWJ4yPWFf+5gkr6slOI1xot8trNP3iY= 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=YRQqHrGc; arc=none smtp.client-ip=209.85.210.169 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="YRQqHrGc" Received: by mail-pf1-f169.google.com with SMTP id d2e1a72fcca58-83ef1d17904so3378789b3a.1 for ; Thu, 14 May 2026 17:04:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778803498; x=1779408298; darn=vger.kernel.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=irCFDIT0zbeJD8rr5msRzKFBiU62wVt6m9l4r3WQEOw=; b=YRQqHrGcUkjofYEH4apg2rCIVI2FdZ9z8xNgT6qdYkaqzXh9GAz8fmw9iHPHdtU2jR rKL1CnHzDjUdjJlpz/vQZez0qZ6l5teYYethiWvJJfSxVv1arXItYsFk8fnt+Go83M2/ sTTbggKT1N0u1z6LJCKdXhUCMs9lKdbk0h7cqUcuB7o4PuTCIgtgRboUOmLL6DA92eRE M/NSw7T/Ucca+M8jBB7gPjKHwpbrw2QXLyjDHyTOtN1KAkpj4nK5rBX9fe8/BT6cZTYf s/7xB3hP2M9E5BqMSCSZBELsiayRSqlrSNixrMCo0o7Q5GXZMJ+iB2+SohcnWhDRmzij d9VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778803498; x=1779408298; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=irCFDIT0zbeJD8rr5msRzKFBiU62wVt6m9l4r3WQEOw=; b=N6Sb6/5yKsXVDNEN4dJgKTeWFU2OX4mFHlLeUOp82yIqUlaqbwp9zS3IA/fitW3r/S ZbQWQbsqOhq7BC5wTJs3bhUVqB7rXcNQcYyeF+5rhT9VfW/5VnRc6YizJ7TVG+eCAGVW S0BnuTog0ywpFCx0xlPJlK1fhmUfuks6VqDVhXrhG9nxelfpycwYiTGzZovlt/LiKNAz GCUfmlN7K2SuhW9941m2kTNpEpuMgjqGEwCXLwOzI+lIaHKObzxfYHxi7Yxyp7340IZJ RDuDPzNnO8bK2jEtYHv1epiDIB39YfEWQi9SEc7EpzrJ8VBhl72jKf5+2V0TNXlU6KiI ZLzA== X-Gm-Message-State: AOJu0YwiJRaztE2eE42qrt73Csx5Apk/X3JDUPL6isVz7QwYaqZc8NEW YMoJUYk2NQMOg0dnBZTFOHCGYA2Rw4Mc6SraAEqQ2IuZjuAQ/KWed3bm X-Gm-Gg: Acq92OEPDzYKvD1svnQ1ptyTsG/4a+24ocGUfml52W/psBBZixGha2Qz6865fvmaAfi lWC2OQcRtMlSNSdFNzvp7YIWbHf97Xfs3HH3up6bnk160wU4PraqAfCpajtxAZSwKYu6Rf+Jpz3 Tcfy35EYxFdJmWte9+cBnxIbSViuAkXxxqgExrTPvUGC8Xo58d4w/ApfOr95v4+h2WdGUFKebES noyC7qmHT/YRHnvULJDcH5cg5xqCvM1aOMRGrfsvo+mOzuNfgZHo5zW2PC8IaYGgOtSA8a39RQL /GcNYfs5TZyHEdaDzAhKbVkNB6xurCHal08p5aZwQFN2J6zQhuSmvfBB27JzEFfcL3p34Rki0iT FKSkuV8N6r2gVFi+rO8mBqSgGGZlVCoRS2pXUBQjsbXVMf9wthQlHTS6urcyip8JZO5WbXQVzj9 s7QbNgGN4z5RqBAfphP0X+ExivNWdOoIWHLDOO2GkP5AT9jOpenvMESA== X-Received: by 2002:a05:6a00:1908:b0:82f:50cd:e586 with SMTP id d2e1a72fcca58-83f33cb2c40mr1600341b3a.13.1778803497814; Thu, 14 May 2026 17:04:57 -0700 (PDT) Received: from v4bel ([58.123.110.97]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83f1966471dsm3886473b3a.6.2026.05.14.17.04.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 May 2026 17:04:57 -0700 (PDT) Date: Fri, 15 May 2026 09:04:53 +0900 From: Hyunwoo Kim To: oleg@redhat.com, mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org, torvalds@linux-foundation.org, qsa@qualys.com, kees@kernel.org Cc: linux-kernel@vger.kernel.org, imv4bel@gmail.com Subject: [PATCH] ptrace: prefer live sibling mm over user_dumpable when task->mm is NULL Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline task_still_dumpable() reads task->user_dumpable when task->mm is NULL. That cache is written exactly once in exit_mm(): a single get_dumpable(mm) load taken just before task->mm is cleared. The load is not ordered against set_dumpable() writes performed by CLONE_VM siblings, either via commit_creds() (any uid/gid/fsuid/fsgid or capability transition) or via prctl(PR_SET_DUMPABLE). If a sibling stores SUID_DUMP_DISABLE after the exiting thread observed SUID_DUMP_USER, the live shared mm and the cached value diverge with no later refresh, so task_still_dumpable() keeps returning the stale SUID_DUMP_USER answer for the exiting task. In the task->mm == NULL branch, walk the thread group under rcu_read_lock and spin_trylock(&t->alloc_lock); use the first sibling that still holds the shared mm and read its current get_dumpable(). Pin the mm's user_ns with get_user_ns() so it can outlive the locked region (the actual ptrace_has_cap() may sleep). Keep task->user_dumpable only as the fallback when no live sibling mm is observable: a single-threaded exit, a PF_KTHREAD, or all siblings simultaneously contended on alloc_lock. Fixes: 31e62c2ebbfd ("ptrace: slightly saner 'get_dumpable()' logic") Signed-off-by: Hyunwoo Kim --- kernel/ptrace.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 130043bfc209..2b2d8402b9ee 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -272,15 +272,59 @@ static bool ptrace_has_cap(struct user_namespace *ns, unsigned int mode) return ns_capable(ns, CAP_SYS_PTRACE); } +static bool task_sibling_mm_dumpable(struct task_struct *task, + unsigned int mode, bool *result) +{ + struct task_struct *t; + bool found = false; + + rcu_read_lock(); + for_each_thread(task, t) { + struct mm_struct *sib_mm; + struct user_namespace *sib_uns; + int sib_dumpable; + + if (t == task) + continue; + if (!spin_trylock(&t->alloc_lock)) + continue; + sib_mm = t->mm; + if (!sib_mm) { + spin_unlock(&t->alloc_lock); + continue; + } + sib_dumpable = get_dumpable(sib_mm); + sib_uns = get_user_ns(sib_mm->user_ns); + spin_unlock(&t->alloc_lock); + + if (sib_dumpable == SUID_DUMP_USER) + *result = true; + else + *result = ptrace_has_cap(sib_uns, mode); + put_user_ns(sib_uns); + found = true; + break; + } + rcu_read_unlock(); + return found; +} + static bool task_still_dumpable(struct task_struct *task, unsigned int mode) { struct mm_struct *mm = task->mm; + bool sib_result; + if (mm) { if (get_dumpable(mm) == SUID_DUMP_USER) return true; return ptrace_has_cap(mm->user_ns, mode); } + /* user_dumpable can be stale; prefer a live sibling mm if any. */ + if (!(task->flags & PF_KTHREAD) && + task_sibling_mm_dumpable(task, mode, &sib_result)) + return sib_result; + if (task->user_dumpable) return true; return ptrace_has_cap(&init_user_ns, mode); -- 2.43.0