Suricata had local patches added in 2019 to support dropping privileges, so the suricata daemon does not run as root. These patches were dropped in the Suricata 7.0.2 update, without a rationale I could find.
Considering Suricata deals with potentially malicious traffic, it seems like a bad idea to run it as root. It is pledged, but the pledge is "stdio rpath wpath cpath fattr unix dns bpf", and it is not unveiled or chrooted, which means a compromised process could modify any file on the system. This restores the local patches for dropping privileges that were dropped in the 7.0.2 update, and updates them to fix the conflicts. Tested briefly on amd64. OKs to commit after unlock, and to commit to 7.5 -stable after it opens? Thanks, Jeremy Index: Makefile =================================================================== RCS file: /cvs/ports/security/suricata/Makefile,v diff -u -p -r1.65 Makefile --- Makefile 22 Feb 2024 09:49:35 -0000 1.65 +++ Makefile 15 Mar 2024 19:03:06 -0000 @@ -5,6 +5,7 @@ COMMENT = high performance network IDS, SURICATA_V = 7.0.3 SUPDATE_V = 1.2.8 +REVISION = 0 DISTNAME = suricata-${SURICATA_V} CATEGORIES = security Index: patches/patch-src_suricata_c =================================================================== RCS file: patches/patch-src_suricata_c diff -N patches/patch-src_suricata_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_suricata_c 15 Mar 2024 19:17:33 -0000 @@ -0,0 +1,32 @@ +Use setresuid/gid() directly to change user and group. Otherwise +Suricata uses libcap-ng on Linux and runs as root elsewhere. + +Index: src/suricata.c +--- src/suricata.c.orig ++++ src/suricata.c +@@ -1600,7 +1600,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, + return TM_ECODE_FAILED; + #endif /* UNITTESTS */ + } else if (strcmp((long_opts[option_index]).name, "user") == 0) { +-#ifndef HAVE_LIBCAP_NG ++#if 0 + SCLogError("libcap-ng is required to" + " drop privileges, but it was not compiled into Suricata."); + return TM_ECODE_FAILED; +@@ -1609,7 +1609,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, + suri->do_setuid = TRUE; + #endif /* HAVE_LIBCAP_NG */ + } else if (strcmp((long_opts[option_index]).name, "group") == 0) { +-#ifndef HAVE_LIBCAP_NG ++#if 0 + SCLogError("libcap-ng is required to" + " drop privileges, but it was not compiled into Suricata."); + return TM_ECODE_FAILED; +@@ -3036,6 +3036,7 @@ int SuricataMain(int argc, char **argv) + SystemHugepageSnapshotDestroy(prerun_snap); + SystemHugepageSnapshotDestroy(postrun_snap); + ++ SCSetUserID(suricata.userid, suricata.groupid); + SCPledge(); + SuricataMainLoop(&suricata); + Index: patches/patch-src_util-privs_c =================================================================== RCS file: patches/patch-src_util-privs_c diff -N patches/patch-src_util-privs_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_util-privs_c 15 Mar 2024 19:13:13 -0000 @@ -0,0 +1,34 @@ +Use setresuid/gid() directly to change user and group. Otherwise +Suricata uses libcap-ng on Linux and runs as root elsewhere. + +Index: src/util-privs.c +--- src/util-privs.c.orig ++++ src/util-privs.c +@@ -244,6 +244,27 @@ void SCGetGroupID(const char *group_name, uint32_t *gi + *gid = grpid; + } + ++int SCSetUserID(const uint32_t uid, const uint32_t gid) ++{ ++ int ret = setresgid(gid, gid, gid); ++ ++ if (ret != 0) { ++ SCLogError("unable to set the group ID," ++ " check permissions!! gid=%u ret=%i errno=%i", gid, ret, errno); ++ exit(EXIT_FAILURE); ++ } ++ ++ ret = setresuid(uid, uid, uid); ++ ++ if (ret != 0) { ++ SCLogError("unable to set the user ID," ++ " check permissions!! uid=%u ret=%i errno=%i", uid, ret, errno); ++ exit(EXIT_FAILURE); ++ } ++ ++ return 0; ++} ++ + #ifdef __OpenBSD__ + int SCPledge(void) + { Index: patches/patch-src_util-privs_h =================================================================== RCS file: patches/patch-src_util-privs_h diff -N patches/patch-src_util-privs_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_util-privs_h 15 Mar 2024 19:02:38 -0000 @@ -0,0 +1,14 @@ +Use setresuid/gid() directly to change user and group. Otherwise +Suricata uses libcap-ng on Linux and runs as root elsewhere. + +Index: src/util-privs.h +--- src/util-privs.h.orig ++++ src/util-privs.h +@@ -92,6 +92,7 @@ void SCDropMainThreadCaps(uint32_t , uint32_t ); + + void SCGetUserID(const char *, const char *, uint32_t *, uint32_t *); + void SCGetGroupID(const char *, uint32_t *); ++int SCSetUserID(const uint32_t uid, const uint32_t gid); + + #ifdef __OpenBSD__ + int SCPledge(void);