mirror of
git://git.suckless.org/sbase
synced 2026-01-26 05:37:54 +00:00
rm: Use basenames to protect against . and ..
POSIX mandates that the protection should care about the basename, and we cannot use basename because it can modify the input string and it would make harder later operations. Also, it would put a limit in the length of the name of the paths and POSIX forbids limitations about that regard in rm(1).
This commit is contained in:
parent
d4dfd42d35
commit
b27871013b
44
rm.c
44
rm.c
@ -11,9 +11,44 @@ usage(void)
|
||||
eprintf("usage: %s [-f] [-iRr] file ...\n", argv0);
|
||||
}
|
||||
|
||||
static int
|
||||
forbidden(char *path, struct stat *root)
|
||||
{
|
||||
char *s, *t;
|
||||
size_t n;
|
||||
struct stat st;
|
||||
static int w1, w2;
|
||||
|
||||
n = strlen(path);
|
||||
for (t = path + n; t > path && t[-1] == '/'; --t)
|
||||
;
|
||||
for (s = t; s > path && s[-1] != '/'; --s)
|
||||
;
|
||||
n = t - s;
|
||||
if (n == 1 && *s == '.' || n == 2 && s[0] == '.' && s[1] == '.') {
|
||||
if (!w1)
|
||||
weprintf("\".\" and \"..\" may not be removed\n");
|
||||
w1 = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (stat(path, &st) < 0)
|
||||
eprintf("stat argument '%s':", path);
|
||||
if (st.st_dev == root->st_dev && st.st_ino == root->st_ino) {
|
||||
if (!w2)
|
||||
weprintf("\"/\" may not be removed\n");
|
||||
w2 = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *s;
|
||||
struct stat st;
|
||||
struct recursor r = { .fn = rm, .maxdepth = 1, .follow = 'P' };
|
||||
|
||||
ARGBEGIN {
|
||||
@ -38,9 +73,14 @@ main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat("/", &st) < 0)
|
||||
eprintf("stat root:");
|
||||
for (; *argv; argc--, argv++) {
|
||||
if (strcmp(*argv, ".") && strcmp(*argv, ".."))
|
||||
recurse(AT_FDCWD, *argv, NULL, &r);
|
||||
if (forbidden(*argv, &st)) {
|
||||
rm_status = 1;
|
||||
continue;
|
||||
}
|
||||
recurse(AT_FDCWD, *argv, NULL, &r);
|
||||
}
|
||||
|
||||
return rm_status || recurse_status;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user