From nobody Sun May 24 19:33:15 2026 Received: from mail-qv1-f54.google.com (mail-qv1-f54.google.com [209.85.219.54]) (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 0C97D3612E0 for ; Thu, 21 May 2026 22:17:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779401851; cv=none; b=mtq/UCR7/tKCkwnNtD7VF2H3ShYnwfmxm2g57YvuYmYOGGpvBCDlodM8R2SIA2mFtwiioHAVl94IhOzJHFCFPKW0YxnZguIoIy6uJfuqOgSXaMQqA+UIAlhE2lk/pFEYHwugB2VPCwzARgVoehIeAmI6gy3cjLf0FZI2qDEKWns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779401851; c=relaxed/simple; bh=A6lXaczDHjgNevA0lmJSvS4vtc7KtIgT6xdB5gyEfL4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=sS9m66cEvt2OCFgT5ucx1dKLF9fyHpu+GPnXTuxZp8wGt2ISbdAcFWOTDapnnOW4sl+ve0otiHYGgdCgV/0nPoyjJqxhQyJqkz4E3kYTmwcz1I/LOaOP0oNyk3UvXspZMI5OG6A+lbwXGjtfiXf3lG1P9eTmJWx6aX4uSH0Vsno= 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=gCNEQk+X; arc=none smtp.client-ip=209.85.219.54 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="gCNEQk+X" Received: by mail-qv1-f54.google.com with SMTP id 6a1803df08f44-8b59772d441so82288356d6.0 for ; Thu, 21 May 2026 15:17:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779401848; x=1780006648; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=hU0DVCjQqwiePLyt3GmtYtEALmWzYB8I3V+uH1gF4Rc=; b=gCNEQk+XYIJns7O0eI0/4S6wd61rjPiRge41Ta7XyY7s9nFfOTkCYISCaeHnDPKPtc i52FNbbxFNR0k20q9xZoXI4B4LCKv23l6mP6VFG7JrAChvA8QCS7MKHz2IkGSxcU5Toc Xv4aiu/N5OQQOxb7KNW+/MLy2l3+I/kU7Px5q7t+N148//yyuLaG2GiUBJJmK46ckIiJ OHmfA3M0w4YaTo/eMJsllHx619kiVP94v03xHYMfFRVf9/AeJ5Toxv8ZRGzQS9eUVxxv e1//me0XSGlqxaSzw7df8cIN3Yd94utnDPQ0otuHSq/7DwGZJqXx2uCe9maIYXbqvk6S y4pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779401848; x=1780006648; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=hU0DVCjQqwiePLyt3GmtYtEALmWzYB8I3V+uH1gF4Rc=; b=eJxU8QGB4rz0Ek/lOTrWd54tDy9aU8NIKC+Kn0WLKPRyjwubDHXMS2HNiHTmaCoxra WOaSe6vq21X+Ref8ZMpzOtf/oCwI9MBEqTJfHnBMP4uzHdUgbHkGwtJreWweE/oOOmdZ aCMtTjUEPx6L52Ku2yIt+J8rWFQE/SKssp/0q+LvZOBR44PO01l0kDEcwxq2wpumKR4j BsWzAuWcF3R+F1emF5xwbS5rJxYT+6xM4DRbRjN+I7dgPTaIGs7ysfQ9MUyb3+Sz0T52 oFIyp4UmVa/CwpADcnRTLoP8Cw2aDqxHV26jaxBUIUokIIrQmXR+HzygqLgpcJT8p9Cd FBBA== X-Forwarded-Encrypted: i=1; AFNElJ/vECIwSiCnfReN/mNiNsJzDXWupZzvFAnBQ2eJkCIu5oe+zn/4tl9HR1jJGI2Rc4YcQ0u+KDw3/ISKvuU=@vger.kernel.org X-Gm-Message-State: AOJu0YznwbUeT098Q1rhIj8oFuggFakCntKXVM3sAqAwTHI8SRR6QmY4 MaRnhQtxA2+c4De2YUdTY/ljWbjFz/snnMnJv8qo/Rm18IztXkAGXEMY X-Gm-Gg: Acq92OF2ZkLM2ZKp2YKN9SwKFOsAkbv0ZFoesNex0eyv7xXxMznzJbPOql3uJFfN/3n Y1rnLdKUSkC1h8yqFiCeTeBjWmD6e8TYSWhsKMZrxRnj4X/h+fOPgScJkzxQHxfmWwsyxllX/UZ U8SdouPIbmEplKGcNydPy1i3+RsRa0e+Vu+iL3AMgKZTsqIXBNr9O8Pf3MIBbBQHzBoInaFy8lQ Ry3oCzwbOrORu4Gu/XIj39gzvguXYOmAZANLpa7USfXbAeagd9ShYTR0S5iMxrIF1ZkqG6Kze12 Mlr8OXe9H5GKMmeu7NRMVqMbDHtSUFtjE23uJBabTfZ3K/ErmnRE/sTRPq38+Z1sU9PPdlh6oe2 YOatrx1RlUw2YcUexYqghJV9iaCMvjBmeugobb1voNnBPIzngXfvv7nowVL/Ms65/AwEEesrFBS ZXZpx6tCOLADMHHApIUifMtt6ZxnUJRnEAUY4NF6Vn7cxduiszFQ1sHBAvXIIfTkeGtSa29hzvt h9tKe+q5a/7kDdHwZbk12Mp2nFrV4c= X-Received: by 2002:ac8:7e91:0:b0:509:3257:c050 with SMTP id d75a77b69052e-516d42e2cafmr18941051cf.24.1779401847508; Thu, 21 May 2026 15:17:27 -0700 (PDT) Received: from server0 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-516d63018fesm3590071cf.1.2026.05.21.15.17.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2026 15:17:27 -0700 (PDT) From: Michael Bommarito To: Andrii Nakryiko , Eduard Zingerman Cc: Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Kumar Kartikeya Dwivedi , Song Liu , Yonghong Song , Jiri Olsa , bpf@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] libbpf: bound /proc//maps scansets in parse_vma_segs() Date: Thu, 21 May 2026 18:17:12 -0400 Message-ID: <20260521221712.3077276-1-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 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" parse_vma_segs() in tools/lib/bpf/usdt.c parses /proc//maps with two widthless scansets, "%s" into mode[16] and "%[^\n]" into line[PATH_MAX]. Both assume the kernel caps maps records to PATH_MAX, but it does not. show_map_vma() emits the path via seq_path() against the seq buffer, which doubles on overflow (m->size <<=3D 1 in fs/seq_file.c), so a VMA whose backing path is a deeply nested directory tree produces a single maps record longer than PATH_MAX. scanf "%s" / "%[^\n]" without a width writes until the field terminator regardless of destination size, so a bpf_program__attach_usdt() consumer attaching against an attacker-controlled PID overflows its own stack inside parse_vma_segs(). Bound both scansets to the declared buffer sizes ("%15s" for mode[16] and "%4095[^\n]" for line[PATH_MAX]) and drain any residue past line[4094] with "%*[^\n]" before the trailing "\n", matching the libbpf-local fscanf style. Without the drain the residue of an over-long record would stay in the stream and break the next "%zx-%zx" parse, so the loop would exit early and any maps records after the over-long entry would be silently skipped. Fixes: 3e6fe5ce4d486 ("libbpf: Fix internal USDT address translation logic = for shared libraries") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito --- Reproduced with Debian 12 on rootless podman: an unprivileged container process mkdirs 50 nested 200-char directories and mmaps a file at the bottom, producing a 10403-byte /proc//maps line. A harness on the host then calls the real parse_vma_segs() against the container's PID; libbpf is built with -fsanitize=3Daddress and the only local source change is dropping the "static" keyword on parse_vma_segs so the symbol is linkable from the harness. Stock libbpf reports: =3D=3DERROR: AddressSanitizer: stack-buffer-overflow WRITE of size 10349 at thread T0 #0 scanf_common -> #1 __isoc99_fscanf #3 parse_vma_segs tools/lib/bpf/usdt.c:509 Address ... in frame parse_vma_segs at offset 8512, just past line[PATH_MAX]. Patched libbpf parses the same maps cleanly. Follow-up calls return 0 with seg_cnt > 0 for libc.so.6 and for ld-linux-x86-64.so.2 (format drain), which appears in maps after the over-long entry. On normal hardened builds the stack canary aborts the consumer; on builds without stack protector the bytes past line[] are attacker-influenced path bytes. =20 Selftest gate =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D tools/testing/selftests/bpf/test_progs -t usdt under QEMU x86_64 (KVM) on the patched kernel: all 6 subtests pass (usdt/basic, basic_optimized, optimized_attach, multispec, urand_auto_attach, urand_pid_attach) on both stock and patched libbpf, diff-clean. The in-tree selftest does not itself exercise long maps records. tools/lib/bpf/usdt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c index e3710933fd52a..e50622ef4c014 100644 --- a/tools/lib/bpf/usdt.c +++ b/tools/lib/bpf/usdt.c @@ -504,8 +504,11 @@ static int parse_vma_segs(int pid, const char *lib_pat= h, struct elf_seg **segs, * 7f5c6f5d1000-7f5c6f5d3000 rw-p 001c7000 08:04 21238613 /usr/lib64= /libc-2.17.so * 7f5c6f5d3000-7f5c6f5d8000 rw-p 00000000 00:00 0 * 7f5c6f5d8000-7f5c6f5d9000 r-xp 00000000 103:01 362990598 /data/user= s/andriin/linux/tools/bpf/usdt/libhello_usdt.so + * + * Bound the writes and drain residue: maps lines can exceed + * PATH_MAX when d_path() expands beyond it. */ - while (fscanf(f, "%zx-%zx %s %zx %*s %*d%[^\n]\n", + while (fscanf(f, "%zx-%zx %15s %zx %*s %*d%4095[^\n]%*[^\n]\n", &seg_start, &seg_end, mode, &seg_off, line) =3D=3D 5) { void *tmp; =20 base-commit: 5200f5f493f79f14bbdc349e402a40dfb32f23c8 --=20 2.53.0