Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70b89021 authored by Tyler Hicks's avatar Tyler Hicks
Browse files

eCryptfs: Handle NULL nameidata pointers



Allow for NULL nameidata pointers in eCryptfs create, lookup, and
d_revalidate functions.

Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
parent 8787c7a3
Loading
Loading
Loading
Loading
+13 −9
Original line number Original line Diff line number Diff line
@@ -46,24 +46,28 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
{
{
	struct dentry *lower_dentry;
	struct dentry *lower_dentry;
	struct vfsmount *lower_mnt;
	struct vfsmount *lower_mnt;
	struct dentry *dentry_save;
	struct dentry *dentry_save = NULL;
	struct vfsmount *vfsmount_save;
	struct vfsmount *vfsmount_save = NULL;
	int rc = 1;
	int rc = 1;


	if (nd->flags & LOOKUP_RCU)
	if (nd && nd->flags & LOOKUP_RCU)
		return -ECHILD;
		return -ECHILD;


	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
		goto out;
		goto out;
	if (nd) {
		dentry_save = nd->path.dentry;
		dentry_save = nd->path.dentry;
		vfsmount_save = nd->path.mnt;
		vfsmount_save = nd->path.mnt;
		nd->path.dentry = lower_dentry;
		nd->path.dentry = lower_dentry;
		nd->path.mnt = lower_mnt;
		nd->path.mnt = lower_mnt;
	}
	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd);
	if (nd) {
		nd->path.dentry = dentry_save;
		nd->path.dentry = dentry_save;
		nd->path.mnt = vfsmount_save;
		nd->path.mnt = vfsmount_save;
	}
	if (dentry->d_inode) {
	if (dentry->d_inode) {
		struct inode *lower_inode =
		struct inode *lower_inode =
			ecryptfs_inode_to_lower(dentry->d_inode);
			ecryptfs_inode_to_lower(dentry->d_inode);
+1 −2
Original line number Original line Diff line number Diff line
@@ -632,8 +632,7 @@ int ecryptfs_interpose(struct dentry *hidden_dentry,
		       u32 flags);
		       u32 flags);
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
					struct dentry *lower_dentry,
					struct dentry *lower_dentry,
					struct inode *ecryptfs_dir_inode,
					struct inode *ecryptfs_dir_inode);
					struct nameidata *ecryptfs_nd);
int ecryptfs_decode_and_decrypt_filename(char **decrypted_name,
int ecryptfs_decode_and_decrypt_filename(char **decrypted_name,
					 size_t *decrypted_name_size,
					 size_t *decrypted_name_size,
					 struct dentry *ecryptfs_dentry,
					 struct dentry *ecryptfs_dentry,
+15 −15
Original line number Original line Diff line number Diff line
@@ -74,16 +74,20 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
	unsigned int flags_save;
	unsigned int flags_save;
	int rc;
	int rc;


	if (nd) {
		dentry_save = nd->path.dentry;
		dentry_save = nd->path.dentry;
		vfsmount_save = nd->path.mnt;
		vfsmount_save = nd->path.mnt;
		flags_save = nd->flags;
		flags_save = nd->flags;
		nd->path.dentry = lower_dentry;
		nd->path.dentry = lower_dentry;
		nd->path.mnt = lower_mnt;
		nd->path.mnt = lower_mnt;
		nd->flags &= ~LOOKUP_OPEN;
		nd->flags &= ~LOOKUP_OPEN;
	}
	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
	rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
	if (nd) {
		nd->path.dentry = dentry_save;
		nd->path.dentry = dentry_save;
		nd->path.mnt = vfsmount_save;
		nd->path.mnt = vfsmount_save;
		nd->flags = flags_save;
		nd->flags = flags_save;
	}
	return rc;
	return rc;
}
}


@@ -241,8 +245,7 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
 */
 */
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
					struct dentry *lower_dentry,
					struct dentry *lower_dentry,
					struct inode *ecryptfs_dir_inode,
					struct inode *ecryptfs_dir_inode)
					struct nameidata *ecryptfs_nd)
{
{
	struct dentry *lower_dir_dentry;
	struct dentry *lower_dir_dentry;
	struct vfsmount *lower_mnt;
	struct vfsmount *lower_mnt;
@@ -290,8 +293,6 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
		goto out;
		goto out;
	if (special_file(lower_inode->i_mode))
	if (special_file(lower_inode->i_mode))
		goto out;
		goto out;
	if (!ecryptfs_nd)
		goto out;
	/* Released in this function */
	/* Released in this function */
	page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER);
	page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER);
	if (!page_virt) {
	if (!page_virt) {
@@ -417,8 +418,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
	}
	}
lookup_and_interpose:
lookup_and_interpose:
	rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry,
	rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry,
						 ecryptfs_dir_inode,
						 ecryptfs_dir_inode);
						 ecryptfs_nd);
	goto out;
	goto out;
out_d_drop:
out_d_drop:
	d_drop(ecryptfs_dentry);
	d_drop(ecryptfs_dentry);