From ae1812c2c755ffa2b62ac5e7e67e04be6798d16c Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 25 Jul 2022 13:33:14 -0700 Subject: Check ownership of symlinks. * safepath.c (safepath_check): Do not continue if a symlink is not owned by root or the caller's effective UID. --- safepath.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'safepath.c') diff --git a/safepath.c b/safepath.c index 8c8ad35..587b07f 100644 --- a/safepath.c +++ b/safepath.c @@ -248,6 +248,18 @@ int safepath_check(const char *name) goto free_out; } + /* We check the symlink ownership and declare a symlink + * not owned by us or root to be unsafe. This is particularly + * important in the case when the previous component is a + * sticky directory which we declared safe, similar to /tmp. + * Multiple users can create symlinks in /tmp or a /tmp-like + * directory, which could be used to subvert this function. + */ + if (st.st_uid != 0 && st.st_uid != geteuid()) { + ret = SAFEPATH_UNSAFE; + goto free_out; + } + if ((len = readlink(copy, link, sizeof link)) < 0) { ret = safepath_err(errno); goto free_out; -- cgit v1.2.3