[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dazuko-devel] patch 9 for dazukofs release 3.0.0
From: |
Lino Sanfilippo |
Subject: |
[Dazuko-devel] patch 9 for dazukofs release 3.0.0 |
Date: |
Wed, 29 Apr 2009 17:25:39 +0200 |
User-agent: |
IceDove 1.5.0.14eol (X11/20090105) |
Bug description:
Dazukofs uses the lookup_one_len() kernel api to get an entry from the
underlaying filesystem
that is not in dentry cache yet.
lookup_one_len() in turn calls the revalidate() operation of the lower
dentry (if it is defined)
with a NULL pointer passed as nameidata.
This is dangerous, since the underlaying dentry might not be prepared to
be given
a NULL nameidata. If it is accessed while revalidate() is processed, it
results in a kernel oops .
(The comment in the kernel source file namei.c where lookup_one_len() is
defined, also points
out that this function is for internal use only, and should only be
used, if the filesystem is
prepared to handle NULL nameidata pointers in revalidate(). But we can
never be sure that
the _underlaying_ filesystem is prepared to handle this)
Ironically even dazukofs itself is not prepared to handle a NULL
nameidata passed to
the revalidate() function. So there is an easy way to trigger the bug
that is described here:
1. mount dazukofs over an ext3 directory that contains the file "testfile".
Note that ext3 does not specify a revalidate() operation for its dentries.
# mount -t dazukofs /testdir /testdir
2. force dazukofs to load the underlaying dentry of "testfile". Since
the lower
dentry does not use revalidate() nothing bad happens.
# file /testdir/testfile
3. mount dazukofs a second time over the same mountpoint
# mount -t dazukofs /testdir /testdir
4. access testfile again: this will call revalidate() of the underlaying
dazukofs()
which returns immediately since the underlaying filesystem (ext3) has no
revalidate() defined
5. mount dazukofs a third time over the same mountpoint
#mount -t dazukofs /testdir /testdir
6. access testfile again: this time the underlaying dazukofs sees that
there is
a revalidate() defined (by the dazukofs below it) and tries to
restore the nameidata.
But this is NULL, so an oops occurs.
As stated above this bug will not only trigger if dazukofs is mounted
multiple times
over the same mountpoint. Indeed it will alway happen if dazukofs is
mounted over
a filesystem that
1. specifies the revalidate() operation for its dentries
2. accesses the nameidata object while processing revalidate()
3. is not prepared that nameidata may be NULL
The bug fix is to use the vfs_path_lookup() kernel api instead of
lookup_one_len(),
since here we can always provide a nameidata that is not NULL.
Geschäftsführender Gesellschafter: Tjark Auerbach
Sitz der Gesellschaft: Tettnang
Handelsregister: Amtsgericht Ulm, HRB 630992
ALLGEMEINE GESCHÄFTSBEDINGUNGEN
Es gelten unsere Allgemeinen Geschäftsbedingungen
(AGB). Sie finden sie in der jeweils gültigen Fassung
im Internet unter http://www.avira.de/agb
***************************************************
diff -rup dazukofs-3.0.0-p8/inode.c dazukofs-3.0.0-p9/inode.c
--- dazukofs-3.0.0-p8/inode.c 2009-04-27 11:37:07.000000000 +0200
+++ dazukofs-3.0.0-p9/inode.c 2009-04-29 15:13:07.000000000 +0200
@@ -129,6 +129,39 @@ out:
return err;
}
+static struct dentry *dazukofs_lookup_one_lower(const char *name,
+ struct dentry *base,
+ struct nameidata *nd)
+{
+ struct dentry *lower_base;
+ struct vfsmount *lower_mnt;
+ struct vfsmount *vfsmount_save;
+ struct dentry *dentry_save;
+ struct dentry *result;
+ int err;
+
+ lower_base = GET_LOWER_DENTRY(base);
+ lower_mnt = GET_LOWER_MNT(base);
+
+ vfsmount_save = nd->path.mnt;
+ dentry_save = nd->path.dentry;
+
+ err = vfs_path_lookup(lower_base, lower_mnt, name, nd->flags, nd);
+ if (err) {
+ result = ERR_PTR(err);
+ goto undo;
+ }
+ /* we dont need the mount */
+ mntput(nd->path.mnt);
+ result = nd->path.dentry;
+undo:
+ nd->path.mnt = vfsmount_save;
+ nd->path.dentry = dentry_save;
+
+ return result;
+}
+
+
/**
* Description: Called when the VFS needs to look up an inode in a parent
* directory. The name to look for is found in the dentry. This method
@@ -161,9 +194,9 @@ static struct dentry *dazukofs_lookup(st
dentry->d_op = &dazukofs_dops;
lower_dentry_parent = GET_LOWER_DENTRY(dentry->d_parent);
- lower_dentry = lookup_one_len(dentry->d_name.name, lower_dentry_parent,
- dentry->d_name.len);
+ lower_dentry = dazukofs_lookup_one_lower(dentry->d_name.name,
+ dentry->d_parent, nd);
if (IS_ERR(lower_dentry)) {
err = PTR_ERR(lower_dentry);
d_drop(dentry);
Nur in dazukofs-3.0.0-p8: MakefileBAK.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dazuko-devel] patch 9 for dazukofs release 3.0.0,
Lino Sanfilippo <=