summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/proc/base.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 9b423fec9732..51507065263b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3097,10 +3097,14 @@ out_no_task:
* In the case of a seek we start with the leader and walk nr
* threads past it.
*/
-static struct task_struct *first_tid(struct pid *pid, int tid,
- int nr, struct pid_namespace *ns)
+static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos,
+ struct pid_namespace *ns)
{
struct task_struct *pos, *task;
+ unsigned long nr = f_pos;
+
+ if (nr != f_pos) /* 32bit overflow? */
+ return NULL;
rcu_read_lock();
task = pid_task(pid, PIDTYPE_PID);
@@ -3108,14 +3112,14 @@ static struct task_struct *first_tid(struct pid *pid, int tid,
goto fail;
/* Attempt to start with the tid of a thread */
- if (tid && (nr > 0)) {
+ if (tid && nr) {
pos = find_task_by_pid_ns(tid, ns);
if (pos && same_thread_group(pos, task))
goto found;
}
/* If nr exceeds the number of threads there is nothing todo */
- if (nr && nr >= get_nr_threads(task))
+ if (nr >= get_nr_threads(task))
goto fail;
/* If we haven't found our starting place yet start
@@ -3123,7 +3127,7 @@ static struct task_struct *first_tid(struct pid *pid, int tid,
*/
pos = task = task->group_leader;
do {
- if (nr-- <= 0)
+ if (!nr--)
goto found;
} while_each_thread(task, pos);
fail: