From: Guy Harris Date: Fri, 2 Jun 2017 00:58:28 +0000 (-0700) Subject: Make the checks and adjustment of the snapshot length module-dependent. X-Git-Tag: libpcap-1.9-bp~808 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/42c3865d71a3d3ad3fc61ee382ad3b5113d40552 Make the checks and adjustment of the snapshot length module-dependent. Also, initialize the snapshot length to 0, meaning "not specified", so that the default snapshot length, if not specified, is also module-dependent. That way, D-Bus has a maximum and default of 128MB, as that's the maximum message size, but other capture devices have the current MAXIMUM_SNAPLEN, so we can handle full-size D-Bus messages without advertising an overly-large snapshot length for other devices, potentially causing libpcap and programs using it or reading libpcap files to allocate overly-large buffers for other capture devices. --- diff --git a/pcap-bpf.c b/pcap-bpf.c index 38844887..7286d884 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -1672,6 +1672,17 @@ pcap_activate_bpf(pcap_t *p) goto bad; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + #if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid) /* * Retrieve the zoneid of the zone we are currently executing in. diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c index 8a258ebf..ac5e529b 100644 --- a/pcap-bt-linux.c +++ b/pcap-bt-linux.c @@ -197,6 +197,17 @@ bt_activate(pcap_t* handle) return PCAP_ERROR; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + /* Initialize some components of the pcap structure. */ handle->bufsize = BT_CTRL_SIZE+sizeof(pcap_bluetooth_h4_header)+handle->snapshot; handle->linktype = DLT_BLUETOOTH_HCI_H4_WITH_PHDR; diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c index 63863a9f..6c016a7e 100644 --- a/pcap-bt-monitor-linux.c +++ b/pcap-bt-monitor-linux.c @@ -173,6 +173,17 @@ bt_monitor_activate(pcap_t* handle) return PCAP_ERROR_RFMON_NOTSUP; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + handle->bufsize = BT_CONTROL_SIZE + sizeof(pcap_bluetooth_linux_monitor_header) + handle->snapshot; handle->linktype = DLT_BLUETOOTH_LINUX_MONITOR; diff --git a/pcap-dag.c b/pcap-dag.c index 80ed01a2..3f68cd6c 100644 --- a/pcap-dag.c +++ b/pcap-dag.c @@ -793,6 +793,17 @@ static int dag_activate(pcap_t* handle) goto faildetach; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + if (handle->opt.immediate) { /* Call callback immediately. * XXX - is this the right way to handle this? diff --git a/pcap-dbus.c b/pcap-dbus.c index ea3a390f..2fedaeff 100644 --- a/pcap-dbus.c +++ b/pcap-dbus.c @@ -223,6 +223,14 @@ dbus_activate(pcap_t *handle) return PCAP_ERROR_RFMON_NOTSUP; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum message length for D-Bus (128MB). + */ + if (handle->snapshot <= 0 || handle->snapshot > 134217728) + handle->snapshot = 134217728; + /* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */ if (handle->opt.buffer_size != 0) dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size); diff --git a/pcap-dlpi.c b/pcap-dlpi.c index 436008d1..08ad6cb1 100644 --- a/pcap-dlpi.c +++ b/pcap-dlpi.c @@ -632,6 +632,17 @@ pcap_activate_dlpi(pcap_t *p) #endif /* AIX vs. HP-UX vs. other */ #endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */ + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + #ifdef HAVE_SOLARIS if (isatm) { /* diff --git a/pcap-dos.c b/pcap-dos.c index 60e9d890..7bffce5a 100644 --- a/pcap-dos.c +++ b/pcap-dos.c @@ -174,6 +174,17 @@ static int pcap_activate_dos (pcap_t *pcap) return (PCAP_ERROR_RFMON_NOTSUP); } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN) + pcap->snapshot = MAXIMUM_SNAPLEN; + if (pcap->snapshot < ETH_MIN+8) pcap->snapshot = ETH_MIN+8; diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c index d2386d79..21ee11e8 100644 --- a/pcap-libdlpi.c +++ b/pcap-libdlpi.c @@ -137,6 +137,17 @@ pcap_activate_libdlpi(pcap_t *p) goto bad; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + /* Enable promiscuous mode. */ if (p->opt.promisc) { retv = dlpromiscon(p, DL_PROMISC_PHYS); diff --git a/pcap-linux.c b/pcap-linux.c index 3df5cf06..179fd348 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -1446,6 +1446,17 @@ pcap_activate_linux(pcap_t *handle) goto fail; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + handle->inject_op = pcap_inject_linux; handle->setfilter_op = pcap_setfilter_linux; handle->setdirection_op = pcap_setdirection_linux; diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c index 49438cda..b8c4f0d2 100644 --- a/pcap-netfilter-linux.c +++ b/pcap-netfilter-linux.c @@ -479,6 +479,17 @@ netfilter_activate(pcap_t* handle) group_count = 1; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + /* Initialize some components of the pcap structure. */ handle->bufsize = 128 + handle->snapshot; handle->offset = 0; diff --git a/pcap-netmap.c b/pcap-netmap.c index cd856fe3..7c6401d3 100644 --- a/pcap-netmap.c +++ b/pcap-netmap.c @@ -188,9 +188,10 @@ static int pcap_netmap_activate(pcap_t *p) { struct pcap_netmap *pn = p->priv; - struct nm_desc *d = nm_open(p->opt.device, NULL, 0, NULL); + struct nm_desc *d; uint32_t if_flags = 0; + d = nm_open(p->opt.device, NULL, 0, NULL); if (d == NULL) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "netmap open: cannot access %s: %s\n", @@ -204,6 +205,18 @@ pcap_netmap_activate(pcap_t *p) d->first_rx_ring, d->last_rx_ring); pn->d = d; p->fd = d->fd; + + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + if (p->opt.promisc && !(d->req.nr_ringid & NETMAP_SW_RING)) { pcap_netmap_ioctl(p, SIOCGIFFLAGS, &if_flags); /* fetch flags */ if (!(if_flags & IFF_PPROMISC)) { diff --git a/pcap-nit.c b/pcap-nit.c index b18f8155..bb5fef77 100644 --- a/pcap-nit.c +++ b/pcap-nit.c @@ -271,6 +271,17 @@ pcap_activate_nit(pcap_t *p) return (PCAP_ERROR_RFMON_NOTSUP); } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + if (p->snapshot < 96) /* * NIT requires a snapshot length of at least 96. diff --git a/pcap-pf.c b/pcap-pf.c index 0c2d0a6f..6f1827c7 100644 --- a/pcap-pf.c +++ b/pcap-pf.c @@ -334,6 +334,18 @@ your system may not be properly configured; see the packetfilter(4) man page\n", p->opt.device, pcap_strerror(errno)); goto bad; } + + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + pf->OrigMissed = -1; enmode = ENTSTAMP|ENNONEXCL; if (!p->opt.immediate) diff --git a/pcap-rpcap.c b/pcap-rpcap.c index a737ccb2..d37d44f7 100644 --- a/pcap-rpcap.c +++ b/pcap-rpcap.c @@ -2176,6 +2176,21 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim "malloc: %s", pcap_strerror(errno)); return NULL; } + + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + * + * XXX - should we leave this up to the remote server to + * do? + */ + if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN) + snaplen = MAXIMUM_SNAPLEN; + fp->opt.device = source_str; fp->snapshot = snaplen; fp->opt.timeout = read_timeout; diff --git a/pcap-septel.c b/pcap-septel.c index b5f6127e..d97bc3ee 100644 --- a/pcap-septel.c +++ b/pcap-septel.c @@ -197,6 +197,17 @@ static pcap_t *septel_activate(pcap_t* handle) { /* Initialize some components of the pcap structure. */ handle->linktype = DLT_MTP2; + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + handle->bufsize = 0; /* diff --git a/pcap-sita.c b/pcap-sita.c index 1e12491c..2a18400d 100644 --- a/pcap-sita.c +++ b/pcap-sita.c @@ -992,6 +992,18 @@ static int pcap_activate_sita(pcap_t *handle) { &handle->linktype); if (fd == -1) return PCAP_ERROR; + + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + handle->fd = fd; handle->bufsize = handle->snapshot; diff --git a/pcap-snf.c b/pcap-snf.c index e3d364a4..aa661a47 100644 --- a/pcap-snf.c +++ b/pcap-snf.c @@ -299,6 +299,17 @@ snf_activate(pcap_t* p) return -1; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + if (p->opt.timeout <= 0) ps->snf_timeout = -1; else diff --git a/pcap-snit.c b/pcap-snit.c index 6471ec47..234285f5 100644 --- a/pcap-snit.c +++ b/pcap-snit.c @@ -296,6 +296,17 @@ pcap_activate_snit(pcap_t *p) return (PCAP_ERROR_RFMON_NOTSUP); } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + if (p->snapshot < 96) /* * NIT requires a snapshot length of at least 96. diff --git a/pcap-snoop.c b/pcap-snoop.c index 2f57fcdb..08720805 100644 --- a/pcap-snoop.c +++ b/pcap-snoop.c @@ -323,6 +323,17 @@ pcap_activate_snoop(pcap_t *p) return (PCAP_ERROR_RFMON_NOTSUP); } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + #ifdef SIOCGIFMTU /* * XXX - IRIX appears to give you an error if you try to set the diff --git a/pcap-tc.c b/pcap-tc.c index bedb4f6e..a4cde6c0 100644 --- a/pcap-tc.c +++ b/pcap-tc.c @@ -571,6 +571,17 @@ TcActivate(pcap_t *p) return PCAP_ERROR; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + /* * Initialize the PPI fixed fields */ diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index bf9a4e5a..353f0b57 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -497,6 +497,17 @@ usb_activate(pcap_t* handle) struct pcap_usb_linux *handlep = handle->priv; char full_path[USB_LINE_LEN]; + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) + handle->snapshot = MAXIMUM_SNAPLEN; + /* Initialize some components of the pcap structure. */ handle->bufsize = handle->snapshot; handle->offset = 0; diff --git a/pcap-win32.c b/pcap-win32.c index 984774cf..b81aae82 100644 --- a/pcap-win32.c +++ b/pcap-win32.c @@ -1003,6 +1003,17 @@ pcap_activate_win32(pcap_t *p) break; } + /* + * Turn a negative snapshot value (invalid), a snapshot value of + * 0 (unspecified), or a value bigger than the normal maximum + * value, into the maximum allowed value. + * + * If some application really *needs* a bigger snapshot + * length, we should just increase MAXIMUM_SNAPLEN. + */ + if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) + p->snapshot = MAXIMUM_SNAPLEN; + /* Set promiscuous mode */ if (p->opt.promisc) { @@ -1074,13 +1085,14 @@ pcap_activate_win32(pcap_t *p) goto bad; } } - } - else + } else { + /* + * Dag Card + */ #ifdef HAVE_DAG_API - { - /* - * Dag Card - */ + /* + * We have DAG support. + */ LONG status; HKEY dagkey; DWORD lptype; @@ -1114,15 +1126,18 @@ pcap_activate_win32(pcap_t *p) while(FALSE); - p->snapshot = PacketSetSnapLen(p->adapter, snaplen); + p->snapshot = PacketSetSnapLen(p->adapter, p->snapshot); /* Set the length of the FCS associated to any packet. This value * will be subtracted to the packet length */ pw->dag_fcs_bits = p->adapter->DagFcsLen; - } -#else - goto bad; +#else /* HAVE_DAG_API */ + /* + * No DAG support. + */ + goto bad; #endif /* HAVE_DAG_API */ + } PacketSetReadTimeout(p->adapter, p->opt.timeout); diff --git a/pcap.c b/pcap.c index 54e19f2c..bb5e648b 100644 --- a/pcap.c +++ b/pcap.c @@ -1334,7 +1334,7 @@ pcap_create_common(char *ebuf, size_t size) initialize_ops(p); /* put in some defaults*/ - p->snapshot = MAXIMUM_SNAPLEN; /* max packet size */ + p->snapshot = 0; /* max packet size unspecified */ p->opt.timeout = 0; /* no timeout specified */ p->opt.buffer_size = 0; /* use the platform's default */ p->opt.promisc = 0; @@ -1367,16 +1367,6 @@ pcap_set_snaplen(pcap_t *p, int snaplen) { if (pcap_check_activated(p)) return (PCAP_ERROR_ACTIVATED); - - /* - * Turn invalid values, or excessively large values, into - * the maximum allowed value. - * - * If some application really *needs* a bigger snapshot - * length, we should just increase MAXIMUM_SNAPLEN. - */ - if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN) - snaplen = MAXIMUM_SNAPLEN; p->snapshot = snaplen; return (0); }