From 041e0c9dc398ef24516b3ab34319fca9fc5f0923 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 18 Jan 2013 18:21:36 +0100 Subject: [PATCH] netsniff-ng, trafgen: drop privileges if wished Signed-off-by: Daniel Borkmann --- src/netsniff-ng.c | 31 ++++++++++++++++++++++++------- src/trafgen.c | 28 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/netsniff-ng.c b/src/netsniff-ng.c index 25390d6b..b8881c4d 100644 --- a/src/netsniff-ng.c +++ b/src/netsniff-ng.c @@ -70,7 +70,7 @@ volatile sig_atomic_t sigint = 0; static volatile bool next_dump = false; -static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqXlvhF:RgAP:V"; +static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqXlvhF:RGAP:Vu:g:"; static const struct option long_options[] = { {"dev", required_argument, NULL, 'd'}, {"in", required_argument, NULL, 'i'}, @@ -84,10 +84,12 @@ static const struct option long_options[] = { {"bind-cpu", required_argument, NULL, 'b'}, {"unbind-cpu", required_argument, NULL, 'B'}, {"prefix", required_argument, NULL, 'P'}, + {"user", required_argument, NULL, 'u'}, + {"group", required_argument, NULL, 'g'}, {"rand", no_argument, NULL, 'r'}, {"rfraw", no_argument, NULL, 'R'}, {"mmap", no_argument, NULL, 'm'}, - {"sg", no_argument, NULL, 'g'}, + {"sg", no_argument, NULL, 'G'}, {"clrw", no_argument, NULL, 'c'}, {"jumbo-support", no_argument, NULL, 'J'}, {"no-promisc", no_argument, NULL, 'M'}, @@ -1037,7 +1039,7 @@ static void help(void) " -M|--no-promisc No promiscuous mode for netdev\n" " -A|--no-sock-mem Don't tune core socket memory\n" " -m|--mmap Mmap pcap file i.e., for replaying\n" - " -g|--sg Scatter/gather pcap file I/O\n" + " -G|--sg Scatter/gather pcap file I/O\n" " -c|--clrw Use slower read(2)/write(2) I/O\n" " -S|--ring-size Manually set ring size to :\n" " mmap space in KiB/MiB/GiB, e.g. \'10MiB\'\n" @@ -1046,6 +1048,8 @@ static void help(void) " is populated with payload from uspace\n" " -b|--bind-cpu Bind to specific CPU (or CPU-range)\n" " -B|--unbind-cpu Forbid to use specific CPU (or CPU-range)\n" + " -u|--user Drop privileges and change to userid\n" + " -g|--group Drop privileges and change to groupid\n" " -H|--prio-high Make this high priority process\n" " -Q|--notouch-irq Do not touch IRQ CPU affinity of NIC\n" " -V|--verbose Be more verbose\n" @@ -1058,6 +1062,7 @@ static void help(void) " netsniff-ng --in dump.pcap --out dump.txf --silent --bind-cpu 0\n" " netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 --type host\n" " netsniff-ng --in eth1 --out /opt/probe/ -s -m -J --interval 100MiB -b 0\n" + " netsniff-ng --in vlan0 --out dump.pcap -c -u `id -u bob` -g `id -g bob`\n" " netsniff-ng --in any --filter http.bpf --jumbo-support --ascii -V\n\n" "Note:\n" " This tool is targeted for network developers! You should\n" @@ -1101,6 +1106,8 @@ int main(int argc, char **argv) int c, i, j, opt_index, ops_touched = 0, vals[4] = {0}; bool prio_high = false, setsockmem = true; void (*main_loop)(struct ctx *ctx) = NULL; + uid_t uid = getuid(); + gid_t gid = getgid(); struct ctx ctx = { .link_type = LINKTYPE_EN10MB, .print_mode = PRINT_NORM, @@ -1113,9 +1120,6 @@ int main(int argc, char **argv) .dump_mode = DUMP_INTERVAL_TIME, }; - setfsuid(getuid()); - setfsgid(getgid()); - srand(time(NULL)); while ((c = getopt_long(argc, argv, short_options, long_options, @@ -1150,6 +1154,12 @@ int main(int argc, char **argv) case 'A': setsockmem = false; break; + case 'u': + uid = strtoul(optarg, NULL, 0); + break; + case 'g': + gid = strtoul(optarg, NULL, 0); + break; case 't': if (!strncmp(optarg, "host", strlen("host"))) ctx.packet_type = PACKET_HOST; @@ -1206,7 +1216,7 @@ int main(int argc, char **argv) ctx.pcap = PCAP_OPS_MMAP; ops_touched = 1; break; - case 'g': + case 'G': ctx.pcap = PCAP_OPS_SG; ops_touched = 1; break; @@ -1295,6 +1305,8 @@ int main(int argc, char **argv) case 'S': case 'b': case 'k': + case 'u': + case 'g': case 'B': case 'e': panic("Option -%c requires an argument!\n", @@ -1310,6 +1322,11 @@ int main(int argc, char **argv) } } + if (setgid(gid) != 0) + panic("Unable to drop group privileges: %s!\n", strerror(errno)); + if (setuid(uid) != 0) + panic("Unable to drop user privileges: %s!\n", strerror(errno)); + if (!ctx.device_in) ctx.device_in = xstrdup("any"); diff --git a/src/trafgen.c b/src/trafgen.c index 39c48471..dba6abb7 100644 --- a/src/trafgen.c +++ b/src/trafgen.c @@ -46,6 +46,7 @@ #include #include #include +#include #include "xmalloc.h" #include "die.h" @@ -81,7 +82,7 @@ size_t plen = 0; struct packet_dyn *packet_dyn = NULL; size_t dlen = 0; -static const char *short_options = "d:c:n:t:vJhS:rk:i:o:VRsP:eE:p"; +static const char *short_options = "d:c:n:t:vJhS:rk:i:o:VRsP:eE:pu:g:"; static const struct option long_options[] = { {"dev", required_argument, NULL, 'd'}, {"out", required_argument, NULL, 'o'}, @@ -94,6 +95,8 @@ static const struct option long_options[] = { {"kernel-pull", required_argument, NULL, 'k'}, {"smoke-test", required_argument, NULL, 's'}, {"seed", required_argument, NULL, 'E'}, + {"user", required_argument, NULL, 'u'}, + {"group", required_argument, NULL, 'g'}, {"jumbo-support", no_argument, NULL, 'J'}, {"cpp", no_argument, NULL, 'p'}, {"rfraw", no_argument, NULL, 'R'}, @@ -194,6 +197,8 @@ static void help(void) " -S|--ring-size Manually set mmap size (KB/MB/GB): e.g.\'10MB\'\n" " -k|--kernel-pull Kernel batch interval in us (def: 10us)\n" " -E|--seed Manually set srand(3) seed\n" + " -u|--user Drop privileges and change to userid\n" + " -g|--group Drop privileges and change to groupid\n" " -V|--verbose Be more verbose\n" " -v|--version Show version\n" " -e|--example Show built-in packet config example\n" @@ -205,7 +210,8 @@ static void help(void) " trafgen --dev eth0 --conf trafgen.cfg --smoke-test 10.0.0.1\n" " trafgen --dev wlan0 --rfraw --conf beacon-test.txf -V --cpus 2\n" " trafgen --dev eth0 --conf trafgen.cfg --rand --gap 1000\n" - " trafgen --dev eth0 --conf trafgen.cfg --rand --num 1400000 -k1000\n\n" + " trafgen --dev eth0 --conf trafgen.cfg --rand --num 1400000 -k1000\n" + " trafgen --dev eth0 --conf trafgen.cfg -u `id -u bob` -g `id -g bob`\n\n" "Arbitrary packet config examples (e.g. trafgen -e > trafgen.cfg):\n" " Run packet on all CPUs: { fill(0xff, 64) csum16(0, 64) }\n" " Run packet only on CPU1: cpu(1): { rnd(64), 0b11001100, 0xaa }\n" @@ -1020,9 +1026,8 @@ int main(int argc, char **argv) unsigned long cpus_tmp; unsigned long long tx_packets, tx_bytes; struct ctx ctx; - - setfsuid(getuid()); - setfsgid(getgid()); + uid_t uid = getuid(); + gid_t gid = getgid(); fmemset(&ctx, 0, sizeof(ctx)); ctx.cpus = get_number_cpus_online(); @@ -1075,6 +1080,12 @@ int main(int argc, char **argv) case 'i': confname = xstrdup(optarg); break; + case 'u': + uid = strtoul(optarg, NULL, 0); + break; + case 'g': + gid = strtoul(optarg, NULL, 0); + break; case 'k': ctx.kpull = strtoul(optarg, NULL, 0); break; @@ -1128,6 +1139,8 @@ int main(int argc, char **argv) case 'E': case 'i': case 'k': + case 'u': + case 'g': case 't': panic("Option -%c requires an argument!\n", optopt); @@ -1142,6 +1155,11 @@ int main(int argc, char **argv) } } + if (setgid(gid) != 0) + panic("Unable to drop group privileges: %s!\n", strerror(errno)); + if (setuid(uid) != 0) + panic("Unable to drop user privileges: %s!\n", strerror(errno)); + if (argc < 5) help(); if (ctx.device == NULL) -- 2.11.4.GIT