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
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <87siie95i7.fsf@devron.myhome.or.jp>
Date:	Fri, 24 Oct 2014 00:21:04 +0900
From:	OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>
To:	Al Viro <viro@...IV.linux.org.uk>
Cc:	Richard Weinberger <richard@....at>, linux-fsdevel@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/2] fat: Fix d_splice_alias() return code checking

Al Viro <viro@...IV.linux.org.uk> writes:

> On Sun, Oct 19, 2014 at 12:39:43PM +0200, Richard Weinberger wrote:
>> d_splice_alias() can return a valid dentry, NULL or an ERR_PTR.
>> Currently the code checks not for ERR_PTR.
>> Fix this by using IS_ERR_OR_NULL().
>
> Why do we need to set ->d_time for non-NULL inode anyway?  AFAICS,
> it's never checked for positive dentries, and the moment when positive
> dentry become negative is when we want to set it anyway.
>
> What am I missing here?  Why not simply do this:

Hm, at least, this changes behavior though (old one drops if parent
changed after target dentry created, then when become negative. New one
drops if changed parent after target became negative.).

However, looks like new behavior is workable. And I think it is worth to try.

Can you add Signed-off-by:?

> diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
> index 6df8d3d..e2dc6bf 100644
> --- a/fs/fat/namei_vfat.c
> +++ b/fs/fat/namei_vfat.c
> @@ -725,15 +725,14 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
>  			inode = NULL;
>  			goto out;
>  		}
> -		goto error;
> +		inode = ERR_PTR(inode);
> +		goto out;
>  	}
>  
>  	inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
>  	brelse(sinfo.bh);
> -	if (IS_ERR(inode)) {
> -		err = PTR_ERR(inode);
> -		goto error;
> -	}
> +	if (IS_ERR(inode))
> +		goto out;
>  
>  	alias = d_find_alias(inode);
>  	if (alias && !vfat_d_anon_disconn(alias)) {
> @@ -754,16 +753,10 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
>  		dput(alias);
>  
>  out:
> +	if (!inode)
> +		dentry->d_time = dir->i_version;
>  	mutex_unlock(&MSDOS_SB(sb)->s_lock);
> -	dentry->d_time = dentry->d_parent->d_inode->i_version;
> -	dentry = d_splice_alias(inode, dentry);
> -	if (dentry)
> -		dentry->d_time = dentry->d_parent->d_inode->i_version;
> -	return dentry;
> -
> -error:
> -	mutex_unlock(&MSDOS_SB(sb)->s_lock);
> -	return ERR_PTR(err);
> +	return d_splice_alias(inode, dentry);
>  }
>  
>  static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
> @@ -793,7 +786,6 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
>  	inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
>  	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
>  
> -	dentry->d_time = dentry->d_parent->d_inode->i_version;
>  	d_instantiate(dentry, inode);
>  out:
>  	mutex_unlock(&MSDOS_SB(sb)->s_lock);
> @@ -824,6 +816,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
>  	clear_nlink(inode);
>  	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
>  	fat_detach(inode);
> +	dentry->d_time = dir->i_version;
>  out:
>  	mutex_unlock(&MSDOS_SB(sb)->s_lock);
>  
> @@ -849,6 +842,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
>  	clear_nlink(inode);
>  	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
>  	fat_detach(inode);
> +	dentry->d_time = dir->i_version;
>  out:
>  	mutex_unlock(&MSDOS_SB(sb)->s_lock);
>  
> @@ -889,7 +883,6 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
>  	inode->i_mtime = inode->i_atime = inode->i_ctime = ts;
>  	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
>  
> -	dentry->d_time = dentry->d_parent->d_inode->i_version;
>  	d_instantiate(dentry, inode);
>  
>  	mutex_unlock(&MSDOS_SB(sb)->s_lock);

-- 
OGAWA Hirofumi <hirofumi@...l.parknet.co.jp>
--
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