X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/2d4f737c35cfcb4c1b5bd1f03461919e0cd57dc4..refs/pull/435/head:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index bd1664c5..8e07d8f2 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -750,16 +750,6 @@ droproot(const char *username, const char *chroot_dir) else { fprintf(stderr, "dropped privs to %s\n", username); } - /* We don't need CAP_SETUID and CAP_SETGID */ - capng_updatev( - CAPNG_DROP, - CAPNG_EFFECTIVE | CAPNG_PERMITTED, - CAP_SETUID, - CAP_SETGID, - -1); - - capng_apply(CAPNG_SELECT_BOTH); - #else if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { @@ -780,6 +770,17 @@ droproot(const char *username, const char *chroot_dir) username); exit(1); } +#ifdef HAVE_LIBCAP_NG + /* We don't need CAP_SETUID and CAP_SETGID any more. */ + capng_updatev( + CAPNG_DROP, + CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_SETUID, + CAP_SETGID, + -1); + capng_apply(CAPNG_SELECT_BOTH); +#endif /* HAVE_LIBCAP_NG */ + } #endif /* WIN32 */ @@ -1739,20 +1740,25 @@ main(int argc, char **argv) if (getuid() == 0 || geteuid() == 0) { #ifdef HAVE_LIBCAP_NG - /* Drop all capabilities from effective set */ - capng_clear(CAPNG_EFFECTIVE); - /* We are running as root and we will be writing to savefile */ - if (WFileName && username) { - /* Add capabilities we will need*/ + /* Initialize capng */ + capng_clear(CAPNG_SELECT_BOTH); + if (username) { capng_updatev( CAPNG_ADD, CAPNG_PERMITTED | CAPNG_EFFECTIVE, CAP_SETUID, CAP_SETGID, - CAP_DAC_OVERRIDE, -1); - capng_apply(CAPNG_SELECT_BOTH); } + + if (WFileName) { + capng_update( + CAPNG_ADD, + CAPNG_PERMITTED | CAPNG_EFFECTIVE, + CAP_DAC_OVERRIDE + ); + } + capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ if (username || chroot_dir) droproot(username, chroot_dir); @@ -1793,8 +1799,17 @@ main(int argc, char **argv) p = pcap_dump_open(pd, dumpinfo.CurrentFileName); #ifdef HAVE_LIBCAP_NG - /* Give up capabilities, clear Effective set */ - capng_clear(CAPNG_EFFECTIVE); + /* Give up CAP_DAC_OVERRIDE capability. + * Only allow it to be restored if the -C or -G flag have been + * set since we may need to create more files later on. + */ + capng_update( + CAPNG_DROP, + (Cflag || Gflag ? 0 : CAPNG_PERMITTED) + | CAPNG_EFFECTIVE, + CAP_DAC_OVERRIDE + ); + capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ if (p == NULL) error("%s", pcap_geterr(pd)); @@ -2211,7 +2226,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #ifdef HAVE_LIBCAP_NG capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); - capng_apply(CAPNG_EFFECTIVE); + capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ #ifdef HAVE_CAPSICUM fd = openat(dump_info->dirfd, @@ -2232,7 +2247,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #endif #ifdef HAVE_LIBCAP_NG capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); - capng_apply(CAPNG_EFFECTIVE); + capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); @@ -2251,59 +2266,74 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s * larger than Cflag - the last packet written to the * file could put it over Cflag. */ - if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) { + if (Cflag != 0) { + long size = pcap_dump_ftell(dump_info->p); + + if (size == -1) + error("ftell fails on output file"); + if (size > Cflag) { #ifdef HAVE_CAPSICUM - FILE *fp; - int fd; + FILE *fp; + int fd; #endif - /* - * Close the current file and open a new one. - */ - pcap_dump_close(dump_info->p); + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); - /* - * Compress the file we just closed, if the user asked for it - */ - if (zflag != NULL) - compress_savefile(dump_info->CurrentFileName); + /* + * Compress the file we just closed, if the user + * asked for it. + */ + if (zflag != NULL) + compress_savefile(dump_info->CurrentFileName); - Cflag_count++; - if (Wflag > 0) { - if (Cflag_count >= Wflag) - Cflag_count = 0; - } - if (dump_info->CurrentFileName != NULL) - free(dump_info->CurrentFileName); - dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); - if (dump_info->CurrentFileName == NULL) - error("dump_packet_and_trunc: malloc"); - MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars); + Cflag_count++; + if (Wflag > 0) { + if (Cflag_count >= Wflag) + Cflag_count = 0; + } + if (dump_info->CurrentFileName != NULL) + free(dump_info->CurrentFileName); + dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); + if (dump_info->CurrentFileName == NULL) + error("dump_packet_and_trunc: malloc"); + MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars); +#ifdef HAVE_LIBCAP_NG + capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); + capng_apply(CAPNG_SELECT_BOTH); +#endif /* HAVE_LIBCAP_NG */ #ifdef HAVE_CAPSICUM - fd = openat(dump_info->dirfd, dump_info->CurrentFileName, - O_CREAT | O_WRONLY | O_TRUNC, 0644); - if (fd < 0) { - error("unable to open file %s", - dump_info->CurrentFileName); - } - fp = fdopen(fd, "w"); - if (fp == NULL) { - error("unable to fdopen file %s", - dump_info->CurrentFileName); - } - dump_info->p = pcap_dump_fopen(dump_info->pd, fp); + fd = openat(dump_info->dirfd, dump_info->CurrentFileName, + O_CREAT | O_WRONLY | O_TRUNC, 0644); + if (fd < 0) { + error("unable to open file %s", + dump_info->CurrentFileName); + } + fp = fdopen(fd, "w"); + if (fp == NULL) { + error("unable to fdopen file %s", + dump_info->CurrentFileName); + } + dump_info->p = pcap_dump_fopen(dump_info->pd, fp); #else /* !HAVE_CAPSICUM */ - dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); + dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif - if (dump_info->p == NULL) - error("%s", pcap_geterr(pd)); +#ifdef HAVE_LIBCAP_NG + capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); + capng_apply(CAPNG_SELECT_BOTH); +#endif /* HAVE_LIBCAP_NG */ + if (dump_info->p == NULL) + error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - cap_rights_init(&rights, CAP_SEEK, CAP_WRITE); - if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)), - &rights) < 0 && errno != ENOSYS) { - error("unable to limit dump descriptor"); - } + cap_rights_init(&rights, CAP_SEEK, CAP_WRITE); + if (cap_rights_limit(fileno(pcap_dump_file(dump_info->p)), + &rights) < 0 && errno != ENOSYS) { + error("unable to limit dump descriptor"); + } #endif + } } pcap_dump((u_char *)dump_info->p, h, sp);