git: 3d459b72ba03 - 2026Q4 - net/ngrep: Fix Capsicum support

From: Vladimir Druzenko <vvd_at_FreeBSD.org>
Date: Tue, 13 Oct 2026 18:50:46 UTC
The branch 2026Q4 has been updated by vvd:

URL: https://cgit.FreeBSD.org/ports/commit/?id=3d459b72ba03882e4afd74f1a9c02076d1dda80c

commit 3d459b72ba03882e4afd74f1a9c02076d1dda80c
Author:     Lasse Bang Mikkelsen <lbm@lbm.dk>
AuthorDate: 2026-10-13 18:31:02 +0000
Commit:     Vladimir Druzenko <vvd@FreeBSD.org>
CommitDate: 2026-10-13 18:50:34 +0000

    net/ngrep: Fix Capsicum support
    
    - Fix Capsicum sandbox crash when using -I (offline capture):
    pcap_fileno() returns -1 for handles opened with pcap_open_offline().
    cap_rights_limit(-1, ...) fails with EBADF rather than ENOSYS,
    bypassing the guard and causing ngrep to exit with "unable to limit pcap
    pcap descriptor" whenever -I is used.
    Cache pcap_fileno(pd) and skip cap_rights_limit() and cap_ioctls_limit()
    when the fd is -1.  Offline handles do not need Capsicum fd sandboxing
    at this point since the file is already open; live captures on a BPF
    device are unaffected.
    
    - Fix USE_CAPSICUM always defined:
    patch-configure.ac never initialises USE_CAPSICUM to "0", so
    AC_DEFINE_UNQUOTED emits "#define USE_CAPSICUM" (empty) regardless of
    the port option.  patch-ngrep.c then uses #ifdef which tests for mere
    presence of the macro rather than its value, so the Capsicum code
    compiles in unconditionally.  The "CONFIG: capsicum disabled" build
    message is misleading -- the code was always active.
    Fix by initialising USE_CAPSICUM="0" before the detection block, and
    changing all #ifdef USE_CAPSICUM guards in patch-ngrep.c to #if.
    
    - Add tzset() before cap_enter():
    So that timezone data is loaded before the process enters capability
    mode.  Without this localtime() cannot open /etc/localtime after
    cap_enter() and silently falls back to UTC, causing timestamps to
    display with the wrong offset.
    
    - Fix silent grab of net/libpcap if installed even if option PORTS_PCAP
      disabled.
    
    PR:             295644
    Sponsored by:   UNIS Labs (vvd)
    Co-authored-by: Vladimir Druzenko <vvd@FreeBSD.org>
    MFH:            2026Q4
    
    (cherry picked from commit ef87fb63d574f632fa0b5fc682924d16df418cd4)
---
 net/ngrep/Makefile                 |  2 ++
 net/ngrep/files/patch-configure.ac |  8 +++++---
 net/ngrep/files/patch-ngrep.c      | 41 ++++++++++++++++++++++----------------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/net/ngrep/Makefile b/net/ngrep/Makefile
index 6d40cb269761..95166789fefd 100644
--- a/net/ngrep/Makefile
+++ b/net/ngrep/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=	ngrep
 DISTVERSION=	1.48.3
+PORTREVISION=	1
 CATEGORIES=	net security
 MASTER_SITES=	SF/${PORTNAME}/v${DISTVERSION}/
 DISTNAME=	v${DISTVERSION}%20source%20code
@@ -44,6 +45,7 @@ PORTS_PCAP_BUILD_DEPENDS=	${LOCALBASE}/include/pcap.h:net/libpcap
 PORTS_PCAP_LIB_DEPENDS=		libpcap.so:net/libpcap
 PORTS_PCAP_CONFIGURE_ON=	--with-pcap-includes=${LOCALBASE}/include
 PORTS_PCAP_CONFIGURE_OFF=	--with-pcap-includes=/usr/include
+PORTS_PCAP_LDFLAGS_OFF=		-L/usr/lib
 
 post-install-DOCS-on:
 	${MKDIR} ${STAGEDIR}${DOCSDIR}
diff --git a/net/ngrep/files/patch-configure.ac b/net/ngrep/files/patch-configure.ac
index 9ad74b5061cb..43c5de123ed8 100644
--- a/net/ngrep/files/patch-configure.ac
+++ b/net/ngrep/files/patch-configure.ac
@@ -1,6 +1,6 @@
 --- configure.ac.orig	2025-11-07 06:35:47 UTC
 +++ configure.ac
