Blob Blame History Raw
diff --color -ru a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c
--- a/pam_cap/pam_cap.c	2021-02-05 06:52:17.000000000 +0100
+++ b/pam_cap/pam_cap.c	2021-04-23 09:48:00.091122637 +0200
@@ -218,7 +218,7 @@
 	if (!cap_set_proc(cap_s)) {
 	    ok = 1;
 	}
-	goto cleanup_cap_s;
+	goto cleanup_conf;
     }
 
     iab = cap_iab_from_text(conf_caps);
@@ -238,10 +238,9 @@
     _pam_drop(conf_caps);
 
 cleanup_cap_s:
-    if (cap_s) {
-	cap_free(cap_s);
-	cap_s = NULL;
-    }
+    cap_free(cap_s);
+    cap_s = NULL;
+
     return ok;
 }
 
diff --color -ru a/progs/capsh.c b/progs/capsh.c
--- a/progs/capsh.c	2021-02-05 06:52:17.000000000 +0100
+++ b/progs/capsh.c	2021-04-23 09:48:00.095122691 +0200
@@ -336,8 +336,8 @@
  */
 static char *find_self(const char *arg0)
 {
-    int i;
-    char *parts, *dir, *scratch;
+    int i, status=1;
+    char *p = NULL, *parts, *dir, *scratch;
     const char *path;
 
     for (i = strlen(arg0)-1; i >= 0 && arg0[i] != '/'; i--);
@@ -352,21 +352,45 @@
     }
 
     parts = strdup(path);
+    if (parts == NULL) {
+        fprintf(stderr, "insufficient memory for parts of path\n");
+	exit(1);
+    }
+
     scratch = malloc(2+strlen(path)+strlen(arg0));
-    if (parts == NULL || scratch == NULL) {
+    if (scratch == NULL) {
         fprintf(stderr, "insufficient memory for path building\n");
-	exit(1);
+	goto free_parts;
     }
 
-    for (i=0; (dir = strtok(parts, ":")); parts = NULL) {
+    for (p = parts; (dir = strtok(p, ":")); p = NULL) {
         sprintf(scratch, "%s/%s", dir, arg0);
 	if (access(scratch, X_OK) == 0) {
-            return scratch;
+	    status = 0;
+	    break;
 	}
     }
+    if (status) {
+	fprintf(stderr, "unable to find executable '%s' in PATH\n", arg0);
+	free(scratch);
+    }
+
+free_parts:
+    free(parts);
+    if (status) {
+	exit(status);
+    }
+    return scratch;
+}
 
-    fprintf(stderr, "unable to find executable '%s' in PATH\n", arg0);
-    exit(1);
+static long safe_sysconf(int name)
+{
+    long ans = sysconf(name);
+    if (ans <= 0) {
+	fprintf(stderr, "sysconf(%d) returned a non-positive number: %ld\n", name, ans);
+	exit(1);
+    }
+    return ans;
 }
 
 int main(int argc, char *argv[], char *envp[])
@@ -617,7 +641,9 @@
 	     * Given we are now in a new directory tree, its good practice
 	     * to start off in a sane location
 	     */
-	    status = chdir("/");
+	    if (status == 0) {
+		status = chdir("/");
+	    }
 
 	    cap_free(orig);
 
@@ -718,14 +744,14 @@
 	  gid_t *group_list;
 	  int g_count;
 
-	  length = sysconf(_SC_GETGR_R_SIZE_MAX);
+	  length = safe_sysconf(_SC_GETGR_R_SIZE_MAX);
 	  buf = calloc(1, length);
 	  if (NULL == buf) {
 	    fprintf(stderr, "No memory for [%s] operation\n", argv[i]);
 	    exit(1);
 	  }
 
-	  max_groups = sysconf(_SC_NGROUPS_MAX);
+	  max_groups = safe_sysconf(_SC_NGROUPS_MAX);
 	  group_list = calloc(max_groups, sizeof(gid_t));
 	  if (NULL == group_list) {
 	    fprintf(stderr, "No memory for gid list\n");
@@ -741,8 +767,7 @@
 	    }
 	    if (!isdigit(*ptr)) {
 	      struct group *g, grp;
-	      getgrnam_r(ptr, &grp, buf, length, &g);
-	      if (NULL == g) {
+	      if (getgrnam_r(ptr, &grp, buf, length, &g) || NULL == g) {
 		fprintf(stderr, "Failed to identify gid for group [%s]\n", ptr);
 		exit(1);
 	      }
@@ -835,6 +860,7 @@
 	    argv[argc] = NULL;
 	    execve(argv[i], argv+i, envp);
 	    fprintf(stderr, "execve '%s' failed!\n", argv[i]);
+	    free(argv[i]);
 	    exit(1);
 	} else if (!strncmp("--shell=", argv[i], 8)) {
 	    shell = argv[i]+8;
diff --color -ru a/psx/psx.c b/psx/psx.c
--- a/psx/psx.c	2021-02-05 06:52:17.000000000 +0100
+++ b/psx/psx.c	2021-04-23 09:48:00.095122691 +0200
@@ -454,6 +454,10 @@
 int __wrap_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
 			  void *(*start_routine) (void *), void *arg) {
     psx_starter_t *starter = calloc(1, sizeof(psx_starter_t));
+    if (starter == NULL) {
+	perror("failed at thread creation");
+	exit(1);
+    }
     starter->fn = start_routine;
     starter->arg = arg;
     /*