]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* support/suexec.c (safe_strtol): New function.
authorJoe Orton <jorton@apache.org>
Mon, 20 Apr 2020 09:25:39 +0000 (09:25 +0000)
committerJoe Orton <jorton@apache.org>
Mon, 20 Apr 2020 09:25:39 +0000 (09:25 +0000)
  (main): Use ^ to be avoid using atoi(); try to catch more string to
  integer and integer to uid/gid conversion errors/surprises.

PR: 33207

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1876744 13f79535-47bb-0310-9956-ffa450edef68

support/suexec.c

index 2ebacb9bee1ad0bfa00c84d04991f7cc1074dbc4..8b81eebd373bed5f806aa1ce6eeb5e623f3d35c6 100644 (file)
@@ -281,6 +281,20 @@ static void clean_env(void)
     environ = cleanenv;
 }
 
+/* Converts name (uid/gid) to long, returning -1 on error. */
+static long safe_strtol(const char *name)
+{
+    char *endp;
+    long rv;
+
+    errno = 0;
+    rv = strtol(name, &endp, 10);
+    if (errno || *endp != '\0')
+        rv = -1;
+
+    return rv;
+}
+
 int main(int argc, char *argv[])
 {
     int userdir = 0;        /* ~userdir flag             */
@@ -417,7 +431,15 @@ int main(int argc, char *argv[])
         }
     }
     else {
-        if ((pw = getpwuid(atoi(target_uname))) == NULL) {
+        long parsed_uid = safe_strtol(target_uname);
+        uid_t target_uid = parsed_uid;
+
+        /* uid_t may be signed or unsigned and may be smaller than
+         * long; try to catch long->(u)int conversion surprises and
+         * avoid calling getpwuid with a negative value though it
+         * should be safe anyway. */
+        if (parsed_uid < 0 || target_uid < 0 || target_uid != parsed_uid
+            || (pw = getpwuid(target_uid)) == NULL) {
             log_err("invalid target user id: (%s)\n", target_uname);
             exit(121);
         }
@@ -433,7 +455,12 @@ int main(int argc, char *argv[])
         }
     }
     else {
-        if ((gr = getgrgid(atoi(target_gname))) == NULL) {
+        long parsed_gid = safe_strtol(target_gname);
+        gid_t target_gid = parsed_gid;
+
+        /* See above on long to uid_t conversion. */
+        if (parsed_gid < 0 || target_gid < 0 || target_gid != parsed_gid
+            || (gr = getgrgid(target_gid)) == NULL) {
             log_err("invalid target group id: (%s)\n", target_gname);
             exit(106);
         }