parent
8400e7d302
commit
63db2d99e7
@ -93,13 +93,13 @@ static int get_dirfd(char *path, bool symlinks)
|
|||||||
if (dirfd == -1)
|
if (dirfd == -1)
|
||||||
eerrorx("%s: unable to open the root directory: %s",
|
eerrorx("%s: unable to open the root directory: %s",
|
||||||
applet, strerror(errno));
|
applet, strerror(errno));
|
||||||
path_dupe = xstrdup(path);
|
ch = path;
|
||||||
ch = path_dupe;
|
|
||||||
while (*ch) {
|
while (*ch) {
|
||||||
if (*ch == '/')
|
if (*ch == '/')
|
||||||
components++;
|
components++;
|
||||||
ch++;
|
ch++;
|
||||||
}
|
}
|
||||||
|
path_dupe = xstrdup(path);
|
||||||
item = strtok(path_dupe, "/");
|
item = strtok(path_dupe, "/");
|
||||||
#ifdef O_PATH
|
#ifdef O_PATH
|
||||||
flags |= O_PATH;
|
flags |= O_PATH;
|
||||||
@ -136,18 +136,44 @@ static int get_dirfd(char *path, bool symlinks)
|
|||||||
dirfd = new_dirfd;
|
dirfd = new_dirfd;
|
||||||
free(linkpath);
|
free(linkpath);
|
||||||
linkpath = NULL;
|
linkpath = NULL;
|
||||||
|
}
|
||||||
item = strtok(NULL, "/");
|
item = strtok(NULL, "/");
|
||||||
components--;
|
components--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
free(path_dupe);
|
free(path_dupe);
|
||||||
if (linkpath) {
|
|
||||||
free(linkpath);
|
free(linkpath);
|
||||||
linkpath = NULL;
|
|
||||||
}
|
|
||||||
return dirfd;
|
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,
|
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)
|
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 symlinks = false;
|
||||||
bool writable = false;
|
bool writable = false;
|
||||||
bool selinux_on = false;
|
bool selinux_on = false;
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
applet = basename_c(argv[0]);
|
applet = basename_c(argv[0]);
|
||||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||||
@ -407,12 +434,14 @@ int main(int argc, char **argv)
|
|||||||
selinux_on = true;
|
selinux_on = true;
|
||||||
|
|
||||||
while (optind < argc) {
|
while (optind < argc) {
|
||||||
|
path = clean_path(argv[optind]);
|
||||||
if (writable)
|
if (writable)
|
||||||
exit(!is_writable(argv[optind]));
|
exit(!is_writable(path));
|
||||||
if (do_check(argv[optind], uid, gid, mode, type, trunc, chowner,
|
if (do_check(path, uid, gid, mode, type, trunc, chowner,
|
||||||
symlinks, selinux_on))
|
symlinks, selinux_on))
|
||||||
retval = EXIT_FAILURE;
|
retval = EXIT_FAILURE;
|
||||||
optind++;
|
optind++;
|
||||||
|
free(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selinux_on)
|
if (selinux_on)
|
||||||
|
Loading…
Reference in New Issue
Block a user