Blame SOURCES/libcap-static-analysis-fix-3.patch

0331fa
diff --color -ru a/libcap/_makenames.c b/libcap/_makenames.c
0331fa
--- a/libcap/_makenames.c	2022-01-28 14:41:38.357147972 +0100
0331fa
+++ b/libcap/_makenames.c	2022-01-28 14:42:45.681379827 +0100
0331fa
@@ -45,7 +45,7 @@
0331fa
 	if (maxcaps <= list[i].index) {
0331fa
 	    maxcaps = list[i].index + 1;
0331fa
 	}
0331fa
-        if (list[i].index >= pointers_avail) {
0331fa
+        if (pointers == NULL || list[i].index >= pointers_avail) {
0331fa
 	    int was = pointers_avail * sizeof(char *);
0331fa
 	    pointers_avail = 2 * list[i].index + 1;
0331fa
 	    pointers = recalloc(pointers, was, pointers_avail * sizeof(char *));
0331fa
diff --color -ru a/progs/capsh.c b/progs/capsh.c
0331fa
--- a/progs/capsh.c	2022-01-28 14:41:38.359148009 +0100
0331fa
+++ b/progs/capsh.c	2022-01-28 14:42:45.682379846 +0100
0331fa
@@ -34,6 +34,35 @@
0331fa
 
0331fa
 #define MAX_GROUPS       100   /* max number of supplementary groups for user */
0331fa
 
0331fa
+/* parse a non-negative integer with some error handling */
0331fa
+static unsigned long nonneg_uint(const char *text, const char *prefix, int *ok)
0331fa
+{
0331fa
+    char *remains;
0331fa
+    unsigned long value;
0331fa
+    ssize_t len = strlen(text);
0331fa
+
0331fa
+    if (len == 0 || *text == '-') {
0331fa
+	goto fail;
0331fa
+    }
0331fa
+    value = strtoul(text, &remains, 0);
0331fa
+    if (*remains) {
0331fa
+	goto fail;
0331fa
+    }
0331fa
+    if (ok != NULL) {
0331fa
+	*ok = 1;
0331fa
+    }
0331fa
+    return value;
0331fa
+
0331fa
+fail:
0331fa
+    if (ok == NULL) {
0331fa
+	fprintf(stderr, "%s: want non-negative integer, got \"%s\"\n",
0331fa
+		prefix, text);
0331fa
+	exit(1);
0331fa
+    }
0331fa
+    *ok = 0;
0331fa
+    return 0;
0331fa
+}
0331fa
+
0331fa
 static char *binary(unsigned long value)
0331fa
 {
0331fa
     static char string[8*sizeof(unsigned long) + 1];
0331fa
@@ -362,7 +391,7 @@
0331fa
 
0331fa
     parts = strdup(path);
0331fa
     if (parts == NULL) {
0331fa
-        fprintf(stderr, "insufficient memory for parts of path\n");
0331fa
+	fprintf(stderr, "insufficient memory for parts of path\n");
0331fa
 	exit(1);
0331fa
     }
0331fa
 
0331fa
@@ -610,7 +639,7 @@
0331fa
 	    unsigned value;
0331fa
 	    int set;
0331fa
 
0331fa
-	    value = strtoul(argv[i]+7, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+7, "invalid --keep value", NULL);
0331fa
 	    set = prctl(PR_SET_KEEPCAPS, value);
0331fa
 	    if (set < 0) {
0331fa
 		fprintf(stderr, "prctl(PR_SET_KEEPCAPS, %u) failed: %s\n",
0331fa
@@ -667,7 +696,7 @@
0331fa
 	} else if (!strncmp("--secbits=", argv[i], 10)) {
0331fa
 	    unsigned value;
0331fa
 	    int status;
0331fa
-	    value = strtoul(argv[i]+10, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+10, "invalid --secbits value", NULL);
0331fa
 	    status = cap_set_secbits(value);
0331fa
 	    if (status < 0) {
0331fa
 		fprintf(stderr, "failed to set securebits to 0%o/0x%x\n",
0331fa
@@ -680,7 +709,7 @@
0331fa
 		fprintf(stderr, "already forked\n");
0331fa
 		exit(1);
0331fa
 	    }
0331fa
-	    value = strtoul(argv[i]+10, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+10, "invalid --forkfor value", NULL);
0331fa
 	    if (value == 0) {
0331fa
 		goto usage;
0331fa
 	    }
0331fa
@@ -696,7 +725,8 @@
0331fa
 	    pid_t result;
0331fa
 	    unsigned value;
0331fa
 
0331fa
-	    value = strtoul(argv[i]+9, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+9, "invalid --killit signo value",
0331fa
+				NULL);
0331fa
 	    if (!child) {
0331fa
 		fprintf(stderr, "no forked process to kill\n");
0331fa
 		exit(1);
0331fa
@@ -722,7 +752,7 @@
0331fa
 	    unsigned value;
0331fa
 	    int status;
0331fa
 
0331fa
-	    value = strtoul(argv[i]+6, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+6, "invalid --uid value", NULL);
0331fa
 	    status = setuid(value);
0331fa
 	    if (status < 0) {
0331fa
 		fprintf(stderr, "Failed to set uid=%u: %s\n",
0331fa
@@ -733,7 +763,7 @@
0331fa
 	    unsigned value;
0331fa
 	    int status;
0331fa
 
0331fa
-	    value = strtoul(argv[i]+10, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+10, "invalid --cap-uid value", NULL);
0331fa
 	    status = cap_setuid(value);
0331fa
 	    if (status < 0) {
0331fa
 		fprintf(stderr, "Failed to cap_setuid(%u): %s\n",
0331fa
@@ -744,7 +774,7 @@
0331fa
 	    unsigned value;
0331fa
 	    int status;
0331fa
 
0331fa
-	    value = strtoul(argv[i]+6, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+6, "invalid --gid value", NULL);
0331fa
 	    status = setgid(value);
0331fa
 	    if (status < 0) {
0331fa
 		fprintf(stderr, "Failed to set gid=%u: %s\n",
0331fa
@@ -924,7 +954,7 @@
0331fa
 	} else if (!strncmp("--is-uid=", argv[i], 9)) {
0331fa
 	    unsigned value;
0331fa
 	    uid_t uid;
0331fa
-	    value = strtoul(argv[i]+9, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+9, "invalid --is-uid value", NULL);
0331fa
 	    uid = getuid();
0331fa
 	    if (uid != value) {
0331fa
 		fprintf(stderr, "uid: got=%d, want=%d\n", uid, value);
0331fa
@@ -933,7 +963,7 @@
0331fa
 	} else if (!strncmp("--is-gid=", argv[i], 9)) {
0331fa
 	    unsigned value;
0331fa
 	    gid_t gid;
0331fa
-	    value = strtoul(argv[i]+9, NULL, 0);
0331fa
+	    value = nonneg_uint(argv[i]+9, "invalid --is-gid value", NULL);
0331fa
 	    gid = getgid();
0331fa
 	    if (gid != value) {
0331fa
 		fprintf(stderr, "gid: got=%d, want=%d\n", gid, value);
0331fa
diff --color -ru a/tests/libcap_psx_test.c b/tests/libcap_psx_test.c
0331fa
--- a/tests/libcap_psx_test.c	2022-01-28 14:41:38.360148027 +0100
0331fa
+++ b/tests/libcap_psx_test.c	2022-01-28 14:42:45.683379864 +0100
0331fa
@@ -21,7 +21,10 @@
0331fa
 	exit(1);
0331fa
     }
0331fa
     if (pid == 0) {
0331fa
-	cap_set_proc(start);
0331fa
+	if (cap_set_proc(start)) {
0331fa
+	    perror("setting empty caps failed");
0331fa
+	    exit(1);
0331fa
+	}
0331fa
 	exit(0);
0331fa
     }
0331fa
     int res;
0331fa
@@ -51,7 +54,10 @@
0331fa
     for (i = 0; i < 10; i++) {
0331fa
 	printf(".");     /* because of fork, this may print double */
0331fa
 	fflush(stdout);  /* try to limit the above effect */
0331fa
-	cap_set_proc(start);
0331fa
+	if (cap_set_proc(start)) {
0331fa
+	    perror("failed to set proc");
0331fa
+	    exit(1);
0331fa
+	}
0331fa
 	usleep(1000);
0331fa
     }
0331fa
     printf(" PASSED\n");