diff options
author | Theo Buehler <tb@cvs.openbsd.org> | 2024-04-14 08:34:01 +0000 |
---|---|---|
committer | Theo Buehler <tb@cvs.openbsd.org> | 2024-04-14 08:34:01 +0000 |
commit | 23798ca9c70b0cbe85b6221fe9944f04c970434c (patch) | |
tree | 21385d16301a4d197462733db140a96172337957 /usr.bin/less | |
parent | fa33e8cf95b060553529ddddf7093ee42294f9cc (diff) |
less: escape newlines in file names
Newlines in a filename can lead to arbitrary code execution
https://marc.info/?l=oss-security&m=171292433330233&w=2
via LESSOPEN. The diff is a straightforward adaptation of
https://github.com/gwsw/less/commit/007521ac3c95bc76
The better fix is deleting the misfeatures that are LESSOPEN
and LESSCLOSE which will happen in a separate commit.
diff looks good to guenther
Diffstat (limited to 'usr.bin/less')
-rw-r--r-- | usr.bin/less/filename.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/usr.bin/less/filename.c b/usr.bin/less/filename.c index 8b2dd9a02f4..dfe998fe9e3 100644 --- a/usr.bin/less/filename.c +++ b/usr.bin/less/filename.c @@ -107,6 +107,15 @@ metachar(char c) } /* + * Must use quotes rather than escape characters for this meta character. + */ +static int +must_quote(char c) +{ + return (c == '\n'); +} + +/* * Insert a backslash before each metacharacter in a string. */ char * @@ -136,6 +145,9 @@ shell_quote(const char *s) * doesn't support escape chars. Use quotes. */ use_quotes = 1; + } else if (must_quote(*p)) { + /* Opening quote + character + closing quote. */ + len += 3; } else { /* * Allow space for the escape char. @@ -155,14 +167,19 @@ shell_quote(const char *s) } else { newstr = r = ecalloc(len, sizeof (char)); while (*s != '\0') { - if (metachar(*s)) { - /* - * Add the escape char. - */ + if (!metachar(*s)) { + *r++ = *s++; + } else if (must_quote(*s)) { + /* Surround the character with quotes. */ + *r++ = openquote; + *r++ = *s++; + *r++ = closequote; + } else { + /* Escape the character. */ (void) strlcpy(r, esc, newstr + len - p); r += esclen; + *r++ = *s++; } - *r++ = *s++; } *r = '\0'; } |