-@@ -138,7 +138,35 @@ AS_IF([test $use_pcap_restart = yes], [
+@@ -138,7 +138,37 @@ AS_IF([test $use_pcap_restart = yes], [
      USE_PCAP_RESTART="0"
  ])
  
@@ -20,6 +20,8 @@
 +#
 +# All of them must be available in order to enable capsicum sandboxing.
 +#
++USE_CAPSICUM="0"
++
 +if test $use_capsicum = yes && test $use_capsicum != no ; then
 +	AC_CHECK_FUNCS(cap_enter cap_rights_limit cap_ioctls_limit openat,
 +	    ac_lbl_capsicum_function_seen=yes,
@@ -36,7 +38,7 @@
  dnl
  dnl Configure the regular expression library.
  dnl
-@@ -553,6 +581,7 @@ AC_DEFINE_UNQUOTED(USE_VLAN_HACK,             $USE_VLA
+@@ -553,6 +583,7 @@ AC_DEFINE_UNQUOTED(USE_VLAN_HACK,             $USE_VLA
  AC_DEFINE_UNQUOTED(USE_IPv6,                  $USE_IPv6,                  [whether to use IPv6 (default off)])
  AC_DEFINE_UNQUOTED(USE_TCPKILL,               $USE_TCPKILL,               [whether to enable tcpkill functionality (default off)])
  AC_DEFINE_UNQUOTED(USE_VLAN_HACK,             $USE_VLAN_HACK,             [whether to automatically include VLAN frames (default on)])
@@ -44,7 +46,7 @@
  
  AC_DEFINE_UNQUOTED(USE_DROPPRIVS,             $USE_DROPPRIVS,             [whether to use privileges dropping (default yes)])
  AC_DEFINE_UNQUOTED(DROPPRIVS_USER,           "$DROPPRIVS_USER",           [pseudo-user for running ngrep (default "nobody")])
-@@ -613,6 +642,12 @@ AS_IF([test "$USE_VLAN_HACK" = "1"], [
+@@ -613,6 +644,12 @@ AS_IF([test "$USE_VLAN_HACK" = "1"], [
      AC_MSG_RESULT(CONFIG: automatically including VLAN frames)
  ], [
      AC_MSG_RESULT(CONFIG: NOT automatically including VLAN frames)
diff --git a/net/ngrep/files/patch-ngrep.c b/net/ngrep/files/patch-ngrep.c
index 76c8ea985385..28bf8c736d27 100644
--- a/net/ngrep/files/patch-ngrep.c
+++ b/net/ngrep/files/patch-ngrep.c
@@ -8,7 +8,7 @@
 -
  #include "config.h"
  
-+#ifdef USE_CAPSICUM
++#if USE_CAPSICUM
 +#include <sys/capsicum.h>
 +#include <net/bpf.h>
 +#endif /* USE_CAPSICUM */
@@ -22,42 +22,49 @@
      int32_t c;
      const char *extra = "";
  
-+#ifdef USE_CAPSICUM
++#if USE_CAPSICUM
 +    cap_rights_t rights;
 +#endif /* USE_CAPSICUM */
 +
      signal(SIGINT,   clean_exit);
      signal(SIGABRT,  clean_exit);
  
-@@ -461,6 +470,22 @@ int main(int argc, char **argv) {
+@@ -461,6 +470,27 @@ int main(int argc, char **argv) {
          free(filter);
      }
  
-+#ifdef USE_CAPSICUM
-+    cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
-+    if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
-+        errno != ENOSYS) {
-+        fprintf(stderr, "unable to limit pcap descriptor");
-+        clean_exit(2);
-+    }
++#if USE_CAPSICUM
++    {
++        int pcap_fd = pcap_fileno(pd);
++        cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
++        if (pcap_fd >= 0 &&
++            cap_rights_limit(pcap_fd, &rights) < 0 &&
++            errno != ENOSYS) {
++            fprintf(stderr, "unable to limit pcap descriptor");
++            clean_exit(2);
++        }
 +
-+    static const unsigned long cmds[] = { BIOCGSTATS };
-+    if (cap_ioctls_limit(pcap_fileno(pd), cmds,
-+        sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
-+        fprintf(stderr, "unable to limit ioctls on pcap descriptor");
-+        clean_exit(2);
++        static const unsigned long cmds[] = { BIOCGSTATS };
++        if (pcap_fd >= 0 &&
++            cap_ioctls_limit(pcap_fd, cmds,
++            sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
++            fprintf(stderr, "unable to limit ioctls on pcap descriptor");
++            clean_exit(2);
++        }
 +    }
 +#endif /* USE_CAPSICUM */
 +
      /* Setup matcher */
  
      if (match_data) {
-@@ -491,6 +516,20 @@ int main(int argc, char **argv) {
+@@ -491,6 +521,22 @@ int main(int argc, char **argv) {
  #if !defined(_WIN32) && !defined(_WIN64) && USE_DROPPRIVS
      drop_privs();
  #endif
 +
-+#ifdef USE_CAPSICUM
++#if USE_CAPSICUM
++    tzset();
++
 +    cap_rights_init(&rights);
 +
 +    if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) {