aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-07-25 13:13:36 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-07-25 13:13:36 -0700
commit1f2256b82b911983c17eabc0dc1f50be461a78d0 (patch)
treeb0969a48e1baa387fb762ac2b09af39554ab13d6
parentc07c90c2283593f2dd97d0efeafacf4122bfda5e (diff)
downloadsafepath-1f2256b82b911983c17eabc0dc1f50be461a78d0.tar.gz
safepath-1f2256b82b911983c17eabc0dc1f50be461a78d0.tar.bz2
safepath-1f2256b82b911983c17eabc0dc1f50be461a78d0.zip
Be sure to root directory from absolute symlink.
* safepath.c (safepath_check): If we are checking a relative directory, and an absolute symlink shows up, then we have to check the root directory; we have not checked it before. It could have bad permissions. We ensure we do this at most once.
-rw-r--r--safepath.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/safepath.c b/safepath.c
index ce95740..8c8ad35 100644
--- a/safepath.c
+++ b/safepath.c
@@ -181,7 +181,7 @@ int safepath_check(const char *name)
const char *start = (*name == '/') ? "/" : ".";
size_t pos = (*name == '/') ? 1 : 0;
char *copy;
- int ret = SAFEPATH_OK, count = 0;
+ int ret = SAFEPATH_OK, count = 0, root_checked = (*name == '/');
/* empty name is invalid */
if (*name == 0) {
@@ -265,6 +265,17 @@ int safepath_check(const char *name)
* Either way it's string grafting.
*/
if (link[0] == '/') {
+ /* We have to check the root directory, if we have
+ * not done so before.
+ */
+ if (!root_checked) {
+ if (stat("/", &st) < 0) {
+ ret = safepath_err(errno);
+ goto free_out;
+ }
+ root_checked = 1;
+ }
+
/* If savechar is zero, we are working with the last component.
* If the last component is an absolute symlink, we just replace
* the path with the target, and iterate. Otherwise, we must