diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-11-07 13:10:44 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-11-07 13:19:08 -0500 |
commit | 163baf1c9af13be0ce705b133e41e0c3d6427398 (patch) | |
tree | 64827684a24c345f436d1135b5b4fbe92933bd47 | |
parent | ce90dc9bc00c46b27b437467bb2f053ab2307fbc (diff) | |
download | bfs-163baf1c9af13be0ce705b133e41e0c3d6427398.tar.xz |
parse: Reject -{exec,ok}dir if $PATH contains a relative path
This matches the behaviour of GNU find.
-rw-r--r-- | src/parse.c | 26 | ||||
-rw-r--r-- | tests/gnu/execdir_path_dot.sh | 1 | ||||
-rw-r--r-- | tests/gnu/execdir_path_empty.sh | 1 | ||||
-rw-r--r-- | tests/gnu/execdir_path_relative.sh | 1 | ||||
-rw-r--r-- | tests/gnu/okdir_path_dot.sh | 1 | ||||
-rw-r--r-- | tests/gnu/okdir_path_empty.sh | 1 | ||||
-rw-r--r-- | tests/gnu/okdir_path_relative.sh | 1 |
7 files changed, 32 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c index 09cfdd3..d21ab40 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1263,6 +1263,28 @@ static struct bfs_expr *parse_exec(struct parser_state *state, int flags, int ar expr->ephemeral_fds = 2; if (execbuf->flags & BFS_EXEC_CHDIR) { + // Check for relative paths in $PATH + const char *path = getenv("PATH"); + while (path) { + if (*path != '/') { + size_t len = strcspn(path, ":"); + char *comp = strndup(path, len); + if (comp) { + parse_expr_error(state, expr, + "This action would be unsafe, since ${bld}$$PATH${rs} contains the relative path ${bld}%pq${rs}\n", comp); + free(comp); + } else { + parse_perror(state, "strndup()"); + } + goto fail; + } + + path = strchr(path, ':'); + if (path) { + ++path; + } + } + // To dup() the parent directory if (execbuf->flags & BFS_EXEC_MULTI) { ++expr->persistent_fds; @@ -1276,6 +1298,10 @@ static struct bfs_expr *parse_exec(struct parser_state *state, int flags, int ar } return expr; + +fail: + bfs_expr_free(expr); + return NULL; } /** diff --git a/tests/gnu/execdir_path_dot.sh b/tests/gnu/execdir_path_dot.sh new file mode 100644 index 0000000..632dbb4 --- /dev/null +++ b/tests/gnu/execdir_path_dot.sh @@ -0,0 +1 @@ +! PATH=".:$PATH" invoke_bfs basic -execdir echo {} + diff --git a/tests/gnu/execdir_path_empty.sh b/tests/gnu/execdir_path_empty.sh new file mode 100644 index 0000000..eda6b1c --- /dev/null +++ b/tests/gnu/execdir_path_empty.sh @@ -0,0 +1 @@ +! PATH=":$PATH" invoke_bfs basic -execdir echo {} + diff --git a/tests/gnu/execdir_path_relative.sh b/tests/gnu/execdir_path_relative.sh new file mode 100644 index 0000000..69899ad --- /dev/null +++ b/tests/gnu/execdir_path_relative.sh @@ -0,0 +1 @@ +! PATH="foo:$PATH" invoke_bfs basic -execdir echo {} + diff --git a/tests/gnu/okdir_path_dot.sh b/tests/gnu/okdir_path_dot.sh new file mode 100644 index 0000000..5b40e27 --- /dev/null +++ b/tests/gnu/okdir_path_dot.sh @@ -0,0 +1 @@ +! PATH=".:$PATH" invoke_bfs basic -okdir echo {} \; diff --git a/tests/gnu/okdir_path_empty.sh b/tests/gnu/okdir_path_empty.sh new file mode 100644 index 0000000..2669ee8 --- /dev/null +++ b/tests/gnu/okdir_path_empty.sh @@ -0,0 +1 @@ +! PATH=":$PATH" invoke_bfs basic -okdir echo {} \; diff --git a/tests/gnu/okdir_path_relative.sh b/tests/gnu/okdir_path_relative.sh new file mode 100644 index 0000000..05100a1 --- /dev/null +++ b/tests/gnu/okdir_path_relative.sh @@ -0,0 +1 @@ +! PATH="foo:$PATH" invoke_bfs basic -okdir echo {} \; |