summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorJoe Orton <jorton@apache.org>2020-04-20 09:25:39 +0000
committerJoe Orton <jorton@apache.org>2020-04-20 09:25:39 +0000
commit156dbb6aafd59f4d3a113fcfa247972a39956765 (patch)
tree79b76eeb7d888e4ba79a58079e83f0a0c3c93e91 /support
parent837428cafecc5acb7d793b0dc3796ae0588d3e99 (diff)
downloadhttpd-156dbb6aafd59f4d3a113fcfa247972a39956765.tar.gz
* support/suexec.c (safe_strtol): New function.
(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
Diffstat (limited to 'support')
-rw-r--r--support/suexec.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/support/suexec.c b/support/suexec.c
index 2ebacb9bee..8b81eebd37 100644
--- a/support/suexec.c
+++ b/support/suexec.c
@@ -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);
}