diff options
Diffstat (limited to '')
-rw-r--r-- | lib/idmapping.c (renamed from libmisc/idmapping.c) | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/libmisc/idmapping.c b/lib/idmapping.c index 30eb89f..56c72ea 100644 --- a/libmisc/idmapping.c +++ b/lib/idmapping.c @@ -11,13 +11,20 @@ #include <limits.h> #include <stdlib.h> #include <stdio.h> +#include <strings.h> + +#include "alloc.h" +#include "atoi/str2i.h" #include "prototypes.h" +#include "string/stpeprintf.h" #include "idmapping.h" #if HAVE_SYS_CAPABILITY_H #include <sys/prctl.h> #include <sys/capability.h> #endif #include "shadowlog.h" +#include "sizeof.h" + struct map_range *get_map_ranges(int ranges, int argc, char **argv) { @@ -29,21 +36,12 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv) return NULL; } - if (ranges != ((argc + 2) / 3)) { + if (ranges * 3 != argc) { fprintf(log_get_logfd(), "%s: ranges: %u is wrong for argc: %d\n", log_get_progname(), ranges, argc); return NULL; } - if ((ranges * 3) > argc) { - fprintf(log_get_logfd(), "ranges: %u argc: %d\n", - ranges, argc); - fprintf(log_get_logfd(), - _( "%s: Not enough arguments to form %u mappings\n"), - log_get_progname(), ranges); - return NULL; - } - - mappings = calloc(ranges, sizeof(*mappings)); + mappings = CALLOC(ranges, struct map_range); if (!mappings) { fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"), log_get_progname()); @@ -53,15 +51,15 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv) /* Gather up the ranges from the command line */ mapping = mappings; for (idx = 0, argidx = 0; idx < ranges; idx++, argidx += 3, mapping++) { - if (!getulong(argv[argidx + 0], &mapping->upper)) { + if (str2ul(&mapping->upper, argv[argidx + 0]) == -1) { free(mappings); return NULL; } - if (!getulong(argv[argidx + 1], &mapping->lower)) { + if (str2ul(&mapping->lower, argv[argidx + 1]) == -1) { free(mappings); return NULL; } - if (!getulong(argv[argidx + 2], &mapping->count)) { + if (str2ul(&mapping->count, argv[argidx + 2]) == -1) { free(mappings); return NULL; } @@ -99,7 +97,7 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv) * 8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real) * 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real) */ -#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3) +#define ULONG_DIGITS (((WIDTHOF(unsigned long) + 9)/10)*3) #if HAVE_SYS_CAPABILITY_H static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings) @@ -141,7 +139,7 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings int idx; const struct map_range *mapping; size_t bufsize; - char *buf, *pos; + char *buf, *pos, *end; int fd; #if HAVE_SYS_CAPABILITY_H @@ -172,7 +170,7 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings } /* Lockdown new{g,u}idmap by dropping all unneeded capabilities. */ - memset(data, 0, sizeof(data)); + bzero(data, sizeof(data)); data[0].effective = CAP_TO_MASK(cap); /* * When uid 0 from the ancestor userns is supposed to be mapped into @@ -187,23 +185,22 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings } #endif - bufsize = ranges * ((ULONG_DIGITS + 1) * 3); - pos = buf = xmalloc(bufsize); + bufsize = (ULONG_DIGITS + 1) * 3 * ranges + 1; + pos = buf = XMALLOC(bufsize, char); + end = buf + bufsize; /* Build the mapping command */ mapping = mappings; for (idx = 0; idx < ranges; idx++, mapping++) { /* Append this range to the string that will be written */ - int written = snprintf(pos, bufsize - (pos - buf), - "%lu %lu %lu\n", - mapping->upper, - mapping->lower, - mapping->count); - if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { - fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - pos += written; + pos = stpeprintf(pos, end, "%lu %lu %lu\n", + mapping->upper, + mapping->lower, + mapping->count); + } + if (pos == end || pos == NULL) { + fprintf(log_get_logfd(), _("%s: stpeprintf failed!\n"), log_get_progname()); + exit(EXIT_FAILURE); } /* Write the mapping to the mapping file */ @@ -213,11 +210,15 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings log_get_progname(), map_file, strerror(errno)); exit(EXIT_FAILURE); } - if (write(fd, buf, pos - buf) != (pos - buf)) { + if (write_full(fd, buf, pos - buf) == -1) { fprintf(log_get_logfd(), _("%s: write to %s failed: %s\n"), log_get_progname(), map_file, strerror(errno)); exit(EXIT_FAILURE); } - close(fd); + if (close(fd) != 0 && errno != EINTR) { + fprintf(log_get_logfd(), _("%s: closing %s failed: %s\n"), + log_get_progname(), map_file, strerror(errno)); + exit(EXIT_FAILURE); + } free(buf); } |