Blob Blame History Raw
From: Jeremie Corbier <jeremie@famille-corbier.net>
Date: Tue, 2 Dec 2014 10:52:42 +0100
Subject: Close file descriptors on exec

Avoid FD leakage to children
Closes: #757848

Signed-off-by: Jeremie Corbier <jeremie@famille-corbier.net>
---
 cftoken.c            |  8 ++++++++
 cftoken.l            |  8 ++++++++
 common.c             | 15 ++++++++++++++-
 dhcp6_ctl.c          |  3 +++
 dhcp6_ctlclient.c    |  3 +++
 dhcp6c.c             | 11 ++++++++++-
 dhcp6relay.c         |  6 ++++++
 missing/getifaddrs.c |  9 +++++++--
 8 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/cftoken.c b/cftoken.c
index 0f6c1bf..079f274 100644
--- a/cftoken.c
+++ b/cftoken.c
@@ -2539,7 +2539,11 @@ cfswitch_buffer(incl)
 	incstack[incstackp].state = YY_CURRENT_BUFFER;
 	incstack[incstackp].lineno = lineno;
 
+#ifdef __linux__
+	fp = fopen(path, "re");
+#else
 	fp = fopen(path, "r");
+#endif
 	if (fp == NULL) {
 		debug_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s",
 			path, strerror(errno));
