From: Jeremie Corbier 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 --- 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);