diff options
author | Renato Botelho <renato@netgate.com> | 2015-12-22 10:55:47 -0200 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2015-12-22 10:55:47 -0200 |
commit | 109a7ad1ec5fcb58bce8d91fa982b503050dcf06 (patch) | |
tree | d9e78329f327edd0a32a31a41466357b4210a662 /lib/libc | |
parent | cfe34c66a5ecf4b4d0db428dcaa83bc1959944e9 (diff) | |
parent | df0dedf653f6c09947ccd61ca9509629c4fb7d2f (diff) | |
download | FreeBSD-src-109a7ad1ec5fcb58bce8d91fa982b503050dcf06.zip FreeBSD-src-109a7ad1ec5fcb58bce8d91fa982b503050dcf06.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/exec.3 | 4 | ||||
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 5 | ||||
-rw-r--r-- | lib/libc/regex/grot/Makefile | 2 | ||||
-rw-r--r-- | lib/libc/resolv/res_data.c | 91 | ||||
-rw-r--r-- | lib/libc/resolv/res_init.c | 26 | ||||
-rw-r--r-- | lib/libc/resolv/res_mkquery.c | 4 | ||||
-rw-r--r-- | lib/libc/resolv/res_mkupdate.c | 4 | ||||
-rw-r--r-- | lib/libc/resolv/res_private.h | 5 | ||||
-rw-r--r-- | lib/libc/resolv/res_query.c | 4 | ||||
-rw-r--r-- | lib/libc/resolv/res_send.c | 4 | ||||
-rw-r--r-- | lib/libc/resolv/res_state.c | 39 | ||||
-rw-r--r-- | lib/libc/yp/yplib.c | 33 |
12 files changed, 163 insertions, 58 deletions
diff --git a/lib/libc/gen/exec.3 b/lib/libc/gen/exec.3 index daeccd1..c9d32b4 100644 --- a/lib/libc/gen/exec.3 +++ b/lib/libc/gen/exec.3 @@ -28,7 +28,7 @@ .\" @(#)exec.3 8.3 (Berkeley) 1/24/94 .\" $FreeBSD$ .\" -.Dd January 24, 1994 +.Dd December 12, 2015 .Dt EXEC 3 .Os .Sh NAME @@ -223,7 +223,7 @@ and .Fn execvp functions was .Dq Pa :/bin:/usr/bin . -This was changed to place the current directory last to enhance system +This was changed to remove the current directory to enhance system security. .Pp The behavior of diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index b4c1a33..9bc2c9b 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -1562,7 +1562,7 @@ addrconfig(struct addrinfo *pai) if (seen_inet) continue; sin = (struct sockaddr_in *)(ifa->ifa_addr); - if (IN_LOOPBACK(htonl(sin->sin_addr.s_addr))) + if (htonl(sin->sin_addr.s_addr) == INADDR_LOOPBACK) continue; seen_inet = 1; break; @@ -2207,6 +2207,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; + res = __res_state(); + buf = malloc(sizeof(*buf)); if (!buf) { RES_SET_H_ERRNO(res, NETDB_INTERNAL); @@ -2253,7 +2255,6 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) return NS_UNAVAIL; } - res = __res_state(); if ((res->options & RES_INIT) == 0 && res_ninit(res) == -1) { RES_SET_H_ERRNO(res, NETDB_INTERNAL); free(buf); diff --git a/lib/libc/regex/grot/Makefile b/lib/libc/regex/grot/Makefile index e715dd8..056b55e 100644 --- a/lib/libc/regex/grot/Makefile +++ b/lib/libc/regex/grot/Makefile @@ -8,7 +8,7 @@ PATHS= ${.CURDIR}/.. ${.CURDIR}/../../locale ${.CURDIR}/../../../../include .PATH: ${PATHS} -CFLAGS+= -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS) +CFLAGS+= -static -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS) .for incpath in ${PATHS} CFLAGS+= -I${incpath} .endfor diff --git a/lib/libc/resolv/res_data.c b/lib/libc/resolv/res_data.c index f020838..e2f905f 100644 --- a/lib/libc/resolv/res_data.c +++ b/lib/libc/resolv/res_data.c @@ -77,9 +77,10 @@ const char *_res_sectioncodes[] = { int res_ourserver_p(const res_state, const struct sockaddr_in *); -int +__noinline int res_init(void) { extern int __res_vinit(res_state, int); + res_state statp = &_res; /* * These three fields used to be statically initialized. This made @@ -100,14 +101,14 @@ res_init(void) { * set in RES_DEFAULT). Our solution is to declare such applications * "broken". They could fool us by setting RES_INIT but none do (yet). */ - if (!_res.retrans) - _res.retrans = RES_TIMEOUT; - if (!_res.retry) - _res.retry = RES_DFLRETRY; - if (!(_res.options & RES_INIT)) - _res.options = RES_DEFAULT; - - return (__res_vinit(&_res, 1)); + if (!statp->retrans) + statp->retrans = RES_TIMEOUT; + if (!statp->retry) + statp->retry = RES_DFLRETRY; + if (!(statp->options & RES_INIT)) + statp->options = RES_DEFAULT; + + return (__res_vinit(statp, 1)); } void @@ -122,10 +123,11 @@ fp_query(const u_char *msg, FILE *file) { void fp_nquery(const u_char *msg, int len, FILE *file) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) return; - res_pquery(&_res, msg, len, file); + res_pquery(statp, msg, len, file); } int @@ -138,23 +140,25 @@ res_mkquery(int op, /*!< opcode of query */ u_char *buf, /*!< buffer to put query */ int buflen) /*!< size of buffer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nmkquery(&_res, op, dname, class, type, + return (res_nmkquery(statp, op, dname, class, type, data, datalen, newrr_in, buf, buflen)); } int res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nmkupdate(&_res, rrecp_in, buf, buflen)); + return (res_nmkupdate(statp, rrecp_in, buf, buflen)); } int @@ -163,11 +167,12 @@ res_query(const char *name, /*!< domain name */ u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer buffer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nquery(&_res, name, class, type, answer, anslen)); + return (res_nquery(statp, name, class, type, answer, anslen)); } #ifndef _LIBC @@ -189,12 +194,13 @@ res_isourserver(const struct sockaddr_in *inp) { int res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { /* errno should have been set by res_init() in this case. */ return (-1); } - return (res_nsend(&_res, buf, buflen, ans, anssiz)); + return (res_nsend(statp, buf, buflen, ans, anssiz)); } #ifndef _LIBC @@ -202,12 +208,13 @@ int res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, u_char *ans, int anssiz) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { /* errno should have been set by res_init() in this case. */ return (-1); } - return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz)); + return (res_nsendsigned(statp, buf, buflen, key, ans, anssiz)); } #endif @@ -218,12 +225,13 @@ res_close(void) { int res_update(ns_updrec *rrecp_in) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nupdate(&_res, rrecp_in, NULL)); + return (res_nupdate(statp, rrecp_in, NULL)); } int @@ -232,12 +240,13 @@ res_search(const char *name, /*!< domain name */ u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nsearch(&_res, name, class, type, answer, anslen)); + return (res_nsearch(statp, name, class, type, answer, anslen)); } int @@ -247,24 +256,26 @@ res_querydomain(const char *name, u_char *answer, /*!< buffer to put answer */ int anslen) /*!< size of answer */ { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nquerydomain(&_res, name, domain, + return (res_nquerydomain(statp, name, domain, class, type, answer, anslen)); } u_int res_randomid(void) { - if ((_res.options & RES_INIT) == 0U && res_init() == -1) { - RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); + res_state statp = &_res; + if ((statp->options & RES_INIT) == 0U && res_init() == -1) { + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return (-1); } - return (res_nrandomid(&_res)); + return (res_nrandomid(statp)); } int @@ -284,13 +295,15 @@ hostalias(const char *name) { int local_hostname_length(const char *hostname) { int len_host, len_domain; + res_state statp; - if (!*_res.defdname) + statp = &_res; + if (!*statp->defdname) res_init(); len_host = strlen(hostname); - len_domain = strlen(_res.defdname); + len_domain = strlen(statp->defdname); if (len_host > len_domain && - !strcasecmp(hostname + len_host - len_domain, _res.defdname) && + !strcasecmp(hostname + len_host - len_domain, statp->defdname) && hostname[len_host - len_domain - 1] == '.') return (len_host - len_domain - 1); return (0); diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index b5444ef..41e9f5a 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/param.h> #include <sys/socket.h> +#include <sys/stat.h> #include <sys/time.h> #include <netinet/in.h> @@ -115,7 +116,9 @@ __FBSDID("$FreeBSD$"); /*% Options. Should all be left alone. */ #define RESOLVSORT -#define DEBUG +#ifndef DEBUG +#define DEBUG +#endif #ifdef SOLARIS2 #include <sys/systeminfo.h> @@ -236,6 +239,7 @@ __res_vinit(res_state statp, int preinit) { statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr; strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa"); strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int"); + statp->_u._ext.ext->reload_period = 2; } else { /* * Historically res_init() rarely, if at all, failed. @@ -321,6 +325,18 @@ __res_vinit(res_state statp, int preinit) { nserv = 0; if ((fp = fopen(_PATH_RESCONF, "re")) != NULL) { + struct stat sb; + struct timespec now; + + if (statp->_u._ext.ext != NULL) { + if (_fstat(fileno(fp), &sb) == 0) { + statp->_u._ext.ext->conf_mtim = sb.st_mtim; + if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) == 0) { + statp->_u._ext.ext->conf_stat = now.tv_sec; + } + } + } + /* read the config file */ while (fgets(buf, sizeof(buf), fp) != NULL) { /* skip comments */ @@ -581,9 +597,7 @@ res_setoptions(res_state statp, const char *options, const char *source) { const char *cp = options; int i; -#ifndef _LIBC struct __res_state_ext *ext = statp->_u._ext.ext; -#endif #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -666,6 +680,12 @@ res_setoptions(res_state statp, const char *options, const char *source) } else if (!strncmp(cp, "no-check-names", sizeof("no-check-names") - 1)) { statp->options |= RES_NOCHECKNAME; + } else if (!strncmp(cp, "reload-period:", + sizeof("reload-period:") - 1)) { + if (ext != NULL) { + ext->reload_period = (u_short) + atoi(cp + sizeof("reload-period:") - 1); + } } #ifdef RES_USE_EDNS0 else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) { diff --git a/lib/libc/resolv/res_mkquery.c b/lib/libc/resolv/res_mkquery.c index b60d8f5..0d45e34 100644 --- a/lib/libc/resolv/res_mkquery.c +++ b/lib/libc/resolv/res_mkquery.c @@ -83,7 +83,9 @@ __FBSDID("$FreeBSD$"); #include "port_after.h" /* Options. Leave them on. */ -#define DEBUG +#ifndef DEBUG +#define DEBUG +#endif extern const char *_res_opcodes[]; diff --git a/lib/libc/resolv/res_mkupdate.c b/lib/libc/resolv/res_mkupdate.c index 00bce4c..5c5858d 100644 --- a/lib/libc/resolv/res_mkupdate.c +++ b/lib/libc/resolv/res_mkupdate.c @@ -54,7 +54,9 @@ __FBSDID("$FreeBSD$"); #include "port_after.h" /* Options. Leave them on. */ -#define DEBUG +#ifndef DEBUG +#define DEBUG +#endif #define MAXPORT 1024 static int getnum_str(u_char **, u_char *); diff --git a/lib/libc/resolv/res_private.h b/lib/libc/resolv/res_private.h index 4e98157..a986e95 100644 --- a/lib/libc/resolv/res_private.h +++ b/lib/libc/resolv/res_private.h @@ -1,3 +1,5 @@ +/* $FreeBSD$ */ + #ifndef res_private_h #define res_private_h @@ -12,6 +14,9 @@ struct __res_state_ext { } sort_list[MAXRESOLVSORT]; char nsuffix[64]; char nsuffix2[64]; + struct timespec conf_mtim; /* mod time of loaded resolv.conf */ + time_t conf_stat; /* time of last stat(resolv.conf) */ + u_short reload_period; /* seconds between stat(resolv.conf) */ }; extern int diff --git a/lib/libc/resolv/res_query.c b/lib/libc/resolv/res_query.c index 4ae97f6..5992edd 100644 --- a/lib/libc/resolv/res_query.c +++ b/lib/libc/resolv/res_query.c @@ -88,7 +88,9 @@ __FBSDID("$FreeBSD$"); #include "port_after.h" /* Options. Leave them on. */ -#define DEBUG +#ifndef DEBUG +#define DEBUG +#endif #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ diff --git a/lib/libc/resolv/res_send.c b/lib/libc/resolv/res_send.c index 2612682..f692522 100644 --- a/lib/libc/resolv/res_send.c +++ b/lib/libc/resolv/res_send.c @@ -119,7 +119,9 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" /* Options. Leave them on. */ -#define DEBUG +#ifndef DEBUG +#define DEBUG +#endif #include "res_debug.h" #include "res_private.h" diff --git a/lib/libc/resolv/res_state.c b/lib/libc/resolv/res_state.c index 59c9430..6d31d92 100644 --- a/lib/libc/resolv/res_state.c +++ b/lib/libc/resolv/res_state.c @@ -26,6 +26,8 @@ */ #include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <resolv.h> @@ -35,6 +37,8 @@ #include "reentrant.h" #include "un-namespace.h" +#include "res_private.h" + #undef _res struct __res_state _res; @@ -59,13 +63,44 @@ res_keycreate(void) res_thr_keycreated = thr_keycreate(&res_key, free_res) == 0; } +static res_state +res_check_reload(res_state statp) +{ + struct timespec now; + struct stat sb; + struct __res_state_ext *ext; + + if ((statp->options & RES_INIT) == 0) { + return (statp); + } + + ext = statp->_u._ext.ext; + if (ext == NULL || ext->reload_period == 0) { + return (statp); + } + + if (clock_gettime(CLOCK_MONOTONIC_FAST, &now) != 0 || + (now.tv_sec - ext->conf_stat) < ext->reload_period) { + return (statp); + } + + ext->conf_stat = now.tv_sec; + if (stat(_PATH_RESCONF, &sb) == 0 && + (sb.st_mtim.tv_sec != ext->conf_mtim.tv_sec || + sb.st_mtim.tv_nsec != ext->conf_mtim.tv_nsec)) { + statp->options &= ~RES_INIT; + } + + return (statp); +} + res_state __res_state(void) { res_state statp; if (thr_main() != 0) - return (&_res); + return res_check_reload(&_res); if (thr_once(&res_init_once, res_keycreate) != 0 || !res_thr_keycreated) @@ -73,7 +108,7 @@ __res_state(void) statp = thr_getspecific(res_key); if (statp != NULL) - return (statp); + return res_check_reload(statp); statp = calloc(1, sizeof(*statp)); if (statp == NULL) return (&_res); diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c index 1778c6a..1a6df69 100644 --- a/lib/libc/yp/yplib.c +++ b/lib/libc/yp/yplib.c @@ -655,7 +655,7 @@ yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen, struct timeval tv; struct ypreq_key yprk; int r; - + int retries = 0; *outval = NULL; *outvallen = 0; @@ -700,6 +700,11 @@ yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen, #endif again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -716,6 +721,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_match: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } @@ -772,7 +778,7 @@ yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen, struct dom_binding *ysd; struct timeval tv; int r; - + int retries = 0; /* Sanity check */ if (indomain == NULL || !strlen(indomain) || @@ -784,6 +790,11 @@ yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen, YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -802,6 +813,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_first: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } if (!(r = ypprot_err(yprkv.stat))) { @@ -844,7 +856,7 @@ yp_next(char *indomain, char *inmap, char *inkey, int inkeylen, struct dom_binding *ysd; struct timeval tv; int r; - + int retries = 0; /* Sanity check */ if (inkey == NULL || !strlen(inkey) || inkeylen <= 0 || @@ -857,6 +869,11 @@ yp_next(char *indomain, char *inmap, char *inkey, int inkeylen, YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } + if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); return (YPERR_DOMAIN); @@ -877,6 +894,7 @@ again: if (r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_next: clnt_call"); _yp_unbind(ysd); + retries++; goto again; } if (!(r = ypprot_err(yprkv.stat))) { @@ -920,7 +938,7 @@ yp_all(char *indomain, char *inmap, struct ypall_callback *incallback) CLIENT *clnt; u_long status, savstat; int clnt_sock; - + int retries = 0; /* Sanity check */ if (indomain == NULL || !strlen(indomain) || @@ -929,6 +947,10 @@ yp_all(char *indomain, char *inmap, struct ypall_callback *incallback) YPLOCK(); again: + if (retries > MAX_RETRIES) { + YPUNLOCK(); + return (YPERR_RPC); + } if (_yp_dobind(indomain, &ysd) != 0) { YPUNLOCK(); @@ -958,9 +980,10 @@ again: if (clnt_call(clnt, YPPROC_ALL, (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_all_seq, &status, tv) != RPC_SUCCESS) { - clnt_perror(ysd->dom_client, "yp_all: clnt_call"); + clnt_perror(clnt, "yp_all: clnt_call"); clnt_destroy(clnt); _yp_unbind(ysd); + retries++; goto again; } |