19352199 libpcap does not handle zoneid and zoneid/linkname correctly
authorJon Anderson <jon.anderson@oracle.com>
Thu, 18 Sep 2014 11:51:03 +0100
changeset 2093 a1854d61ecef
parent 2092 5888331a0f07
child 2094 37705edf6dec
19352199 libpcap does not handle zoneid and zoneid/linkname correctly
components/libpcap/patches/01-pcap-bpf.m4.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/libpcap/patches/01-pcap-bpf.m4.patch	Thu Sep 18 11:51:03 2014 +0100
@@ -0,0 +1,62 @@
+#
+# This patch was devleloped in house.  The changes have been fed
+# upstream and were merged into the-tcpdump-group/libpcap.  This
+# was committed under 2f9790bd3cfe56c0f78d10953571dc4b34060e4f.
+#
+# libpcap-1.7.0 is the projected release which will include this
+# change.
+#
+--- libpcap-1.5.1/pcap-bpf.c	2014-08-14 16:14:46.837979600 +0100
++++ libpcap-1.5.1/pcap-bpf.c	2014-08-18 15:13:20.805460460 +0100
+@@ -1539,22 +1539,43 @@
+ 
+ #if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
+ 	/*
++	 * Retrieve the zoneid of the zone we are currently executing in.
++	 */
++	if ((ifr.lifr_zoneid = getzoneid()) == -1) {
++		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "getzoneid(): %s",
++		     pcap_strerror(errno));
++		status = PCAP_ERROR;
++		goto bad;
++	}
++	/*
+ 	 * Check if the given source network device has a '/' separated
+-	 * zonename prefix string. The zonename prefixed source device
+-	 * can be used by libpcap consumers to capture network traffic
+-	 * in non-global zones from the global zone on Solaris 11 and
+-	 * above. If the zonename prefix is present then we strip the
+-	 * prefix and pass the zone ID as part of lifr_zoneid.
++	 * zonename prefix string.  The zonename prefixed source device can
++	 * be used by pcap consumers in the Solaris global zone to capture
++	 * traffic on datalinks in non-global zones.  Non-global zones
++	 * do not have access to datalinks outside of their own namespace.
+ 	 */
+ 	if ((zonesep = strchr(p->opt.source, '/')) != NULL) {
+-		char zonename[ZONENAME_MAX];
++		char path_zname[ZONENAME_MAX];
+ 		int  znamelen;
+ 		char *lnamep;
+ 
++		if (ifr.lifr_zoneid != GLOBAL_ZONEID) {
++			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
++			    "zonename/linkname only valid in global zone.");
++			status = PCAP_ERROR;
++			goto bad;
++		}
+ 		znamelen = zonesep - p->opt.source;
+-		(void) strlcpy(zonename, p->opt.source, znamelen + 1);
++		(void) strlcpy(path_zname, p->opt.source, znamelen + 1);
++		ifr.lifr_zoneid = getzoneidbyname(path_zname);
++		if (ifr.lifr_zoneid == -1) {
++			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
++			    "getzoneidbyname(%s): %s", path_zname,
++		    	pcap_strerror(errno));
++			status = PCAP_ERROR;
++			goto bad;
++		}
+ 		lnamep = strdup(zonesep + 1);
+-		ifr.lifr_zoneid = getzoneidbyname(zonename);
+ 		free(p->opt.source);
+ 		p->opt.source = lnamep;
+ 	}