diff options
Diffstat (limited to 'safepath.c')
-rw-r--r-- | safepath.c | 47 |
1 files changed, 36 insertions, 11 deletions
@@ -35,9 +35,19 @@ #include <fcntl.h> #include <pwd.h> #include <grp.h> +#include <regex.h> #include "safepath.h" /* + * Regular expressions used by abs_path_check. + */ + +static const char *bad_proc = { + "^/proc/([0-9]+|self)/(cwd|root|map_files|fd/[0-9]+|task/[0-9]+/(cwd|root|fd/[0-9]+))($|/)" +}; +static regex_t bad_proc_rx; + +/* * Returns non-zero if st informs about an object that is not writable by * anyone other than the real user ID of the process, or else the superuser. */ @@ -200,17 +210,9 @@ static int abs_path_check(const char *abspath) char *sabspath = simplify_path(abspath); if (geteuid() == 0) { - const char *proc = "/proc/"; - size_t proclen = strlen(proc); - - if (strncmp(sabspath, proc, proclen) == 0) { - const char *pid = sabspath + proclen; - size_t pidlen = strspn(pid, "0123456789"); - - if (pid[pidlen] == '/' || pid[pidlen] == 0) { - free(sabspath); - return 0; - } + if (regexec(&bad_proc_rx, sabspath, 0, NULL, 0) == 0) { + free(sabspath); + return 0; } } @@ -268,6 +270,29 @@ static void set_errno(int spres) } } +/* + * Must be called exactly once before safepath_check is used. + * Returns 1 on success, 0 on failure. + */ +int safepath_init(void) +{ + if (regcomp(&bad_proc_rx, bad_proc, REG_EXTENDED | REG_NOSUB) != 0) + return 0; + return 1; +} + +/* + * If safepath_init was was successfully called, this may be called once to + * release the resources allocated by safepath_init. + * The library may not be used after that. + * A new call to safepath_init is permitted after safepath_cleanup. + */ +void safepath_cleanup(void) +{ + regfree(&bad_proc_rx); + memset(&bad_proc_rx, 0, sizeof bad_proc_rx); +} + int safepath_check(const char *name) { struct stat st; |