From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 2DCA73E121A for ; Tue, 28 Apr 2026 10:01:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777370478; cv=none; b=bBovvzbMeL+VLCXANtEN+cVOldRuEqc+yYGIOlRx/kau8ai8P9mkyJVq04/FXCRim46njKGHJnugqXwxjdgSKf4E/A+qBLnEBiVppEeivYSrRmGjJUD167WN3S7ExNDe0HEtuDfS3WtExMvM+KlJwE+GJDQdFKkXvPIJRN7qdhE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777370478; c=relaxed/simple; bh=i4hv0UeHtyM3DqopjiwGr9bnDPgnmIRVxPnkNr8GmIg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=GAkEYzBbp3mtYaXxwyvlbihFAFQl6RqsZbSqM3XByS7yALqQrH4UP3a5XjFbQntLbFZhiOFmlObYnzb/ENgACocPd5Gs9nbsr4c39VwXR4AqY1tBJTWOCjz6CVTYZazQ9U7wwb3QaH6zDjSzaAzlZGFvTMwcQiyYn+avaDDPf3w= 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=GjO5jUXI; arc=none smtp.client-ip=209.85.128.45 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="GjO5jUXI" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-48334ee0aeaso117015425e9.1 for ; Tue, 28 Apr 2026 03:01:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777370476; x=1777975276; 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=/50XZQ0iXHXF4hZ1uj3CWweX99HDYB10QdKh/6U0RUI=; b=GjO5jUXIg/Y7lxP9cXRfZyrBbDG74nZ/1XGZ3itjDNY2hwyGtIxPDhpSVlQV25U9aE MRJjaRxFzVx4wzY67wY6LobGHU4r0sg6WzO+oeIp7GjWopFLipLQBxw5qxCR5FfuMsYX xukpSGnIkqNKPd0+SvZdEk7qwvp3hKN2YrWGy2OmsYBWQccud9xKKK2EifcMYJby/QhH WalRfkFTLnKReicP233J11b+Otj8guCa8WP+18EQGy3TlWz+uPfOsjgF/sBG2sGS9REM VWg5Thz2hpvgbCt0pDavA+PpLRFUCTYkGvd5qVL9QbDIhqRapLg0ykxPlqoaaGra+w/2 KdIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777370476; x=1777975276; 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=/50XZQ0iXHXF4hZ1uj3CWweX99HDYB10QdKh/6U0RUI=; b=iD/2MPLBysAxiXbim4b36UIJfAg+/WbYG1MMYJBTC7pnWGZfJiq7SsmZKg90Cblt0p kWO6HoDs1JCZELvOeUHcMlX6xfjrEJct/4JDWSdfFDxNILlIFfXXG++MNC/XxIVjVGGP KZYQta1ufIhwGf9IUXAN96NEzeDYCl4eWMHNywdAKp3PUvg2tDLI8UxOf6pwjuCyRWFQ /bxoCzAGUNzdXrRAmpVCplO4vkOI/oHfGadSfq3KA9qKzITOJVnqiQTHCFPZ8pJrHTte 9lChE9eAXCNmIT6BtIA/CLNpO87dusrc/ZR6iHe4SkldS0FHf9KPA4Kv1LITxExxk+0G Py8g== X-Forwarded-Encrypted: i=1; AFNElJ+yoWB0EgQpgrQ87UY18/rArd/ZwOgbTbDd8oQU/GMxFm/2945qU9NHzASZ9EdsypWXQS/so+4y/G5GB/U=@vger.kernel.org X-Gm-Message-State: AOJu0YxBcwTj++ldAPhIR5LSpW8qiz024Rz0vecufbn+p53yGdw4bylp oYo2CU6HCoBe3fS+PsBt+OLXVaw7T+tuTMBk/fYKk8vJLfEDoQNpKQo4 X-Gm-Gg: AeBDievy+P+o3T5rQ7bQtspUo1JPO2JxwHcI+yeVSlcrmC5x2DwTI9fSi5EFV9sCcx7 gJMQ1DVD/kuWYxCMHEO7ukpx3bui+mVdC8KOmz6LeMm9GKL7tLCT7+pnWj1RON2Hf1be63NhELP vDcVWicThSJQyfqhPs6M+j722QcZFhMhDxCdaUnwvdcXhiKPZ8ffdqf2CjomvUuA6PgFhPE6GGv zh6tzdIAOuavo73OYWDYRzvNhuP+wt3UhDXkkiQ5JaWiLuIZy4gMfblI5iQHg2yok9fr3aaZqGK CyPxUZ4ZuGaHYvvfJb3HIYzqYlMs/P5rZEm9YCPZI2NWWohdkSntM+6mINvjUKmRN95n5/D/5Ki 3Rp0JIvmbAEsBrSwVRTTqgNUb2fpCBamqDV1fz7kQqObQn/1WaWHAfuQjPS5RY1Gozfyu4zPpP2 JRUgStUAZYs86QkztMFJlKO/Y9wzO1Kt3tfOzwJn1zFJIgy5iAwFVlfWO/+5X5OufrIVk/TqcZZ 0sk X-Received: by 2002:a05:600c:a10a:b0:48a:5574:3a5d with SMTP id 5b1f17b1804b1-48a77aea542mr27777335e9.7.1777370475096; Tue, 28 Apr 2026 03:01:15 -0700 (PDT) Received: from localhost.localdomain ([2a05:6e02:1135:da10:f045:eb7e:ea01:7d2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48a773af544sm47395625e9.6.2026.04.28.03.01.13 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Tue, 28 Apr 2026 03:01:14 -0700 (PDT) From: Hasan Basbunar To: Daniel Borkmann Cc: Alexei Starovoitov , Andrii Nakryiko , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, Hasan Basbunar Subject: [PATCH] bpf: bpf_dbg: fix off-by-one in cmd_select and pcap_next_pkt Date: Tue, 28 Apr 2026 12:01:09 +0200 Message-ID: <20260428100109.56572-1-basbunarhasan@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-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bpf_dbg's interactive 'select ' command, documented in the file header ("select 3 (run etc will start from the 3rd packet in the pcap)") to use 1-based packet indexing, advances the pcap cursor one packet too many. The loop in cmd_select(): pcap_reset_pkt(); /* cursor on packet 1 */ for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) /* noop */; calls pcap_next_pkt() N times to reach packet N, but pcap_next_pkt() validates the packet at the cursor and then advances past it. After N calls the cursor is on packet N+1, so 'select 3' positions on packet 4, 'select 4' on packet 5, etc. To land on packet N the loop must advance the cursor only N-1 times. A second off-by-one in pcap_next_pkt() rejects the last packet of any pcap whose mapped size equals the sum of its packets exactly (the common case — pcap files have no trailer): if (pcap_ptr_va_curr + sizeof(*hdr) + hdr->caplen - pcap_ptr_va_start >= pcap_map_size) return false; When the current packet ends exactly at the mmap boundary, the expression equals pcap_map_size and the >= check rejects a fully in-bounds packet. The same off-by-one is present in the earlier header-fits check on the same function. Both should compare with >. Combined effect: 'select N' on a pcap of N packets always reports "no packet #N available!". For a 1-packet pcap, 'select 1' reports the only packet as unavailable. Reproduction (deterministic, no kernel needed): build bpf_dbg from the unmodified tree, synthesize a pcap with N>=1 packets each with a distinct payload byte, and drive 'select K / step 1 / quit'. Before this fix, 'select 1' shows packet 2's payload; 'select N' shows the "no packet" error. After this fix, 'select K' shows packet K for all K in 1..N, and 'select N+1' correctly errors. Cloudflare's downstream mirror at github.com/cloudflare/bpftools carries the same defect. Fixes: fd981e3c321a ("filter: bpf_dbg: add minimal bpf debugger") Signed-off-by: Hasan Basbunar --- tools/bpf/bpf_dbg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/bpf/bpf_dbg.c b/tools/bpf/bpf_dbg.c index 00e560a17baf..f21576dc2326 100644 --- a/tools/bpf/bpf_dbg.c +++ b/tools/bpf/bpf_dbg.c @@ -923,12 +923,12 @@ static bool pcap_next_pkt(void) struct pcap_pkthdr *hdr = pcap_curr_pkt(); if (pcap_ptr_va_curr + sizeof(*hdr) - - pcap_ptr_va_start >= pcap_map_size) + pcap_ptr_va_start > pcap_map_size) return false; if (hdr->caplen == 0 || hdr->len == 0 || hdr->caplen > hdr->len) return false; if (pcap_ptr_va_curr + sizeof(*hdr) + hdr->caplen - - pcap_ptr_va_start >= pcap_map_size) + pcap_ptr_va_start > pcap_map_size) return false; pcap_ptr_va_curr += (sizeof(*hdr) + hdr->caplen); @@ -1141,7 +1141,7 @@ static int cmd_select(char *num) pcap_reset_pkt(); bpf_reset(); - for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) + for (i = 1; i < which && (have_next = pcap_next_pkt()); i++) /* noop */; if (!have_next || pcap_curr_pkt() == NULL) { rl_printf("no packet #%u available!\n", which); -- 2.53.0