@@ -2562,7 +2566,11 @@ cfparse(conf)
 	char *conf;
 {
 	configfilename = conf;
+#ifdef __linux__
+	if ((yyin = fopen(configfilename, "re")) == NULL) {
+#else
 	if ((yyin = fopen(configfilename, "r")) == NULL) {
+#endif
 		debug_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s",
 			configfilename, strerror(errno));
 		if (errno == ENOENT)
diff --git a/cftoken.l b/cftoken.l
index 6afda5f..f480406 100644
--- a/cftoken.l
+++ b/cftoken.l
@@ -415,7 +415,11 @@ cfswitch_buffer(incl)
 	incstack[incstackp].state = YY_CURRENT_BUFFER;
 	incstack[incstackp].lineno = lineno;
 
+#ifdef __linux__
+	fp = fopen(path, "re");
+#else
 	fp = fopen(path, "r");
+#endif
 	if (fp == NULL) {
 		debug_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s",
 			path, strerror(errno));
@@ -438,7 +442,11 @@ cfparse(conf)
 	char *conf;
 {
 	configfilename = conf;
+#ifdef __linux__
+	if ((yyin = fopen(configfilename, "re")) == NULL) {
+#else
 	if ((yyin = fopen(configfilename, "r")) == NULL) {
+#endif
 		debug_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s",
 			configfilename, strerror(errno));
 		if (errno == ENOENT)
diff --git a/common.c b/common.c
index cc4abcc..b5c09c3 100644
--- a/common.c
+++ b/common.c
@@ -1115,7 +1115,11 @@ getifhwaddr(const char *ifname, char *buf, u_int16_t *hwtypep, int ppa)
 		(void) snprintf(fname, sizeof (fname), "/dev/%s", ifname);
 	getctl.maxlen = sizeof (getbuf);
 	getctl.buf = (char *)getbuf;
+#ifdef __linux__
+	if ((fd = open(fname, O_RDWR | O_CLOEXEC)) == -1) {
+#else
 	if ((fd = open(fname, O_RDWR)) == -1) {
+#endif
 		dl_attach_req_t dlar;
 
 		cp = fname + strlen(fname) - 1;
@@ -1131,7 +1135,11 @@ getifhwaddr(const char *ifname, char *buf, u_int16_t *hwtypep, int ppa)
 		cp++;
 		dlar.dl_ppa = atoi(cp);
 		*cp = '\0';
+#ifdef __linux__
+		if ((fd = open(fname, O_RDWR | O_CLOEXEC)) == -1)
+#else
 		if ((fd = open(fname, O_RDWR)) == -1)
+#endif
 			return (-1);
 		dlar.dl_primitive = DL_ATTACH_REQ;
 		putctl.len = sizeof (dlar);
@@ -3292,7 +3300,12 @@ ifaddrconf(cmd, ifname, addr, plen, pltime, vltime)
 		return (-1);
 	}
 
-	if ((s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+#ifdef __linux__
+#define SOCKTYPE (SOCK_DGRAM | SOCK_CLOEXEC)
+#else
+#define SOCKTYPE SOCK_DGRAM
+#endif
+	if ((s = socket(PF_INET6, SOCKTYPE, IPPROTO_UDP)) < 0) {
 		debug_printf(LOG_ERR, FNAME, "can't open a temporary socket: %s",
 		    strerror(errno));
 		return (-1);
diff --git a/dhcp6_ctl.c b/dhcp6_ctl.c
index a12f82a..f1bae0b 100644
--- a/dhcp6_ctl.c
+++ b/dhcp6_ctl.c
@@ -97,6 +97,9 @@ dhcp6_ctl_init(addr, port, max, sockp)
 		    gai_strerror(error));
 		return (-1);
 	}
+#ifdef __linux__
+	res->ai_socktype |= SOCK_CLOEXEC;
+#endif
 	ctlsock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 	if (ctlsock < 0) {
 		debug_printf(LOG_ERR, FNAME, "socket(control sock): %s",
diff --git a/dhcp6_ctlclient.c b/dhcp6_ctlclient.c
index 5597c9e..2bec3e7 100644
--- a/dhcp6_ctlclient.c
+++ b/dhcp6_ctlclient.c
@@ -169,6 +169,9 @@ main(argc, argv)
 
 	s = -1;
 	for (res = res0; res != NULL; res = res->ai_next) {
+#ifdef __linux__
+		res->ai_socktype |= SOCK_CLOEXEC;
+#endif
 		s = socket(res->ai_family, res->ai_socktype,
 		    res->ai_protocol);
 		if (s < 0) {
diff --git a/dhcp6c.c b/dhcp6c.c
index 1953f76..ccb601c 100644
--- a/dhcp6c.c
+++ b/dhcp6c.c
@@ -290,6 +290,10 @@ client6_init()
 		    gai_strerror(error));
 		exit(1);
 	}
+#ifdef __linux__
+	/* Force socket to be closed on execve */
+	res->ai_socktype |= SOCK_CLOEXEC;
+#endif
 	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 	if (sock < 0) {
 		debug_printf(LOG_ERR, FNAME, "socket");
@@ -346,7 +350,12 @@ client6_init()
 	freeaddrinfo(res);
 
 	/* open a routing socket to watch the routing table */
-	if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
+#ifdef __linux__
+#define SOCKTYPE (SOCK_RAW | SOCK_CLOEXEC)
+#else
+#define SOCKTYPE SOCK_RAW
+#endif
+	if ((rtsock = socket(PF_ROUTE, SOCKTYPE, 0)) < 0) {
 		debug_printf(LOG_ERR, FNAME, "open a routing socket: %s",
 		    strerror(errno));
 		exit(1);
diff --git a/dhcp6relay.c b/dhcp6relay.c
index 99b1227..200d3cb 100644
--- a/dhcp6relay.c
+++ b/dhcp6relay.c
@@ -359,6 +359,9 @@ relay6_init(int ifnum, char *iflist[])
 		    gai_strerror(error));
 		goto failexit;
 	}
+#ifdef __linux__
+	res->ai_socktype |= SOCK_CLOEXEC;
+#endif
 	csock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 	if (csock < 0) {
 		debug_printf(LOG_ERR, FNAME, "socket(csock): %s", strerror(errno));
@@ -465,6 +468,9 @@ relay6_init(int ifnum, char *iflist[])
 		goto failexit;
 	}
 	memcpy(&sa6_client, res->ai_addr, sizeof (sa6_client));
+#ifdef __linux__
+	res->ai_socktype |= SOCK_CLOEXEC;
+#endif
 	ssock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 	if (ssock < 0) {
 		debug_printf(LOG_ERR, FNAME, "socket(outsock): %s",
diff --git a/missing/getifaddrs.c b/missing/getifaddrs.c
index 4320c43..23b3e43 100644
--- a/missing/getifaddrs.c
+++ b/missing/getifaddrs.c
@@ -167,9 +167,14 @@ getifaddrs(struct ifaddrs **ifap)
 	struct ifaddrs *ifa = NULL;
 	char *buf;
 
-	if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+#ifdef __linux__
+#define SOCKTYPE (SOCK_DGRAM | SOCK_CLOEXEC)
+#else
+#define SOCKTYPE SOCK_DGRAM
+#endif
+	if ((fd4 = socket(AF_INET, SOCKTYPE, 0)) == -1)
 		return (-1);
-	if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 &&
+	if ((fd6 = socket(AF_INET6, SOCKTYPE, 0)) == -1 &&
 	    errno != EAFNOSUPPORT) {
 		(void) close(fd4);
 		return (-1);