From nobody Thu Apr 30 00:39:02 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1776226116; cv=none; d=zohomail.com; s=zohoarc; b=Bfg276Md+wNQl5vohE5ZCQ4yXsTXrhk0AmEIECiZJhyseByroGJ6Dr4v72krE/ykx5ufulKZDg5YjtlDpVWl2rryQ4NzeLUDnPoxxsz6kjSdGrBuOIezLmxjqrmI346HaspnRRa/xF3ZRLk/6a/sQNfCBW/shWb+ae+Pj2a+tMI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776226116; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uqvJg/Mgtv6OwVCd/aP++X0wBdWO0zPsmqBCsAcI/WQ=; b=X4BFHL2rLuHBSL7kxtHZTr28Ws+BgI/+fiL6z91pNIPu7gNq3spfFDStHEvGM1X0pahhP82TXQB+ytNubAB95+9+sQI4zer7t8WgYVbnIz/2/25f4alvwM2cWe1yBbIJluhFmo3bXhGYtZl13KYCqjYKcJmps/LPJUq/AzdbiDo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 177622611646261.79692743678402; Tue, 14 Apr 2026 21:08:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wCrXf-0006n6-6r; Wed, 15 Apr 2026 00:07:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wCnee-0008F7-P8 for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:52 -0400 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wCnec-0003X9-Nb for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:52 -0400 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-43cf7258875so428958f8f.2 for ; Tue, 14 Apr 2026 16:58:50 -0700 (PDT) Received: from [192.168.10.11] ([182.181.137.32]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43ead3d5f11sm115535f8f.18.2026.04.14.16.58.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2026 16:58:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776211129; x=1776815929; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=uqvJg/Mgtv6OwVCd/aP++X0wBdWO0zPsmqBCsAcI/WQ=; b=gn1QZLriw27dIV7VAxwziwGLAI9ZsKlQjYJV41tgm+W1/z0HWjH7OCHjn+99IFFeDc 7VAd/y+UFfzPEyigEipnOiq6WwP30hA+rKUlGF2w8idE9iQSjXgX39woHt9M8ZCjS/uP Tcd4XUcehhSnUm3H2o+eZOqR2wQt/Jnmldyve5K6K0s2sQc5tH0QjzsEhajRSpozotNN HyrvlAmHtvb3ZultY3qfWIVRUuJ8ER1j4xoUr5rm4ri3C9TZhR33RxqDBWdZBbwFtsYv l7VlKcKl1rOHMPoZOldNGk31pZDzzx3TtdJ1FGdX63OO/qSIlIOUcSR7xUjMVf+MROXc Q6cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776211129; x=1776815929; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=uqvJg/Mgtv6OwVCd/aP++X0wBdWO0zPsmqBCsAcI/WQ=; b=cinv0EBwJ4fho3yXLQqoi7N3/Dfsgslxe8tuvSV6LElXAfJ0xDTAbuuN7qxYZlTNRn LGj9Y/srj0QkAzuVF9BhO+zBDeyOUorgfWd8yLNRCW2z+1FWMzZYsxpRx+ajGt1f+bmu 4ve4LOhh5eYTO8xNeHFs1E54kZFlPOVHIqpGHsYDw+ZBaa8Porsi5Rt4B0i2dnmfhkHQ HHol9AYwF9Uu3SL+13/7EOH8VjO5kQajVFXl2XfInV/cZ/TnUWlyVI7qDcGMk5/WadWB EOkP7XMCpoQpC4o2mzyLU2f5VOj7iI0bX17MeR6A3E13+5ch46Fi3AenPz+Ifd7i8yp1 nSzg== X-Gm-Message-State: AOJu0Yz9x0QWAN/eeAInJIo+YdhxyGffjTuY6RqZkPAua/mx2LCNsfHK rCrtRsJSiUyF4PtHFBVN7AA4Dda7Bnixp6ftCS0ilA1we1j83GUx92ua X-Gm-Gg: AeBDieuDBXeaD40YjLmwKhP1rHJFyJwy/p/A1JmiT7vAV1s6NLlKpYYrq7Dgn7TSmf+ rXKht0cRCzyHZeWXumYvvUTWCojbDLrUZtWTQ0knLsApXZwmWSx3wWckVc6EBu7Acf6nFoty1is IudD/rtFx6bBSv98orD3cOazzgtBjvPv27VyX4DlgjDj361iXvxn8QlMGMO89VLcZShOXiG23rx dYInE5QulZ8MlTaiUUdRHDCAP6SHYyOLFMpeLVWFv8g7TzauQSkzMhdPBwI8hIHIPt+fZXo/ovs fIIDpjOgpn/VpT0iu1QM2tcx/3Sl/QmAMbuJiUS5Gkqpn/H2Ra7BfJNFZBzJjjdELOkliTgxub/ rk4Z0o3VSmvTlxxoXLFzVCRflQSYKJ+B6t4agRKsjeHAcP6mwxM4j3hClTgsdYe6SC9YuHdilJV xcZfZhvr1CkULf8Mv0RIBQlYGXTKsoIBQH X-Received: by 2002:a05:6000:2109:b0:43d:74dc:7e9 with SMTP id ffacd0b85a97d-43eacfa1546mr117387f8f.1.1776211128977; Tue, 14 Apr 2026 16:58:48 -0700 (PDT) From: Ali Raza Date: Wed, 15 Apr 2026 04:58:34 +0500 Subject: [PATCH 1/3] linux-user: Filter /proc/*/task/ to hide QEMU-internal threads MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260415-master-v1-1-8dd2ef111eee@gmail.com> References: <20260415-master-v1-0-8dd2ef111eee@gmail.com> In-Reply-To: <20260415-master-v1-0-8dd2ef111eee@gmail.com> To: qemu-devel@nongnu.org Cc: Ali Raza , morgan@kernel.org X-Mailer: b4 0.15.2 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=elirazamumtaz@gmail.com; helo=mail-wr1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 15 Apr 2026 00:07:54 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1776226118111158500 When a guest process reads /proc//task/ via getdents/getdents64, the host kernel returns directory entries for all host threads in the process, including QEMU-internal threads (RCU, TCG workers) that have no guest CPUState. This causes problems for guest libraries like libcap's PSX that enumerate threads via /proc/self/task/ and send signals to each one -- signals sent to QEMU-internal threads are never handled, leading to deadlocks. Add filtering to do_getdents() and do_getdents64() that detects when the fd refers to a /proc//task/ directory and skips entries whose TID does not belong to a guest thread. Guest thread TIDs are identified by iterating the CPU list via CPU_FOREACH(), matching the existing pattern used for /proc/self/stat num_threads. This fixes the psx_test hang reported in containers using QEMU user-mode emulation for cross-architecture builds. Resolves: https://github.com/AndrewGMorgan/libcap_mirror/issues/6 Signed-off-by: Ali Raza (@locus-x64) --- linux-user/syscall.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 80 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f4b74ad350..b5a912dc22 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9108,6 +9108,50 @@ static int host_to_target_cpu_mask(const unsigned lo= ng *host_mask, return 0; } =20 +/* + * Check if a directory fd refers to /proc//task/ for the current + * process. Used to filter out QEMU-internal host threads (RCU, TCG) + * that are not guest threads from directory listings. + */ +static bool is_proc_pid_task_dir(int dirfd) +{ + char link_path[64]; + char link_target[PATH_MAX]; + ssize_t len; + char expected[80]; + int expected_len; + + snprintf(link_path, sizeof(link_path), "/proc/self/fd/%d", dirfd); + len =3D readlink(link_path, link_target, sizeof(link_target) - 1); + if (len < 0) { + return false; + } + link_target[len] =3D '\0'; + + expected_len =3D snprintf(expected, sizeof(expected), + "/proc/%d/task", getpid()); + return strncmp(link_target, expected, expected_len) =3D=3D 0 + && (link_target[expected_len] =3D=3D '\0' + || link_target[expected_len] =3D=3D '/'); +} + +/* + * Check if a given host TID belongs to a guest thread by looking it up + * in the CPU list. Must be called under RCU read lock. + */ +static bool is_guest_tid(pid_t tid) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + TaskState *ts =3D get_task_state(cpu); + if (ts->ts_tid =3D=3D tid) { + return true; + } + } + return false; +} + #ifdef TARGET_NR_getdents static int do_getdents(abi_long dirfd, abi_long arg2, abi_long count) { @@ -9116,6 +9160,7 @@ static int do_getdents(abi_long dirfd, abi_long arg2,= abi_long count) int hlen, hoff, toff; int hreclen, treclen; off_t prev_diroff =3D 0; + bool filter_task =3D is_proc_pid_task_dir(dirfd); =20 hdirp =3D g_try_malloc(count); if (!hdirp) { @@ -9150,6 +9195,23 @@ static int do_getdents(abi_long dirfd, abi_long arg2= , abi_long count) =20 namelen =3D strlen(hde->d_name); hreclen =3D hde->d_reclen; + + /* + * Filter /proc//task/ listings to hide QEMU-internal + * host threads (RCU, TCG) that have no guest CPUState. + */ + if (filter_task) { + char *endp; + long tid =3D strtol(hde->d_name, &endp, 10); + if (tid > 0 && *endp =3D=3D '\0') { + WITH_RCU_READ_LOCK_GUARD() { + if (!is_guest_tid(tid)) { + treclen =3D 0; + continue; + } + } + } + } treclen =3D offsetof(struct target_dirent, d_name) + namelen + 2; treclen =3D QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent)= ); =20 @@ -9203,6 +9265,7 @@ static int do_getdents64(abi_long dirfd, abi_long arg= 2, abi_long count) int hlen, hoff, toff; int hreclen, treclen; off_t prev_diroff =3D 0; + bool filter_task =3D is_proc_pid_task_dir(dirfd); =20 hdirp =3D g_try_malloc(count); if (!hdirp) { @@ -9226,6 +9289,23 @@ static int do_getdents64(abi_long dirfd, abi_long ar= g2, abi_long count) =20 namelen =3D strlen(hde->d_name) + 1; hreclen =3D hde->d_reclen; + + /* + * Filter /proc//task/ listings to hide QEMU-internal + * host threads (RCU, TCG) that have no guest CPUState. + */ + if (filter_task) { + char *endp; + long tid =3D strtol(hde->d_name, &endp, 10); + if (tid > 0 && *endp =3D=3D '\0') { + WITH_RCU_READ_LOCK_GUARD() { + if (!is_guest_tid(tid)) { + treclen =3D 0; + continue; + } + } + } + } treclen =3D offsetof(struct target_dirent64, d_name) + namelen; treclen =3D QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent6= 4)); =20 --=20 2.43.0 From nobody Thu Apr 30 00:39:02 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1776226115; cv=none; d=zohomail.com; s=zohoarc; b=HWUDlmfH+f+7405SWlnVbMXTKgS7P/XZUewobrWuZfitAIBvgdfGHGsfNmgw5zkfKGHTOAtFFN3uym4hkL6uDxDnE0UxltP62+R4ZC8dx5tC74i49iumQriuwVPsjWj79BClr5adKqUikNX7HZ8PH6ZziHHIfNmiO/efPQfK2D8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776226115; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kHFAcl/jzvkoKQBJ6saCtlCSuiizvOoPEDXt1Y+LFq8=; b=fSEIAQBM0FpKQNarWaEEgMKieVRVz9yqs9udca1CMq3lRKXlNeIeekB60ThNSGY4lXkHj3dG8YO83u87wUkXhd717V+6tMB0lgvI8OFEE52BqnKgiM61FDiZ1Vrka20qypcn59jR3+jO/S4EO1giRXMPzUphdZoFzIvk2BoMHnc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776226115987748.971988213195; Tue, 14 Apr 2026 21:08:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wCrXk-0006nv-CT; Wed, 15 Apr 2026 00:08:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wCneg-0008FH-4X for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:54 -0400 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wCnee-0003XT-I2 for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:53 -0400 Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4832c8f9d87so9049675e9.3 for ; Tue, 14 Apr 2026 16:58:52 -0700 (PDT) Received: from [192.168.10.11] ([182.181.137.32]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43ead3d5f11sm115535f8f.18.2026.04.14.16.58.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2026 16:58:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776211131; x=1776815931; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=kHFAcl/jzvkoKQBJ6saCtlCSuiizvOoPEDXt1Y+LFq8=; b=isA1l+pK64WbYxJREb7ZYIXQ5HbipPsN+46nl8aplIgMG2BkrYZAHDvQ24va2ls+0w 1MNoKy3HElRnlK1ndB7QGaVlaTwzKdKmOVMauJbN7s3eXMAfq1zl7t5Yf0ADyXePSIeD TTCwySGyMbrXjioJ1VvSSvxu2u2B9EqiF37dznnwL8wqRhy+Gb4ZDJU+PiRpRyQ0fPR/ Kc/z+hGBz0a2SH+ELorbRkKtZXMcEiEir4DPjmaY4+SyJXHGq9HQcwFmR8+vpUmIfBFc csQ33FLSxEWCZAbrS8zunzS/LTM3Nnk5UogmdJCo83JPiV0dT1mIHxVtdzl/PGNAIbwy Q2eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776211131; x=1776815931; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=kHFAcl/jzvkoKQBJ6saCtlCSuiizvOoPEDXt1Y+LFq8=; b=J0RXQsUuxLRi0j+xwYJ94hQ7eo0IbXdziasJVnM8sRcJkUQhtlomVGqc+hCasGfPtG Ib8Q43qtRTwpkoyNdc2hb4m9HU/xErhE6KYvoAak5RMF722qeFJhAf+i1YT3iwI0uoKb znL+J5YgzADv1Esb9H1MKuwzGgCPaZ9I1TTScROKjQDJgvX1Fxs84fuA9kvytJ8bTAgf 6/8fSU1pO0lp8tm5SAh9ZOwmWRjsS1JpFlrkIPkAKzcXdRYmiSYnnk3zXc3gaCCaysUO pmTtx3oKm0DZijJ3hMFnSZfoBmxoNe6YiIBxxI62A6bSAQPPchD+JPTCH2AjJJtYjY9N o1dA== X-Gm-Message-State: AOJu0YxKo5EQt0rbEkcXUe5iHA4UklI08s0PnfJ384M9xLEZ2UYev814 esg1mz3oQCv7ge+4feUAfZWQ+nLRxa+mibfJ0M4HVV4Mx/0uU2lDneF8Atn9cfPO X-Gm-Gg: AeBDieu1kcEu14CAk+KTnSxCGXY/9MOCW5nnYaU4m1fenif5fST+d4UFRcaRT4bQUIF BGdhKgQ4IIA09hZtKgruAy1TUKjPo7zQh8Nhh19l8UdWBvixqxNmEkoz13/piWPgx09u450ahcC tMQZk8YGuqNY9pw4Quakgcwhl7mZfoZDzBhubqKzzRPI1+67ATcCdmIY/wvbxVh8rpfQCJI+0aj 2dKm3ZjviBk6EH4EnhNq/bllLfgOwXzs/F0I222xNGKYMfUd5YjZ/O6GhL4TNgO0ciSqttpg8Qa vvpG6ftKRJAoawGTUC7wJkQLoi8bMqoWZ0y+UqwXDpz5psPwDzDZSHR8C5rWfknTMZ4c7E5h8m7 KQqUWq+GW/JsjW3JKaq/TIwN4xDdJU31gsy2CqIa3IQD9GWlZyvZP4o2wi4rpOLFhJpEMyjknHV 8qQZ0JOeN7lQUZW+Q1hcIgfljjzz7EGqpx X-Received: by 2002:a5d:5d01:0:b0:43c:fd0b:c5c5 with SMTP id ffacd0b85a97d-43eacf77b7fmr171133f8f.6.1776211130863; Tue, 14 Apr 2026 16:58:50 -0700 (PDT) From: Ali Raza Date: Wed, 15 Apr 2026 04:58:35 +0500 Subject: [PATCH 2/3] linux-user: Validate tkill/tgkill targets are guest threads MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260415-master-v1-2-8dd2ef111eee@gmail.com> References: <20260415-master-v1-0-8dd2ef111eee@gmail.com> In-Reply-To: <20260415-master-v1-0-8dd2ef111eee@gmail.com> To: qemu-devel@nongnu.org Cc: Ali Raza , morgan@kernel.org X-Mailer: b4 0.15.2 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::336; envelope-from=elirazamumtaz@gmail.com; helo=mail-wm1-x336.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FORGED_GMAIL_RCVD=1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 15 Apr 2026 00:07:57 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1776226119074154100 The tkill and tgkill syscall handlers pass the guest-supplied TID directly to the host kernel without checking whether it belongs to a guest thread. This allows a guest to send signals to QEMU-internal host threads (RCU, TCG workers) that have no CPUState and no guest signal handlers, which can cause hangs or disrupt QEMU operation. Add validation that checks the target TID against the guest CPU list before forwarding the signal to the host. For tgkill, also verify that the tgid matches the current process. Return -ESRCH for TIDs that do not correspond to any guest thread, matching the behavior a real kernel would return for a nonexistent thread. This complements the /proc/*/task/ filtering in the previous commit to provide defense-in-depth: even if a guest discovers or guesses a QEMU-internal thread TID, it cannot send signals to it. Signed-off-by: Ali Raza (@locus-x64) --- linux-user/syscall.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b5a912dc22..a075b9a90b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -13449,11 +13449,41 @@ static abi_long do_syscall1(CPUArchState *cpu_env= , int num, abi_long arg1, #endif =20 case TARGET_NR_tkill: - return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2)= )); + { + int tid =3D (int)arg1; + /* + * Reject signals to host threads that are not guest threads. + * QEMU-internal threads (RCU, TCG) share the host PID but have + * no CPUState and cannot handle guest-originated signals. + */ + WITH_RCU_READ_LOCK_GUARD() { + if (!is_guest_tid(tid)) { + return -TARGET_ESRCH; + } + } + return get_errno(safe_tkill(tid, target_to_host_signal(arg2))); + } =20 case TARGET_NR_tgkill: - return get_errno(safe_tgkill((int)arg1, (int)arg2, + { + int tgid =3D (int)arg1; + int tid =3D (int)arg2; + /* + * Validate that the target TID is a guest thread. Also verify + * that the tgid matches our process, since all guest threads + * share the same host tgid. + */ + if (tgid !=3D getpid()) { + return -TARGET_ESRCH; + } + WITH_RCU_READ_LOCK_GUARD() { + if (!is_guest_tid(tid)) { + return -TARGET_ESRCH; + } + } + return get_errno(safe_tgkill(tgid, tid, target_to_host_signal(arg3))); + } =20 #ifdef TARGET_NR_set_robust_list case TARGET_NR_set_robust_list: --=20 2.43.0 From nobody Thu Apr 30 00:39:02 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1776226119; cv=none; d=zohomail.com; s=zohoarc; b=i1QtolkHvqsgSPv+vdnY6FBmqjPPFM8szmkMQLqf2vtdkQh56pa3agJ9zgZWLYch9a5HHqTHWWXtiZNCACMuBsNXvZDoMWnxtCzZyjYnhtS+WDeUchHC+f0USsa+LhS/w/4TJB49IPLozhPVhDNs2ZKtTIQEw1rFsCNTUltjLVY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776226119; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=iO17NpRgpPKsJF/GBSlvS4CvmUeJukcd4DXozhw0GlA=; b=VYNjgU1KNZ6f4axgjjHxhGlIpGgg9MhJRwpoIhuCPmoJhppX6LMyLlpGaPlt+6wecBokPM0/n02+YAqL5d0aKI+7njISU9lg1VQoOEpW3+TqJmgsTl2908WxhxqFmebtoWFAorWDzKlRGtM639XE0Ebchg9f0JigFB9kDilg81c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1776226119288865.674886665346; Tue, 14 Apr 2026 21:08:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wCrXo-0006pC-8j; Wed, 15 Apr 2026 00:08:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wCnei-0008Fu-G6 for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:56 -0400 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wCneg-0003Xu-Cl for qemu-devel@nongnu.org; Tue, 14 Apr 2026 19:58:55 -0400 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-43cf5f6d2eeso296181f8f.0 for ; Tue, 14 Apr 2026 16:58:54 -0700 (PDT) Received: from [192.168.10.11] ([182.181.137.32]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43ead3d5f11sm115535f8f.18.2026.04.14.16.58.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2026 16:58:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776211133; x=1776815933; darn=nongnu.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=iO17NpRgpPKsJF/GBSlvS4CvmUeJukcd4DXozhw0GlA=; b=ESkQ6aRkSeoj0FUiMMUjxlA8lCl4zBjSGf6JDivRJeL35CDXh5Ga1qH5WWEQZA/nrW p3ywza94MMK7I1AinUCorLgHPspwoGpZwatskgbiTn3ZaqSK7F+7rQzM1ZsLwf9hGubq U4N0CfgS+0O//jXFNH1OIDXdAv1nUWqQNFx9CFPq8xSCOrPJuPyi1I3HVkh0i3oWuJHO d5bifwYuaYRSRZuuDSW1RGveiBxws2hmw206BX3Z1lIKVGX7qnpx0nAZ0ucNKKpLvNEN gPMWld1HjQBMlHZ6g9Kh/DbkgZhG17RYgLW5ZtdK2ucaWWjSJwCvvDOsqg2hbp6+MSRt nNxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776211133; x=1776815933; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=iO17NpRgpPKsJF/GBSlvS4CvmUeJukcd4DXozhw0GlA=; b=m+PIDqeYGWEtThrdzL1Xl9NqAN9hTgXFKsc+W6SqfPXn3wtuompeOVz1c6fTddnqSW p+e8X/oZU0WxtWA8jHbNyphL8Tlu4qml3Ccx+sgmtRS/tjbVrHASQMpTS48wvn59h+e2 Tuq5CQm2qR8pYPSz4L8dY26mXfwi0wb8OY6VNZcEbfHwGJw4DwYYpYSjoZwiZGD/RZU5 1j0+oy0H6Cs2OqFytZbOdiKQtn4c5vtyih0hzadpoEmty/6ogWVMgS688oAQt97PbmzK j1A8gx/rVYkn6t3TyXoZTJHsRogNA1nKoTaw1TBSn9UALYdDitYhRpDJbcv/23Z/D88s GF5A== X-Gm-Message-State: AOJu0YxljIx04AUg6kdAPLlzpPCJ3VRCiFq9ciXufYoMNsAwamtYUAmI im3OfPG68g7bhg9i7HmDYRwRe/OddaCf4zQbRw7HSRiska+G+Z9jEf8P X-Gm-Gg: AeBDietZPUg6shHVy5uRRfSy+AZj6bCNpHYy/I+yf2cnWJTEuh+jiOR0bFszizZHS0I 7mb7bNIYaUPhgpjFjD+081OtWOaV1H2LZ9qgdsVqMczJnyoWzwDZdr3BPhPm808+jBimuXvddvY xEz0zMzJnM4RfB5Bb5K/MfzjwOciL5Pym3TPuJpXypeb49IloCrhzWufzWErjw9Nm7VELeJEOgy kWkrm9j1aQP/wvcC9R/Ux/DzrSLidMp1AFlO1ujSarmOScysYGu+/bLMyXc90w8+ogN1OYs1WWe wrp/x57G1XDwAhZGYLlV5q0FkUuEcusAsqMgeaMFobYxgsxErtm6UUGEd8hdT8X6id5WD65SThQ wP9SA3DBtxFVd/Ja3cMlPl2pwvZ2upWPKcEeUvhjT6Bq+gyU9o6n4aA9IJyUTPKzdcOO2exBFos esLrWm8GsFnmd6/QEfXKbMsq4T/ghZz7rQ X-Received: by 2002:a05:6000:2705:b0:43d:b99:bdca with SMTP id ffacd0b85a97d-43eacf72c8dmr105019f8f.6.1776211132774; Tue, 14 Apr 2026 16:58:52 -0700 (PDT) From: Ali Raza Date: Wed, 15 Apr 2026 04:58:36 +0500 Subject: [PATCH 3/3] tests/tcg: Add test for /proc/self/task/ filtering and tkill validation MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260415-master-v1-3-8dd2ef111eee@gmail.com> References: <20260415-master-v1-0-8dd2ef111eee@gmail.com> In-Reply-To: <20260415-master-v1-0-8dd2ef111eee@gmail.com> To: qemu-devel@nongnu.org Cc: Ali Raza , morgan@kernel.org X-Mailer: b4 0.15.2 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=elirazamumtaz@gmail.com; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Wed, 15 Apr 2026 00:08:00 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1776226119899158500 Add a multiarch linux-user test that verifies: 1. /proc/self/task/ only lists guest threads -- spawns NUM_THREADS pthreads, reads the task directory, and asserts every entry maps to a known guest TID and the total count matches. 2. tkill(guest_tid, 0) succeeds for all guest threads. 3. tkill to a non-guest TID returns ESRCH. On native Linux this test trivially passes since there are no QEMU-internal threads. Under QEMU user-mode, it exercises the getdents64 filtering and tkill validation added in the previous two commits. Signed-off-by: Ali Raza (@locus-x64) --- tests/tcg/multiarch/Makefile.target | 2 + tests/tcg/multiarch/linux/linux-proc-task.c | 178 ++++++++++++++++++++++++= ++++ 2 files changed, 180 insertions(+) diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Make= file.target index 508149d57b..8d6e2af617 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -39,6 +39,8 @@ testthread: LDFLAGS+=3D-lpthread =20 threadcount: LDFLAGS+=3D-lpthread =20 +linux-proc-task: LDFLAGS+=3D-lpthread + signals: LDFLAGS+=3D-lrt -lpthread =20 munmap-pthread: CFLAGS+=3D-pthread diff --git a/tests/tcg/multiarch/linux/linux-proc-task.c b/tests/tcg/multia= rch/linux/linux-proc-task.c new file mode 100644 index 0000000000..805cfd4e47 --- /dev/null +++ b/tests/tcg/multiarch/linux/linux-proc-task.c @@ -0,0 +1,178 @@ +/* + * Test that /proc/self/task/ only lists guest threads. + * + * Under QEMU user-mode emulation, the host process may contain + * internal threads (RCU, TCG workers) that are not guest threads. + * These must be hidden from directory listings of /proc//task/ + * and signals to non-guest TIDs must return ESRCH. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_THREADS 3 + +static pid_t guest_tids[NUM_THREADS + 1]; /* +1 for main thread */ +static int num_guest_tids; +static pthread_barrier_t barrier; + +static pid_t gettid_sys(void) +{ + return syscall(SYS_gettid); +} + +static void *thread_func(void *arg) +{ + int idx =3D (int)(intptr_t)arg; + + guest_tids[idx] =3D gettid_sys(); + pthread_barrier_wait(&barrier); + + /* Wait for main thread to finish testing. */ + pthread_barrier_wait(&barrier); + return NULL; +} + +/* + * Read /proc/self/task/ and return the count of numeric entries + * (thread TIDs). For each entry, verify it matches a known guest TID. + */ +static int count_and_verify_task_entries(void) +{ + DIR *dir; + struct dirent *de; + int count =3D 0; + + dir =3D opendir("/proc/self/task"); + assert(dir !=3D NULL); + + while ((de =3D readdir(dir)) !=3D NULL) { + char *endp; + long tid; + int i, found; + + if (de->d_name[0] =3D=3D '.') { + continue; /* skip "." and ".." */ + } + + tid =3D strtol(de->d_name, &endp, 10); + if (*endp !=3D '\0' || tid <=3D 0) { + continue; /* non-numeric entry */ + } + + /* Every TID in the listing must be a known guest thread. */ + found =3D 0; + for (i =3D 0; i < num_guest_tids; i++) { + if (guest_tids[i] =3D=3D (pid_t)tid) { + found =3D 1; + break; + } + } + if (!found) { + fprintf(stderr, "FAIL: /proc/self/task/ contains unknown TID %= ld\n", + tid); + fprintf(stderr, " Known guest TIDs:"); + for (i =3D 0; i < num_guest_tids; i++) { + fprintf(stderr, " %d", guest_tids[i]); + } + fprintf(stderr, "\n"); + } + assert(found); + count++; + } + + closedir(dir); + return count; +} + +/* + * Verify that tkill(tid, 0) succeeds for all guest TIDs and that + * tkill to a TID that should not exist returns ESRCH. + */ +static void test_tkill_validation(void) +{ + int i, ret; + + /* Signal 0 to each guest TID should succeed. */ + for (i =3D 0; i < num_guest_tids; i++) { + ret =3D syscall(SYS_tkill, guest_tids[i], 0); + if (ret !=3D 0) { + fprintf(stderr, "FAIL: tkill(%d, 0) returned %d (errno=3D%d)\n= ", + guest_tids[i], ret, errno); + } + assert(ret =3D=3D 0); + } + + /* + * Try a TID that is very unlikely to be a guest thread. + * Use pid_max (typically 4194304) minus 1 as a probe. + * On a real kernel this would return ESRCH for a nonexistent thread; + * on QEMU with validation it should also return ESRCH. + * Skip this check if the TID happens to exist (unlikely). + */ + ret =3D syscall(SYS_tkill, 4194303, 0); + if (ret =3D=3D -1 && errno =3D=3D ESRCH) { + printf("tkill to non-guest TID correctly returned ESRCH\n"); + } +} + +int main(void) +{ + pthread_t threads[NUM_THREADS]; + int i, task_count; + + pthread_barrier_init(&barrier, NULL, NUM_THREADS + 1); + + /* Record main thread TID. */ + guest_tids[0] =3D gettid_sys(); + num_guest_tids =3D 1; + + /* Spawn worker threads. */ + for (i =3D 0; i < NUM_THREADS; i++) { + int ret =3D pthread_create(&threads[i], NULL, thread_func, + (void *)(intptr_t)(i + 1)); + assert(ret =3D=3D 0); + } + + /* Wait for all threads to record their TIDs. */ + pthread_barrier_wait(&barrier); + num_guest_tids =3D NUM_THREADS + 1; + + printf("Guest TIDs:"); + for (i =3D 0; i < num_guest_tids; i++) { + printf(" %d", guest_tids[i]); + } + printf("\n"); + + /* Test 1: /proc/self/task/ entry count matches guest thread count. */ + task_count =3D count_and_verify_task_entries(); + printf("/proc/self/task/ entries: %d, expected: %d\n", + task_count, num_guest_tids); + assert(task_count =3D=3D num_guest_tids); + + /* Test 2: tkill validation. */ + test_tkill_validation(); + + /* Release worker threads. */ + pthread_barrier_wait(&barrier); + + for (i =3D 0; i < NUM_THREADS; i++) { + pthread_join(threads[i], NULL); + } + + pthread_barrier_destroy(&barrier); + + printf("PASS: /proc/self/task/ filtering and tkill validation\n"); + return EXIT_SUCCESS; +} --=20 2.43.0