summaryrefslogtreecommitdiffstats
path: root/lib/idmapping.c
diff options
context:
space:
mode:
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);
}