summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2015-12-22 10:55:47 -0200
committerRenato Botelho <renato@netgate.com>2015-12-22 10:55:47 -0200
commit109a7ad1ec5fcb58bce8d91fa982b503050dcf06 (patch)
treed9e78329f327edd0a32a31a41466357b4210a662 /lib/libc
parentcfe34c66a5ecf4b4d0db428dcaa83bc1959944e9 (diff)
parentdf0dedf653f6c09947ccd61ca9509629c4fb7d2f (diff)
downloadFreeBSD-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.34
-rw-r--r--lib/libc/net/getaddrinfo.c5
-rw-r--r--lib/libc/regex/grot/Makefile2
-rw-r--r--lib/libc/resolv/res_data.c91
-rw-r--r--lib/libc/resolv/res_init.c26
-rw-r--r--lib/libc/resolv/res_mkquery.c4
-rw-r--r--lib/libc/resolv/res_mkupdate.c4
-rw-r--r--lib/libc/resolv/res_private.h5
-rw-r--r--lib/libc/resolv/res_query.c4
-rw-r--r--lib/libc/resolv/res_send.c4
-rw-r--r--lib/libc/resolv/res_state.c39
-rw-r--r--lib/libc/yp/yplib.c33
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;
}
OpenPOWER on IntegriCloud