diff options
author | Rich Felker <dalias@aerifal.cx> | 2014-07-31 12:05:25 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2014-07-31 12:05:25 -0400 |
commit | 5059deb1a5bf33632390461f3137ebd3dc902e6e (patch) | |
tree | f75605ab06626dbff3722ee2a36f75e1a0f4c56f /src | |
parent | ecc082c61b6da9a8b2ae0c07aa3331673834d94a (diff) | |
download | musl-5059deb1a5bf33632390461f3137ebd3dc902e6e.tar.gz musl-5059deb1a5bf33632390461f3137ebd3dc902e6e.tar.xz musl-5059deb1a5bf33632390461f3137ebd3dc902e6e.zip |
harden locale name handling and prevent slashes in LC_MESSAGES
the code which loads locale files was already rejecting locale names containing slashes. however, LC_MESSAGES records a locale name even if libc does not have a matching locale file, so that gettext or application code can use the recorded locale name for message translations to languages that libc does not support. this recorded name was not being checked for slashes, meaning that such code could potentially be tricked into directory traversal. in addition, since the value of a locale category is sometimes used as a pathname component by callers, the improved code rejects any value beginning with a dot. this prevents traversal to the parent directory via "..", use of the top-level locale directory via ".", and also avoids "hidden" directories as a side effect. finally, overly long locale names are now rejected (treated as an unrecognized name and thus as an alias for C.UTF-8) rather than being truncated.
Diffstat (limited to 'src')
-rw-r--r-- | src/locale/__setlocalecat.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/locale/__setlocalecat.c b/src/locale/__setlocalecat.c index 44385e02..1c894d9c 100644 --- a/src/locale/__setlocalecat.c +++ b/src/locale/__setlocalecat.c @@ -28,8 +28,6 @@ static struct __locale_map *findlocale(const char *name, size_t n) for (p=loc_head; p; p=p->next) if (!strcmp(name, p->name)) return p; - if (strchr(name, '/')) return 0; - if (!libc.secure) path = getenv("MUSL_LOCPATH"); /* FIXME: add a default path? */ if (!path) return 0; @@ -81,7 +79,9 @@ int __setlocalecat(locale_t loc, int cat, const char *val) (val = "C.UTF-8"); } - size_t n = strnlen(val, LOCALE_NAME_MAX); + size_t n; + for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++); + if (val[0]=='.' || val[n]) val = "C.UTF-8"; int builtin = (val[0]=='C' && !val[1]) || !strcmp(val, "C.UTF-8") || !strcmp(val, "POSIX"); |