Bug 296

Summary: character ranges regression
Product: Sudo Reporter: Martin Pitt <martin.pitt>
Component: SudoAssignee: Todd C. Miller <Todd.Miller>
Status: RESOLVED FIXED    
Severity: high    
Priority: low    
Version: 1.6.9   
Hardware: PC   
OS: Linux   
URL: https://bugs.launchpad.net/ubuntu/+source/sudo/+bug/228046
Attachments: Diff to restrict sudo to the C loale

Description Martin Pitt 2008-07-31 04:05:14 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
Comment 1 Todd C. Miller 2008-08-20 10:25:59 MDT
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.
Comment 2 Todd C. Miller 2008-08-22 12:59:17 MDT
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.
Comment 3 Todd C. Miller 2008-08-27 15:42:50 MDT
Created attachment 229 [details]
Diff to restrict sudo to the C loale
Comment 4 Todd C. Miller 2008-08-27 15:44:30 MDT
I have committed the attached diff which restricts sudo to the C
locale, like older versions did.
Comment 5 Martin Pitt 2009-05-11 12:04:12 MDT
It seems that this didn't make it into 1.7?
Comment 6 Todd C. Miller 2009-05-11 12:12:48 MDT
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.