checkpath: remove extra slashes from paths

This fixes #418.
This commit is contained in:
William Hubbs 2021-04-13 17:13:20 -05:00
parent 8400e7d302
commit 63db2d99e7

View File

@ -93,13 +93,13 @@ static int get_dirfd(char *path, bool symlinks)
if (dirfd == -1)
eerrorx("%s: unable to open the root directory: %s",
applet, strerror(errno));
path_dupe = xstrdup(path);
ch = path_dupe;
ch = path;
while (*ch) {
if (*ch == '/')
components++;
ch++;
}
path_dupe = xstrdup(path);
item = strtok(path_dupe, "/");
#ifdef O_PATH
flags |= O_PATH;
@ -136,18 +136,44 @@ static int get_dirfd(char *path, bool symlinks)
dirfd = new_dirfd;
free(linkpath);
linkpath = NULL;
item = strtok(NULL, "/");
components--;
}
item = strtok(NULL, "/");
components--;
}
free(path_dupe);
if (linkpath) {
free(linkpath);
linkpath = NULL;
}
free(linkpath);
return dirfd;
}
static char *clean_path(char *path)
{
char *ch;
char *ch2;
char *str;
str = xmalloc(strlen(path));
ch = path;
ch2 = str;
while (true) {
*ch2 = *ch;
ch++;
ch2++;
if (!*(ch-1))
break;
while (*(ch - 1) == '/' && *ch == '/')
ch++;
}
/* get rid of trailing / characters */
while ((ch = strrchr(str, '/'))) {
if (ch == str)
break;
if (!*(ch+1))
*ch = 0;
else
break;
}
return str;
}
static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode,
inode_t type, bool trunc, bool chowner, bool symlinks, bool selinux_on)
{
@ -345,6 +371,7 @@ int main(int argc, char **argv)
bool symlinks = false;
bool writable = false;
bool selinux_on = false;
char *path = NULL;
applet = basename_c(argv[0]);
while ((opt = getopt_long(argc, argv, getoptstring,
@ -407,12 +434,14 @@ int main(int argc, char **argv)
selinux_on = true;
while (optind < argc) {
path = clean_path(argv[optind]);
if (writable)
exit(!is_writable(argv[optind]));
if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner,
exit(!is_writable(path));
if (do_check(path, uid, gid, mode, type, trunc, chowner,
symlinks, selinux_on))
retval = EXIT_FAILURE;
optind++;
free(path);
}
if (selinux_on)