diff options
author | Jo-Philipp Wich <jo@mein.io> | 2018-12-21 08:50:36 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-05-26 16:21:13 +0200 |
commit | 71b00ab6f2ef13c697f8de9b3468e31f685b58d8 (patch) | |
tree | 55781aef2dddd90c844b563647259af9742eb34c | |
parent | c7bb956634126de2b1c945015da2cd4537236d16 (diff) | |
download | rpcd-71b00ab6f2ef13c697f8de9b3468e31f685b58d8.tar.gz |
file: rpc_file_exec_run: fix potential memory leak and integer overflow
- Store the realloc result in a separate pointer so that we can free
the original on allocation failure
- Use an explicit uint8_t for the argument vector length instead of
"char" which might be signed or unsigned, depending on the arch
- Bail out with an invalid argument error if the argument vector
exceeds 255 items
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit e5243c16eb214d2f6a2008ca4f15c4eb3ec6682c)
-rw-r--r-- | file.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -20,6 +20,7 @@ #include <fcntl.h> #include <errno.h> #include <unistd.h> +#include <stdint.h> #include <stdlib.h> #include <string.h> #include <limits.h> @@ -326,7 +327,7 @@ static int rpc_file_md5(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ +{ int rv, i; char *path; struct stat s; @@ -606,8 +607,8 @@ rpc_file_exec_run(const char *cmd, int rem; struct blob_attr *cur; - char arglen; - char **args; + uint8_t arglen; + char **args, **tmp; struct rpc_file_exec_context *c; @@ -657,11 +658,22 @@ rpc_file_exec_run(const char *cmd, if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) continue; + if (arglen == 255) + { + free(args); + return UBUS_STATUS_INVALID_ARGUMENT; + } + arglen++; + tmp = realloc(args, sizeof(char *) * arglen); - if (!(args = realloc(args, sizeof(char *) * arglen))) + if (!tmp) + { + free(args); return UBUS_STATUS_UNKNOWN_ERROR; + } + args = tmp; args[arglen-2] = blobmsg_data(cur); args[arglen-1] = NULL; } |