file: extend exec acl checks to commands with arguments
When the initial exec permission check on the executable path fails, concatenate the command line with spaces and use the resulting string as lookup path for a second exec permission check. This allows for exec acls similar to this example: "file": { "/usr/bin/program --flag --option=1 arg *": [ "exec" ] } The example above would allow executing `/usr/bin/program` with the arguments `--flag`, `--option=1` and `arg` in exactly this order, followed by any number of optional arguments as denoted by the asterisk. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
77ad0de092
commit
aaa08366e6
1 changed files with 28 additions and 2 deletions
30
file.c
30
file.c
|
@ -43,6 +43,9 @@
|
|||
/* limit of regular files and command output data */
|
||||
#define RPC_FILE_MAX_SIZE (4096 * 64)
|
||||
|
||||
/* limit of command line length for exec acl checks */
|
||||
#define RPC_CMDLINE_MAX_SIZE (1024)
|
||||
|
||||
#define ustream_for_each_read_buffer(stream, ptr, len) \
|
||||
for (ptr = ustream_get_read_buf(stream, &len); \
|
||||
ptr != NULL && len > 0; \
|
||||
|
@ -71,6 +74,7 @@ struct rpc_file_exec_context {
|
|||
|
||||
static struct blob_buf buf;
|
||||
static char *canonpath;
|
||||
static char cmdstr[RPC_CMDLINE_MAX_SIZE];
|
||||
|
||||
enum {
|
||||
RPC_F_R_PATH,
|
||||
|
@ -801,7 +805,7 @@ rpc_file_exec_run(const char *cmd, const struct blob_attr *sid,
|
|||
struct blob_attr *cur;
|
||||
|
||||
uint8_t arglen;
|
||||
char *executable, **args, **tmp;
|
||||
char *executable, **args, **tmp, *p;
|
||||
|
||||
struct rpc_file_exec_context *c;
|
||||
|
||||
|
@ -816,7 +820,29 @@ rpc_file_exec_run(const char *cmd, const struct blob_attr *sid,
|
|||
return UBUS_STATUS_UNKNOWN_ERROR;
|
||||
|
||||
if (!rpc_file_access(sid, executable, "exec"))
|
||||
return UBUS_STATUS_PERMISSION_DENIED;
|
||||
{
|
||||
if (arg == NULL || strlen(executable) >= sizeof(cmdstr))
|
||||
return UBUS_STATUS_PERMISSION_DENIED;
|
||||
|
||||
arglen = 0;
|
||||
p = cmdstr + sprintf(cmdstr, "%s", executable);
|
||||
|
||||
blobmsg_for_each_attr(cur, arg, rem)
|
||||
{
|
||||
if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
if (arglen == 255 ||
|
||||
p + blobmsg_data_len(cur) >= cmdstr + sizeof(cmdstr))
|
||||
break;
|
||||
|
||||
p += sprintf(p, " %s", blobmsg_get_string(cur));
|
||||
arglen++;
|
||||
}
|
||||
|
||||
if (!rpc_file_access(sid, cmdstr, "exec"))
|
||||
return UBUS_STATUS_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
c = malloc(sizeof(*c));
|
||||
|
||||
|
|
Loading…
Reference in a new issue