This service will be undergoing maintenance at 00:00 UTC, 2016-08-01. It is expected to last about 1 hours
Bug 472325 - (CVE-2008-5182) CVE-2008-5182 kernel: fix inotify watch removal/umount races
CVE-2008-5182 kernel: fix inotify watch removal/umount races
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
high Severity high
: ---
: ---
Assigned To: Red Hat Product Security
impact=important,source=lkml,reported...
: Security
Depends On: 472327 472328 472329
Blocks:
  Show dependency treegraph
 
Reported: 2008-11-19 22:29 EST by Eugene Teo (Security Response)
Modified: 2012-07-19 11:51 EDT (History)
13 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2010-12-21 12:53:01 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)
Proposed patch for real-time kernel (15.85 KB, patch)
2008-11-27 03:19 EST, Eugene Teo (Security Response)
no flags Details | Diff

  None (edit)
Description Eugene Teo (Security Response) 2008-11-19 22:29:21 EST
From: Al Viro <viro@ZenIV.linux.org.uk>

Inotify watch removals suck violently.

To kick the watch out we need (in this order) inode->inotify_mutex and ih->mutex.  That's fine if we have a hold on inode; however, for all other cases we need to make damn sure we don't race with umount.  We can *NOT* just grab a reference to a watch - inotify_unmount_inodes() will happily sail past it and we'll end with reference to inode potentially outliving its superblock.

Ideally we just want to grab an active reference to superblock if we can; that will make sure we won't go into inotify_umount_inodes() until we are done.  Cleanup is just deactivate_super().

However, that leaves a messy case - what if we *are* racing with umount() and active references to superblock can't be acquired anymore? We can bump ->s_count, grab ->s_umount, which will almost certainly wait until the superblock is shut down and the watch in question is pining for fjords.  That's fine, but there is a problem - we might have hit the window between ->s_active getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock is past the point of no return and is heading for shutdown) and the moment when deactivate_super() acquires ->s_umount.

We could just do drop_super() yield() and retry, but that's rather antisocial and this stuff is luser-triggerable.  OTOH, having grabbed ->s_umount and having found that we'd got there first (i.e.  that ->s_root is non-NULL) we know that we won't race with inotify_umount_inodes().

So we could grab a reference to watch and do the rest as above, just with drop_super() instead of deactivate_super(), right? Wrong.  We had to drop ih->mutex before we could grab ->s_umount.  So the watch could've been gone already.

That still can be dealt with - we need to save watch->wd, do idr_find() and compare its result with our pointer.  If they match, we either have the damn thing still alive or we'd lost not one but two races at once, the watch had been killed and a new one got created with the same ->wd at the same address.  That couldn't have happened in inotify_destroy(), but inotify_rm_wd() could run into that.  Still, "new one got created" is not a problem - we have every right to kill it or leave it alone, whatever's more convenient.

So we can use idr_find(...) == watch && watch->inode->i_sb == sb as "grab it and kill it" check.  If it's been our original watch, we are fine, if it's a newcomer - nevermind, just pretend that we'd won the race and kill the fscker anyway; we are safe since we know that its superblock won't be going away.

And yes, this is far beyond mere "not very pretty"; so's the entire concept of inotify to start with.
Comment 5 Eugene Teo (Security Response) 2008-11-27 03:19:12 EST
Created attachment 324842 [details]
Proposed patch for real-time kernel

Luis, kindly review. Only boot tested. Thanks.
Comment 6 Fedora Update System 2008-12-17 11:21:13 EST
kernel-2.6.27.9-159.fc10 has been submitted as an update for Fedora 10.
http://admin.fedoraproject.org/updates/kernel-2.6.27.9-159.fc10
Comment 7 Fedora Update System 2008-12-17 11:22:12 EST
kernel-2.6.27.9-73.fc9 has been submitted as an update for Fedora 9.
http://admin.fedoraproject.org/updates/kernel-2.6.27.9-73.fc9
Comment 8 Fedora Update System 2008-12-24 13:45:23 EST
kernel-2.6.27.9-159.fc10 has been pushed to the Fedora 10 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 9 Fedora Update System 2008-12-24 13:47:39 EST
kernel-2.6.27.9-73.fc9 has been pushed to the Fedora 9 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 11 Fedora Update System 2009-01-07 04:17:45 EST
kernel-2.6.26.8-57.fc8 has been pushed to the Fedora 8 stable repository.  If problems still persist, please make note of it in this bug report.
Comment 14 Vincent Danen 2010-12-21 12:53:01 EST
This was addressed via:

Red Hat Enterprise Linux (v. 5.2.z server) (RHSA-2009:0021)
MRG Realtime for RHEL 5 Server (RHSA-2009:0053)
Red Hat Enterprise Linux version 5 (RHSA-2009:0225)

Note You need to log in before you can comment on or make changes to this bug.