diff options
Diffstat (limited to 'src/misc')
| -rw-r--r-- | src/misc/getopt.c | 3 | ||||
| -rw-r--r-- | src/misc/getrlimit.c | 2 | ||||
| -rw-r--r-- | src/misc/initgroups.c | 26 | ||||
| -rw-r--r-- | src/misc/lockf.c | 2 | ||||
| -rw-r--r-- | src/misc/mntent.c | 56 | ||||
| -rw-r--r-- | src/misc/nftw.c | 6 | ||||
| -rw-r--r-- | src/misc/setrlimit.c | 2 | ||||
| -rw-r--r-- | src/misc/syslog.c | 3 | 
8 files changed, 79 insertions, 21 deletions
| diff --git a/src/misc/getopt.c b/src/misc/getopt.c index c3f66995..b02b81c3 100644 --- a/src/misc/getopt.c +++ b/src/misc/getopt.c @@ -87,7 +87,8 @@ int getopt(int argc, char * const argv[], const char *optstring)  	if (optstring[i] == ':') {  		optarg = 0;  		if (optstring[i+1] != ':' || optpos) { -			optarg = argv[optind++] + optpos; +			optarg = argv[optind++]; +			if (optpos) optarg += optpos;  			optpos = 0;  		}  		if (optind > argc) { diff --git a/src/misc/getrlimit.c b/src/misc/getrlimit.c index bf676307..a5558d81 100644 --- a/src/misc/getrlimit.c +++ b/src/misc/getrlimit.c @@ -26,5 +26,3 @@ int getrlimit(int resource, struct rlimit *rlim)  	return ret;  #endif  } - -weak_alias(getrlimit, getrlimit64); diff --git a/src/misc/initgroups.c b/src/misc/initgroups.c index 922a9581..101f5c7b 100644 --- a/src/misc/initgroups.c +++ b/src/misc/initgroups.c @@ -1,11 +1,29 @@  #define _GNU_SOURCE  #include <grp.h>  #include <limits.h> +#include <stdlib.h>  int initgroups(const char *user, gid_t gid)  { -	gid_t groups[NGROUPS_MAX]; -	int count = NGROUPS_MAX; -	if (getgrouplist(user, gid, groups, &count) < 0) return -1; -	return setgroups(count, groups); +	gid_t buf[32], *groups = buf; +	int count = sizeof buf / sizeof *buf, prev_count = count; +	while (getgrouplist(user, gid, groups, &count) < 0) { +		if (groups != buf) free(groups); + +		/* Return if failure isn't buffer size */ +		if (count <= prev_count) +			return -1; + +		/* Always increase by at least 50% to limit to +		 * logarithmically many retries on TOCTOU races. */ +		if (count < prev_count + (prev_count>>1)) +			count = prev_count + (prev_count>>1); + +		groups = calloc(count, sizeof *groups); +		if (!groups) return -1; +		prev_count = count; +	} +	int ret = setgroups(count, groups); +	if (groups != buf) free(groups); +	return ret;  } diff --git a/src/misc/lockf.c b/src/misc/lockf.c index 16a80bec..0162442b 100644 --- a/src/misc/lockf.c +++ b/src/misc/lockf.c @@ -28,5 +28,3 @@ int lockf(int fd, int op, off_t size)  	errno = EINVAL;  	return -1;  } - -weak_alias(lockf, lockf64); diff --git a/src/misc/mntent.c b/src/misc/mntent.c index d404fbe3..76f9c162 100644 --- a/src/misc/mntent.c +++ b/src/misc/mntent.c @@ -20,6 +20,42 @@ int endmntent(FILE *f)  	return 1;  } +static char *unescape_ent(char *beg) +{ +	char *dest = beg; +	const char *src = beg; +	while (*src) { +		const char *val; +		unsigned char cval = 0; +		if (*src != '\\') { +			*dest++ = *src++; +			continue; +		} +		if (src[1] == '\\') { +			++src; +			*dest++ = *src++; +			continue; +		} +		val = src + 1; +		for (int i = 0; i < 3; ++i) { +			if (*val >= '0' && *val <= '7') { +				cval <<= 3; +				cval += *val++ - '0'; +			} else { +				break; +			} +		} +		if (cval) { +			*dest++ = cval; +			src = val; +		} else { +			*dest++ = *src++; +		} +	} +	*dest = 0; +	return beg; +} +  struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)  {  	int n[8], use_internal = (linebuf == SENTINEL); @@ -45,7 +81,7 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle  		len = strlen(linebuf);  		if (len > INT_MAX) continue;  		for (i = 0; i < sizeof n / sizeof *n; i++) n[i] = len; -		sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", +		sscanf(linebuf, " %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %n%*[^ \t\n]%n %d %d",  			n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,  			&mnt->mnt_freq, &mnt->mnt_passno);  	} while (linebuf[n[0]] == '#' || n[1]==len); @@ -55,10 +91,10 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle  	linebuf[n[5]] = 0;  	linebuf[n[7]] = 0; -	mnt->mnt_fsname = linebuf+n[0]; -	mnt->mnt_dir = linebuf+n[2]; -	mnt->mnt_type = linebuf+n[4]; -	mnt->mnt_opts = linebuf+n[6]; +	mnt->mnt_fsname = unescape_ent(linebuf+n[0]); +	mnt->mnt_dir = unescape_ent(linebuf+n[2]); +	mnt->mnt_type = unescape_ent(linebuf+n[4]); +	mnt->mnt_opts = unescape_ent(linebuf+n[6]);  	return mnt;  } @@ -79,5 +115,13 @@ int addmntent(FILE *f, const struct mntent *mnt)  char *hasmntopt(const struct mntent *mnt, const char *opt)  { -	return strstr(mnt->mnt_opts, opt); +	size_t l = strlen(opt); +	char *p = mnt->mnt_opts; +	for (;;) { +		if (!strncmp(p, opt, l) && (!p[l] || p[l]==',' || p[l]=='=')) +			return p; +		p = strchr(p, ','); +		if (!p) return 0; +		p++; +	}  } diff --git a/src/misc/nftw.c b/src/misc/nftw.c index 8dcff7fe..71bc62ee 100644 --- a/src/misc/nftw.c +++ b/src/misc/nftw.c @@ -31,6 +31,8 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,  	int err;  	struct FTW lev; +	st.st_dev = st.st_ino = 0; +  	if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {  		if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))  			type = FTW_SLN; @@ -46,7 +48,7 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,  		type = FTW_F;  	} -	if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev) +	if ((flags & FTW_MOUNT) && h && type != FTW_NS && st.st_dev != h->dev)  		return 0;  	new.chain = h; @@ -138,5 +140,3 @@ int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, str  	pthread_setcancelstate(cs, 0);  	return r;  } - -weak_alias(nftw, nftw64); diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c index 5b713cf3..edb413fa 100644 --- a/src/misc/setrlimit.c +++ b/src/misc/setrlimit.c @@ -49,5 +49,3 @@ int setrlimit(int resource, const struct rlimit *rlim)  	return __syscall_ret(ret);  #endif  } - -weak_alias(setrlimit, setrlimit64); diff --git a/src/misc/syslog.c b/src/misc/syslog.c index 7dc0c1be..710202f9 100644 --- a/src/misc/syslog.c +++ b/src/misc/syslog.c @@ -11,6 +11,7 @@  #include <fcntl.h>  #include "lock.h"  #include "fork_impl.h" +#include "locale_impl.h"  static volatile int lock[1];  static char log_ident[32]; @@ -99,7 +100,7 @@ static void _vsyslog(int priority, const char *message, va_list ap)  	now = time(NULL);  	gmtime_r(&now, &tm); -	strftime(timebuf, sizeof timebuf, "%b %e %T", &tm); +	strftime_l(timebuf, sizeof timebuf, "%b %e %T", &tm, C_LOCALE);  	pid = (log_opt & LOG_PID) ? getpid() : 0;  	l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ", | 
