lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <20071015084052.GA21870@infradead.org> Date: Mon, 15 Oct 2007 09:40:52 +0100 From: Christoph Hellwig <hch@...radead.org> To: Laurent Riffard <laurent.riffard@...e.fr> Cc: Andrew Morton <akpm@...ux-foundation.org>, Dave Hansen <haveblue@...ibm.com>, linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org, reiserfs-devel@...r.kernel.org Subject: Re: 2.6.23-mm1: BUG in reiserfs_delete_xattrs On Mon, Oct 15, 2007 at 12:34:58AM +0200, Laurent Riffard wrote: > reiserfs_delete_xattrs > reiserfs_delete_inode > generic_delete_inode > generic_drop_inode > iput > do_unlinkat > sys_unlink > sys_enter_past_esp > > I reported a similar BUG in 2.6.22-rc8-mm2 (see > http://lkml.org/lkml/2007/9/27/235). Dave Hansen sent a patch for it, I > tested it and it was OK for 2.6.22-rc8-mm2. > > I tried this patch on 2.6.23-mm1, and it fixed the BUGs here too. The delete path is a similar case as the one Dave fixed, also cause by a NULL vfsmount passed to dentry_open, but through a different code-path. Untested fix for this problem below: Index: linux-2.6.23-rc8/fs/reiserfs/xattr.c =================================================================== --- linux-2.6.23-rc8.orig/fs/reiserfs/xattr.c 2007-09-30 14:13:46.000000000 +0200 +++ linux-2.6.23-rc8/fs/reiserfs/xattr.c 2007-09-30 14:18:30.000000000 +0200 @@ -207,9 +207,8 @@ static struct dentry *get_xa_file_dentry * we're called with i_mutex held, so there are no worries about the directory * changing underneath us. */ -static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) +static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir) { - struct inode *inode = filp->f_path.dentry->d_inode; struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ INITIALIZE_PATH(path_to_entry); struct buffer_head *bh; @@ -352,24 +351,19 @@ static int __xattr_readdir(struct file * * this is stolen from vfs_readdir * */ -static -int xattr_readdir(struct file *file, filldir_t filler, void *buf) +static int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) { - struct inode *inode = file->f_path.dentry->d_inode; int res = -ENOTDIR; - if (!file->f_op || !file->f_op->readdir) - goto out; + mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); -// down(&inode->i_zombie); res = -ENOENT; if (!IS_DEADDIR(inode)) { lock_kernel(); - res = __xattr_readdir(file, buf, filler); + res = __xattr_readdir(inode, buf, filler); unlock_kernel(); } -// up(&inode->i_zombie); mutex_unlock(&inode->i_mutex); - out: + return res; } @@ -721,7 +715,6 @@ reiserfs_delete_xattrs_filler(void *buf, /* This is called w/ inode->i_mutex downed */ int reiserfs_delete_xattrs(struct inode *inode) { - struct file *fp; struct dentry *dir, *root; int err = 0; @@ -742,15 +735,8 @@ int reiserfs_delete_xattrs(struct inode return 0; } - fp = dentry_open(dir, NULL, O_RDWR); - if (IS_ERR(fp)) { - err = PTR_ERR(fp); - /* dentry_open dputs the dentry if it fails */ - goto out; - } - lock_kernel(); - err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir); + err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); if (err) { unlock_kernel(); goto out_dir; @@ -770,7 +756,7 @@ int reiserfs_delete_xattrs(struct inode unlock_kernel(); out_dir: - fput(fp); + dput(dir); out: if (!err) @@ -812,7 +798,6 @@ reiserfs_chown_xattrs_filler(void *buf, int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) { - struct file *fp; struct dentry *dir; int err = 0; struct reiserfs_chown_buf buf; @@ -836,13 +821,6 @@ int reiserfs_chown_xattrs(struct inode * goto out; } - fp = dentry_open(dir, NULL, O_RDWR); - if (IS_ERR(fp)) { - err = PTR_ERR(fp); - /* dentry_open dputs the dentry if it fails */ - goto out; - } - lock_kernel(); attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); @@ -850,7 +828,7 @@ int reiserfs_chown_xattrs(struct inode * buf.attrs = attrs; buf.inode = inode; - err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf); + err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); if (err) { unlock_kernel(); goto out_dir; @@ -860,7 +838,7 @@ int reiserfs_chown_xattrs(struct inode * unlock_kernel(); out_dir: - fput(fp); + dput(dir); out: attrs->ia_valid = ia_valid; @@ -1008,7 +986,6 @@ reiserfs_listxattr_filler(void *buf, con */ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) { - struct file *fp; struct dentry *dir; int err = 0; struct reiserfs_listxattr_buf buf; @@ -1031,13 +1008,6 @@ ssize_t reiserfs_listxattr(struct dentry goto out; } - fp = dentry_open(dir, NULL, O_RDWR); - if (IS_ERR(fp)) { - err = PTR_ERR(fp); - /* dentry_open dputs the dentry if it fails */ - goto out; - } - buf.r_buf = buffer; buf.r_size = buffer ? size : 0; buf.r_pos = 0; @@ -1045,7 +1015,7 @@ ssize_t reiserfs_listxattr(struct dentry REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; - err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf); + err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); if (err) goto out_dir; @@ -1055,7 +1025,7 @@ ssize_t reiserfs_listxattr(struct dentry err = buf.r_pos; out_dir: - fput(fp); + dput(dir); out: reiserfs_read_unlock_xattr_i(dentry->d_inode); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists