[dev] [PATCH] rm: Use basenames to protect against . and ..

0 views
Skip to first unread message

Roberto E. Vargas Caballero

unread,
Apr 25, 2025, 6:40:35 AMApr 25
to d...@suckless.org, Roberto E. Vargas Caballero
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).
---
rm.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/rm.c b/rm.c
index 1f23c09..c1ae4fd 100644
--- a/rm.c
+++ b/rm.c
@@ -11,9 +11,29 @@ usage(void)
eprintf("usage: %s [-f] [-iRr] file ...\n", argv0);
}

+static int
+dotdot(char *path)
+{
+ char *s, *t;
+ size_t len;
+
+ len = strlen(path);
+ for (t = path + len; t > path && t[-1] == '/'; --t)
+ ;
+ for (s = t; s > path && s[-1] != '/'; --s)
+ ;
+
+ if (t - s == 1 && *s == '.')
+ return 1;
+ if (t - s == 2 && s[0] == '.' && s[1] == '.')
+ return 1;
+ return 0;
+}
+
int
main(int argc, char *argv[])
{
+ char *s;
struct recursor r = { .fn = rm, .maxdepth = 1, .follow = 'P' };

ARGBEGIN {
@@ -39,8 +59,12 @@ main(int argc, char *argv[])
}

for (; *argv; argc--, argv++) {
- if (strcmp(*argv, ".") && strcmp(*argv, ".."))
- recurse(AT_FDCWD, *argv, NULL, &r);
+ if (dotdot(*argv)) {
+ weprintf("\".\" and \"..\" may not be removed");
+ rm_status = 1;
+ continue;
+ }
+ recurse(AT_FDCWD, *argv, NULL, &r);
}

return rm_status || recurse_status;
--
2.46.1


Reply all
Reply to author
Forward
0 new messages