components/libpcap/patches/01-pcap-bpf.m4.patch
author Jon Anderson <jon.anderson@oracle.com>
Wed, 24 Sep 2014 10:06:43 +0100
branchs11u2-sru
changeset 3328 7d4961ad30d3
permissions -rw-r--r--
19352199 libpcap does not handle zoneid and zoneid/linkname correctly

#
# 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;
 	}