]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/canonicalize: add canonicalize_path_restricted() to canonicalize without suid...
authorKarel Zak <kzak@redhat.com>
Mon, 26 Nov 2012 15:24:28 +0000 (16:24 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 26 Nov 2012 15:24:28 +0000 (16:24 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/canonicalize.h
lib/canonicalize.c

index f26df18c2b116599528e1c23b811b015c4f0a117..c1497380299e56cf91d4cbbc1f97e77431d86a66 100644 (file)
@@ -4,6 +4,7 @@
 #include "c.h" /* for PATH_MAX */
 
 extern char *canonicalize_path(const char *path);
+extern char *canonicalize_path_restricted(const char *path);
 extern char *canonicalize_dm_name(const char *ptname);
 
 #endif /* CANONICALIZE_H */
index ab32c10431bd88dde3b9b6fff3c88224c28f4811..1e8aff4f2b3fa9f631c54551a3484418dcf6dbd8 100644 (file)
@@ -188,6 +188,48 @@ canonicalize_path(const char *path)
        return strdup(canonical);
 }
 
+char *
+canonicalize_path_restricted(const char *path)
+{
+       char canonical[PATH_MAX+2];
+       char *p = NULL;
+       int errsv;
+       uid_t euid;
+       gid_t egid;
+
+       if (path == NULL)
+               return NULL;
+
+       euid = geteuid();
+       egid = getegid();
+
+       /* drop permissions */
+       if (setegid(getgid()) < 0 || seteuid(getuid()) < 0)
+               return NULL;
+
+       errsv = errno = 0;
+
+       if (myrealpath(path, canonical, PATH_MAX+1)) {
+               p = strrchr(canonical, '/');
+               if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4)))
+                       p = canonicalize_dm_name(p+1);
+               else
+                       p = NULL;
+               if (!p)
+                       p = strdup(canonical);
+       } else
+               errsv = errno;
+
+       /* restore */
+       if (setegid(egid) < 0 || seteuid(euid) < 0) {
+               free(p);
+               return NULL;
+       }
+
+       errno = errsv;
+       return p;
+}
+
 
 #ifdef TEST_PROGRAM_CANONICALIZE
 int main(int argc, char **argv)