Skip to content
Permalink
Browse files
xfs: make sure link path does not go away at access
When following a trailing symlink in rcu-walk mode it's possible to
succeed in getting the ->get_link() method pointer but the link path
string be deallocated while it's being used.

Utilize the rcu mechanism to mitigate this risk.

Suggested-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Ian Kent <raven@themaw.net>
  • Loading branch information
raven-au authored and intel-lab-lkp committed Nov 11, 2021
1 parent ce256b2 commit 1208c3b6210fbb49718cdf4fa5f7db35bea008f6
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
@@ -61,6 +61,10 @@ static inline void kmem_free(const void *ptr)
{
kvfree(ptr);
}
static inline void kmem_free_rcu(const void *ptr)
{
kvfree_rcu(ptr);
}


static inline void *
@@ -2644,8 +2644,8 @@ xfs_ifree(
* already been freed by xfs_attr_inactive.
*/
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
kmem_free(ip->i_df.if_u1.if_data);
ip->i_df.if_u1.if_data = NULL;
kmem_free_rcu(ip->i_df.if_u1.if_data);
RCU_INIT_POINTER(ip->i_df.if_u1.if_data, NULL);
ip->i_df.if_bytes = 0;
}

@@ -524,11 +524,17 @@ xfs_vn_get_link_inline(

/*
* The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if
* if_data is junk.
* if_data is junk. Also, if the path walk is in rcu-walk mode
* and the inode link path has gone away due inode re-use we have
* no choice but to tell the VFS to redo the lookup.
*/
link = ip->i_df.if_u1.if_data;
link = rcu_dereference(ip->i_df.if_u1.if_data);
if (!dentry && !link)
return ERR_PTR(-ECHILD);

if (XFS_IS_CORRUPT(ip->i_mount, !link))
return ERR_PTR(-EFSCORRUPTED);

return link;
}

0 comments on commit 1208c3b

Please sign in to comment.