From f95bbb6f6e517f43fd0f3d7129f238fe817beca4 Mon Sep 17 00:00:00 2001 From: "Kelvin M. Klann" Date: Mon, 20 Mar 2023 20:31:55 -0300 Subject: util.c: add and use ascii-only char functions The "invalid_name" function claims to "allow strict ASCII letters and numbers". However, it uses isalnum(3) and isdigit(3), which may take the current locale into account and thus return 1 for non-ASCII characters. So add the following functions: * ascii_isalnum * ascii_isalpha * ascii_isdigit * ascii_islower * ascii_isupper * ascii_isxdigit And use the applicable ones in "invalid_name" so that it actually uses strictly ASCII in its comparisons. Added on commit b4ffaa207 ("merges; more on cleaning up esc chars", 2023-02-14). Relates to #5578. Kind of relates to #5708. --- src/firejail/firejail.h | 6 ++++++ src/firejail/util.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 76f1a12a0..2cde75463 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -580,6 +580,12 @@ int has_handler(pid_t pid, int signal); void enter_network_namespace(pid_t pid); int read_pid(const char *name, pid_t *pid); pid_t require_pid(const char *name); +int ascii_isalnum(unsigned char c); +int ascii_isalpha(unsigned char c); +int ascii_isdigit(unsigned char c); +int ascii_islower(unsigned char c); +int ascii_isupper(unsigned char c); +int ascii_isxdigit(unsigned char c); int invalid_name(const char *name); void check_homedir(const char *dir); diff --git a/src/firejail/util.c b/src/firejail/util.c index cda99e432..b2a0c85f1 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -1448,15 +1448,42 @@ static int has_link(const char *dir) { return 0; } +int ascii_isalnum(unsigned char c) { + return (ascii_isalpha(c) || ascii_isdigit(c)); +} + +int ascii_isalpha(unsigned char c) { + return (ascii_islower(c) || ascii_isupper(c)); +} + +int ascii_isdigit(unsigned char c) { + return (c >= '0' && c <= '9'); +} + +int ascii_islower(unsigned char c) { + return (c >= 'a' && c <= 'z'); +} + +int ascii_isupper(unsigned char c) { + return (c >= 'A' && c <= 'Z'); +} + +int ascii_isxdigit(unsigned char c) { + int ret = (ascii_isdigit(c) || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F')); + return ret; +} + // allow strict ASCII letters and numbers; names with only numbers are rejected; spaces are rejected int invalid_name(const char *name) { const char *c = name; int only_numbers = 1; while (*c) { - if (!isalnum(*c)) + if (!ascii_isalnum(*c)) return 1; - if (!isdigit(*c)) + if (!ascii_isdigit(*c)) only_numbers = 0; ++c; } -- cgit v1.2.3-70-g09d2