Bug 5458

Summary: usermod -u follows symlinks indefinitely
Product: [Retired] Red Hat Linux Reporter: jlewis
Component: shadow-utilsAssignee: Cristian Gafton <gafton>
Status: CLOSED RAWHIDE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 6.0Keywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-02-16 15:47:52 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description jlewis 1999-09-30 18:39:30 UTC
While synchronizing uids for my accounts on several of my
systems, I noticed an issue with usermod from
shadow-utils-980403 (included with both Red Hat 5.2 and 6.0)
on both Red Hat 5.2 and 6.0 systems.  usermod -u 500
jlewis will try to chown /home/jlewis such that files owned
by jlewis's old uid become owned by jlewis's new uid.  The
problem is that usermod follows symlinks.  I issued the
command, and thought it odd that it should be taking so
long, so I straced it to see what was going on.

I saw lots of lines like:

stat("/home/jlewis/root/home/jlewis/root/home/jlewis/root/home/jlewis/[rest
clipped...this went on to nearly fill my xterm]

/home/jlewis/root is a symlink to /.

There are 2 problems here.  First is that because chown_tree
is recursive and follows symlinks, it can end up eating
lots of time and disk i/o as it recursively loops stat'ing
files in an infinite loop (likely until/unless usermod
crashes) as well as traversing large portions of the
mounted filesystems that probably should not have been. This
could maybe be fixed by changing (in libmisc/chowndir.c):

                if (S_ISDIR(sb.st_mode)) {

                        /*
                         * Do the entire subdirectory.
                         */

to

         if (S_ISDIR(sb.st_mode) && !(S_ISLNK(sb.st_mode)) {

                        /*
                         * Do the entire subdirectory.
                         */

and the chown a few lines down would likely need to become
lchown, so chown can't follow the symlink.

The second problem (and I'm not saying it's likely to
happen...just a theoretical problem) is that the stat to see
who owns the file is done, and then a few lines of code
later, the chown is done with the assumption the file being
chown'd is still the file that was stat'd.

If the system can be slowed enough, and if the user can
cause programs to be executed at the right time, it may be
possible to steal files by playing with symlinks.

Since usermod -u is probably not used anywhere with any
frequency or regularity, this second issue probably isn't an
urgent one, but it doesn't look very secure.  The first
issue pretty much breaks usermod -u if appropriate symlinks
are encountered.

I've only tested this on Red Hat 5.2 and 6.0 for i386.  It's
likely to affect other versions and architectures.

Since this is a shadow-suite problem, I've also notified the
Shadow mailing list at shadow and
security-audit.ox.ac.uk.

Comment 1 Bernhard Rosenkraenzer 2000-02-16 15:47:59 UTC
Thanks, fixed.