[patch-2.4.0-test6-pre1] fixed race in chroot_fs_refs()

From: Tigran Aivazian (tigran@veritas.com)
Date: Tue Aug 01 2000 - 08:20:55 EST


Hi Linus,

below is the patch that accesses p->fs while walking the
for_each_task(p) list properly, i.e. fixes the (harmless, according to
comments) race in fs/super.c:chroot_fs_refs()

regards,
Tigran

PS. While we are on the subject of tasklist_lock - a horrible doubt is
bothering me - if I hold read_lock(&tasklist_lock) and walk the task list,
can't some other context call release(p) under me (and thus free task
structure) in kernel/exit.c:sys_wait4()? I see no protection against it...

--- linux/fs/super.c Fri Jul 28 09:59:00 2000
+++ work/fs/super.c Tue Aug 1 14:11:31 2000
@@ -1566,15 +1566,23 @@
                            struct vfsmount *new_rootmnt)
 {
         struct task_struct *p;
+ struct fs_struct *fs;
 
         read_lock(&tasklist_lock);
         for_each_task(p) {
- /* FIXME - unprotected usage of ->fs + (harmless) race */
- if (!p->fs) continue;
- if (p->fs->root == old_root && p->fs->rootmnt == old_rootmnt)
- set_fs_root(p->fs, new_rootmnt, new_root);
- if (p->fs->pwd == old_root && p->fs->pwdmnt == old_rootmnt)
- set_fs_pwd(p->fs, new_rootmnt, new_root);
+ task_lock(p);
+ fs = p->fs;
+ if (!p->fs) {
+ task_unlock(p);
+ continue;
+ } else
+ atomic_inc(&fs->count);
+ task_unlock(p);
+ if (fs->root == old_root && fs->rootmnt == old_rootmnt)
+ set_fs_root(fs, new_rootmnt, new_root);
+ if (fs->pwd == old_root && fs->pwdmnt == old_rootmnt)
+ set_fs_pwd(fs, new_rootmnt, new_root);
+ put_fs_struct(fs);
         }
         read_unlock(&tasklist_lock);
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Aug 07 2000 - 21:00:05 EST