Date: Sat, 12 Jul 2014 12:41:56 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Locale path and security [Was: Status towards next release (1.1.4)] On Sat, Jul 12, 2014 at 11:03:33AM -0400, Rich Felker wrote: > On Sat, Jul 12, 2014 at 01:10:35AM -0400, Rich Felker wrote: > > - The Big Bikeshed: where to find locale files? These will be somewhat > > musl-specific (to the extent that no other implementation uses the > > design I have in mind, though it would be easy for others to use > > it), so there's no existing practice to simply adopt. The files are > > not machine-specific (we'll support either endianness .mo file) so > > /usr/share (or other prefix variants) is the natural base location. > > One idea for this: just don't accept anything except the built-in > locales (C, C.UTF-8, POSIX) and absolute pathnames. For suid programs, > the latter could be rejected completely (the safest and probably what > we should do) or restricted to a set of reasonable paths where each > path component is checked for permissions. > > Another idea is pulling the search path from /etc/musl-locale.conf or > similar. Obviously this is not the most friendly to Rune's usage case, > but it would just be one more hard-coded path to override in the > custom build, or if absolute pathnames were also accepted for locales > the support for /etc/musl-locale.conf could just be stripped out. >From a usability standpoint, I think it's desirable to have some sort of search path, even if absolute pathnames are also supported. Consider mixed environments where the user has something like LANG=fr_FR.UTF-8 for glibc programs; assuming the corresponding locale is also installed for musl, the reasonable user expectation is that musl-linked programs also use French messages, time formatting, collation, etc. glibc honors the non-POSIX environment variable LOCPATH to control its search for locales. While this is something of a consideration for applications trying to avoid unwanted environment-influenced behavior for security purposes or otherwise, it's not a big conformance problem since setlocale already depends on the environment anyway (and thus can't be called safely in parallel with modifications to the environment, per POSIX). We could honor the same variable and just append "/musl/" to the value (this would be nice from the standpoint of not introducing another variable apps have to be aware of when they want to filter it) but that's somewhat ugly since the glibc one is intended to point to a "lib" (arch-specific) dir whereas musl's is portable data. Using a separate variable might be preferable if we even want to support an environment variable as a way to configure this at runtime -- and I think doing so may be valuable since users may want locales that are not installed by the system administrator. In light of glibc CVE-2014-0475, which I'm not sure is even really a proper "vulnerability" but rather just a complication of the standard locale semantics that makes it hard to write secure programs without filtering out locale vars from untrusted sources, a major goal I'd like to pursue is minimizing the potential security impact of an untrusted/malicious locale file. Obviously suid/AT_SECURE programs should not even honor locale files except possibly from a hard-coded trusted source, but ideally even programs without formally elevated privilegs -- think gitolite type setups with ssh authorized_keys -- would not yield code execution or information leak when fed a malicious locale file. Here are the security aspects I have in mind: - For libc itself (obviously we can't control application use of gettext), only translate literal strings, never printf/scanf format strings. For dlerror this requires some refactoring of the message strings but otherwise I think this property is easy to satisfy. The purpose of this property is to prevent format string injection via locales and limit the scope of bad messages to literal copying of those messages into the program output. - Avoid loading as a locale any file which was not intended to be a locale. This entails checking the magic number, sanity-checking the headers, and also doing a single gettext-type string lookup for a key string associated with our locale file format (a specialization of general mo files). If the key is not found, the file can be rejected; it's probably a mo file but not one that satisfies the needs of libc for the requested locale category. The purpose of this check is to prevent disclosure of contents of files that were not intended to be locales. - During gettext lookup (binary search), validate all offsets as lying within the address range of the mapping. The purpose of this check is to preclude information disclosure due to reading strings from locations outside the mapping. Obviously as long as mmap is used, there is a possibility of DoS via file truncation and SIGBUS. I don't think it's worth trying to work around this since the scope is limited to crashing your own programs (or allowing someone else to crash them if you use a locale file writable by someone else). As previoysly discussed for zoneinfo, one option would be to malloc, read, and validate (rather than mmap), but IMO this is cost-prohibitive. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.