Bugzilla – Bug 296
character ranges regression
Last modified: 2009-05-11 12:12:48 MDT
sudoers allows the usage of shell globs and character classes to limit possible arguments. This functionality regressed somewhere in between 1.6.8p12 (where it reportedly still worked) and 1.6.9p10. With a (admittedly bogus) rule like joe ALL=/bin/ls -l [A-z]* joe should be able to do "ls -l foo", but not "ls -l 3". However, sudo always claims that joe is not in the sudoers file and does not allow either command. The same is reportedly true for negative matches, such as "!/bin/ls foo[A-z]*". Interestingly, using a rule joe ALL=/bin/ls -l [a-Z]* seems to do the right thing. However, ASCIIbetically this is reverse, since upper case letters have lower ASCII values. POSIX shells such as dash do the asciibetically correct thing ([A-z] matches all letters, while [a-Z] does not match anything). bash seems to have a special case, both [A-z] and [a-Z] match all letters. In order to not break previously configured rules, sudo should revert to the previous behaviour in 1.6.8. Thank you! Martin
I can reproduce this on Linux (though not on BSD). It is probably related to the switch to using glob(3) instead of fnmatch(3) for matching.
Actually, the behavior I am seeing is different than you describe, though the issues may be related. In my case, the user is found in sudoers but is not allowed to run "ls foo". The problem appears to be related to locales. With LANG=en_US.UTF-8 the fnmatch() routine in glibc does not match "foo" against "[A-z]*", but if LANG is not defined (or if it is defined to "C") the matching happens as expected. The problem is that [A-z] is fundamentally non-portable when locales are taken into account. You should either use [[\:alpha\:]] or [A-Za-z]. I'll update the sudo documentation accordingly. In older sudo revisions, LANG was not preserved during command matching, which is why 1.6.8 doesn't show this behavior.
Created attachment 229 [details] Diff to restrict sudo to the C loale
I have committed the attached diff which restricts sudo to the C locale, like older versions did.
It seems that this didn't make it into 1.7?
It's not really a bug, the correct range to use is [A-Za-z]. In 1.7 there is now a sudoers_locale Defaults setting that can be used to specify the locale to use when evaluating sudoers globs.