From: Simon Derr This fixes a possible race between two threads of a single process in cpuset_tasks_read(). It is mostly the same issue as the one that was in sysfs. Signed-Off-By: Simon Derr Signed-off-by: Andrew Morton --- 25-akpm/kernel/cpuset.c | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff -puN kernel/cpuset.c~cpusets-fix-possible-race-in-cpuset_tasks_read kernel/cpuset.c --- 25/kernel/cpuset.c~cpusets-fix-possible-race-in-cpuset_tasks_read 2004-09-11 17:26:05.822749504 -0700 +++ 25-akpm/kernel/cpuset.c 2004-09-11 17:26:05.826748896 -0700 @@ -1083,20 +1083,27 @@ err0: static ssize_t cpuset_tasks_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct ctr_struct *ctr = (struct ctr_struct *)file->private_data; + struct ctr_struct *ctr; + down(&cpuset_sem); + ctr = (struct ctr_struct *)file->private_data; /* allocate buffer and fill it on first call to read() */ if (!ctr) { ctr = cpuset_tasks_mkctr(file); - if (!ctr) + if (!ctr) { + up(&cpuset_sem); return -ENOMEM; + } } if (*ppos + nbytes > ctr->bufsz) nbytes = ctr->bufsz - *ppos; - if (copy_to_user(buf, ctr->buf + *ppos, nbytes)) + if (copy_to_user(buf, ctr->buf + *ppos, nbytes)) { + up(&cpuset_sem); return -EFAULT; + } *ppos += nbytes; + up(&cpuset_sem); return nbytes; } _