• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revisionf23e4db5d0462de3a3e74686d7e1a4b708bef002 (tree)
Zeit2008-10-20 04:57:43
AutorEugene Teo <eugeneteo@kern...>
CommiterWilly Tarreau

Log Message

CVE-2008-3275 Linux kernel local filesystem DoS

This is a backport for CVE-2008-3275.

"Lookup can install a child dentry for a deleted directory. This keeps
the directory dentry alive, and the inode pinned in the cache and on
disk, even after all external references have gone away.

This isn't a big problem normally, since memory pressure or umount
will clear out the directory dentry and its children, releasing the
inode. But for UBIFS this causes problems because its orphan area can
overflow.

Fix this by returning ENOENT for all lookups on a S_DEAD directory
before creating a child dentry."

Signed-off-by: Eugene Teo <eugeneteo@kernel.sg>
[ WT: problem and fix confirmed on ramfs using method described

Signed-off-by: Willy Tarreau <w@1wt.eu>

Ändern Zusammenfassung

Diff

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -296,7 +296,14 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
296296 */
297297 result = d_lookup(parent, name);
298298 if (!result) {
299- struct dentry * dentry = d_alloc(parent, name);
299+ struct dentry *dentry;
300+
301+ /* Don't create child dentry for a dead directory. */
302+ result = ERR_PTR(-ENOENT);
303+ if (IS_DEADDIR(dir))
304+ goto out_unlock;
305+
306+ dentry = d_alloc(parent, name);
300307 result = ERR_PTR(-ENOMEM);
301308 if (dentry) {
302309 lock_kernel();
@@ -307,6 +314,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, i
307314 else
308315 result = dentry;
309316 }
317+ out_unlock:
310318 up(&dir->i_sem);
311319 return result;
312320 }
@@ -798,7 +806,14 @@ struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
798806
799807 dentry = cached_lookup(base, name, 0);
800808 if (!dentry) {
801- struct dentry *new = d_alloc(base, name);
809+ struct dentry *new;
810+
811+ /* Don't create child dentry for a dead directory. */
812+ dentry = ERR_PTR(-ENOENT);
813+ if (IS_DEADDIR(inode))
814+ goto out;
815+
816+ new = d_alloc(base, name);
802817 dentry = ERR_PTR(-ENOMEM);
803818 if (!new)
804819 goto out;
Show on old repository browser