Commit b5a660ee authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] is_subdir locking fix

From: Maneesh Soni <maneesh@in.ibm.com>

o The following patch fixes is_subdir() races with d_move. Due to concurrent
  d_move, in is_subdir() we can end up accessing freed d_parent pointer in
  case of pre-emptible kernel. To avoid this we can use rcu_read_lock() and
  rcu_read_unlock().

o This also fixes the seqlock uses in is_subdir() as we need to restart the
  the inner loop with the origianl new_dentry passed to the routine in case
  of any rename occured while we are traversing d_parent links.
parent c2d6098c
...@@ -1433,15 +1433,23 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) ...@@ -1433,15 +1433,23 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
* *
* Returns 1 if new_dentry is a subdirectory of the parent (at any depth). * Returns 1 if new_dentry is a subdirectory of the parent (at any depth).
* Returns 0 otherwise. * Returns 0 otherwise.
* Caller must ensure that "new_dentry" is pinned before calling is_subdir()
*/ */
int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry) int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
{ {
int result; int result;
struct dentry * saved = new_dentry;
unsigned long seq; unsigned long seq;
result = 0; result = 0;
/* need rcu_readlock to protect against the d_parent trashing due to
* d_move
*/
rcu_read_lock();
do { do {
/* for restarting inner loop in case of seq retry */
new_dentry = saved;
seq = read_seqbegin(&rename_lock); seq = read_seqbegin(&rename_lock);
for (;;) { for (;;) {
if (new_dentry != old_dentry) { if (new_dentry != old_dentry) {
...@@ -1455,6 +1463,7 @@ int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry) ...@@ -1455,6 +1463,7 @@ int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
break; break;
} }
} while (read_seqretry(&rename_lock, seq)); } while (read_seqretry(&rename_lock, seq));
rcu_read_unlock();
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment