Hi All,
FreeBSD has designed capsicum which is a sandboxing mechanism.
Please find below a patch against FreeBSD 10 Release:
(Patch based on FreeBSD's port of tcpdump done by p...@freebsd.org)
diff --git a/tcpdump.c b/tcpdump.c
index 739f9c8..aaac4b8 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -66,6 +66,13 @@ extern int SIZE_BUF;
#include
#include
#include
+#ifdef __FreeBSD__
+#include
+#include
+#include
+#include
+#include
+#endif /* __FreeBSD__ */
#ifndef WIN32
#include
#include
@@ -388,6 +395,9 @@ struct dump_info {
char*CurrentFileName;
pcap_t *pd;
pcap_dumper_t *p;
+#ifdef __FreeBSD__
+ int dirfd;
+#endif
};
#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
@@ -712,6 +722,11 @@ main(int argc, char **argv)
#endif
int status;
FILE *VFile;
+#ifdef __FreeBSD__
+ cap_rights_t rights;
+ int cansandbox;
+#endif /* __FreeBSD__ */
+
#ifdef WIN32
if(wsockinit() != 0) return 1;
#endif /* WIN32 */
@@ -1216,6 +1231,13 @@ main(int argc, char **argv)
pd = pcap_open_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
+#ifdef __FreeBSD__
+ cap_rights_init(&rights, CAP_READ);
+ if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
+ errno != ENOSYS) {
+ error("unable to limit pcap descriptor");
+ }
+#endif
dlt = pcap_datalink(pd);
dlt_name = pcap_datalink_val_to_name(dlt);
if (dlt_name == NULL) {
@@ -1472,6 +1494,21 @@ main(int argc, char **argv)
if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd));
+#ifdef __FreeBSD__
+ if (RFileName == NULL && VFileName == NULL) {
+ static const unsigned long cmds[] = { BIOCGSTATS };
+
+ cap_rights_init(&rights, CAP_IOCTL, CAP_READ);
+ if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
+ errno != ENOSYS) {
+ error("unable to limit pcap descriptor");
+ }
+ if (cap_ioctls_limit(pcap_fileno(pd), cmds,
+ sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
+ error("unable to limit ioctls on pcap descriptor");
+ }
+ }
+#endif
if (WFileName) {
pcap_dumper_t *p;
/* Do not exceed the default PATH_MAX for files. */
@@ -1493,9 +1530,32 @@ main(int argc, char **argv)
#endif
if (p == NULL)
error("%s", pcap_geterr(pd));
+#ifdef __FreeBSD__
+ cap_rights_init(&rights, CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(fileno(pcap_dump_file(p)), &rights) < 0 &&
+ errno != ENOSYS) {
+ error("unable to limit dump descriptor");
+ }
+#endif
if (Cflag != 0 || Gflag != 0) {
- callback = dump_packet_and_trunc;
+#ifdef __FreeBSD__
+ dumpinfo.WFileName = strdup(basename(WFileName));
+ dumpinfo.dirfd = open(dirname(WFileName),
+ O_DIRECTORY | O_RDONLY);
+ if (dumpinfo.dirfd < 0) {
+ error("unable to open directory %s",
+ dirname(WFileName));
+ }
+ cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL,
+ CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
+ if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 &&
+ errno != ENOSYS) {
+ error("unable to limit directory rights");
+ }
+#else /* !__FreeBSD__ */
dumpinfo.WFileName = WFileName;
+#endif
+ callback = dump_packet_and_trunc;
dumpinfo.pd = pd;
dumpinfo.p = p;
pcap_userdata = (u_char *)&dumpinfo;
@@ -1565,6 +1625,15 @@ main(int argc, char **argv)
(void)fflush(stderr);
}
#endif /* WIN32 */
+
+#ifdef __FreeBSD__
+ cansandbox = (nflag && VFileName == NULL && zflag == NULL);
+ if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
+ error("unable to enter the capability mode");
+ if (cap_sandboxed())
+ fprintf(stderr, "capability mode sandbox enabled\n");
+#endif /* __FreeBSD__ */
+
do {
status = pcap_loop(pd, cnt, callback, pcap_userdata);
if (WFileName == NULL) {
@@ -1612,6 +1681,13 @@ main(int argc, char **argv)
pd = pcap_open_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
+#ifdef __FreeBSD__
+