aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-11-06 08:02:20 -0700
committerAndrew G. Morgan <morgan@kernel.org>2021-11-06 08:02:20 -0700
commit8e1e967bc8d99a3233d51f67f6b88620cdff78dc (patch)
treeb3162861d8e6bd22e9e92cd2f98f9e2e8d7022b2
parent5306fa23ff92832be949b28d86eec39b54fbee26 (diff)
downloadlibcap-8e1e967bc8d99a3233d51f67f6b88620cdff78dc.tar.gz
setcap: clean up error handling of the ns rootid argument.
Bug reported by Artem S. Tashkinov: https://bugzilla.kernel.org/show_bug.cgi?id=214909 Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--progs/setcap.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/progs/setcap.c b/progs/setcap.c
index f8be53a..02a8a5d 100644
--- a/progs/setcap.c
+++ b/progs/setcap.c
@@ -26,13 +26,42 @@ static void usage(int status)
" -h this message and exit status 0\n"
" -q quietly\n"
" -v validate supplied capability matches file\n"
- " -n <rootid> write a user namespace limited capability\n"
+ " -n <rootid> write a user namespace (!= 0) limited capability\n"
" --license display the license info\n"
);
exit(status);
}
-#define MAXCAP 2048
+/* parse a positive integer with some error handling */
+static unsigned long pos_uint(const char *text, const char *prefix, int *ok)
+{
+ char *remains;
+ unsigned long value;
+ ssize_t len = strlen(text);
+
+ if (len == 0 || *text == '-') {
+ goto fail;
+ }
+ value = strtoul(text, &remains, 0);
+ if (*remains || value == 0) {
+ goto fail;
+ }
+ if (ok != NULL) {
+ *ok = 1;
+ }
+ return value;
+
+fail:
+ if (ok == NULL) {
+ fprintf(stderr, "%s: want positive integer, got \"%s\"\n",
+ prefix, text);
+ exit(1);
+ }
+ *ok = 0;
+ return 0;
+}
+
+#define MAXCAP 2048
static int read_caps(int quiet, const char *filename, char *buffer)
{
@@ -99,7 +128,7 @@ int main(int argc, char **argv)
if (!strcmp("--license", *argv)) {
printf(
"%s see LICENSE file for details.\n"
- "Copyright (c) 1997,2007-8,2020,21 Andrew G. Morgan"
+ "Copyright (c) 1997,2007-8,2020-21 Andrew G. Morgan"
" <morgan@kernel.org>\n", argv[0]);
exit(0);
}
@@ -117,11 +146,7 @@ int main(int argc, char **argv)
exit(1);
}
--argc;
- rootid = (uid_t) atoi(*++argv);
- if (rootid+1 < 2) {
- fprintf(stderr, "invalid rootid!=0 of '%s'", *argv);
- exit(1);
- }
+ rootid = (uid_t) pos_uint(*++argv, "bad ns rootid", NULL);
continue;
}