public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/6] bacct_add_tsk: fix unsafe and wrong parent/group_leader dereference
@ 2006-10-26 23:21 Oleg Nesterov
  2006-10-27 17:40 ` Jay Lan
  0 siblings, 1 reply; 2+ messages in thread
From: Oleg Nesterov @ 2006-10-26 23:21 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Shailabh Nagar, Balbir Singh, Jay Lan, linux-kernel

1. ts = timespec_sub(uptime, current->group_leader->start_time);

   It is possible that current != tsk. Probably it was supposed
   to be 'tsk->group_leader->start_time. But why we are reading
   group_leader's start_time ? This accounting is per thread,
   not per procees, I changed this to 'tsk->start_time.
   Please corect me.

2. stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0;

   tsk->parent never == NULL, and it is unsafe to dereference it.
   Both the task and it's parent may exit after the caller unlocks
   tasklist_lock, the memory could be unmapped (DEBUG_SLAB).
   (And we should use ->real_parent->tgid in fact).

Q: I don't understand the 'if (thread_group_leader(tsk))' check.
Why it is needed ?

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>

--- STATS/kernel/tsacct.c~2_par_fix	2006-10-22 18:24:03.000000000 +0400
+++ STATS/kernel/tsacct.c	2006-10-27 01:03:26.000000000 +0400
@@ -36,7 +36,7 @@ void bacct_add_tsk(struct taskstats *sta
 
 	/* calculate task elapsed time in timespec */
 	do_posix_clock_monotonic_gettime(&uptime);
-	ts = timespec_sub(uptime, current->group_leader->start_time);
+	ts = timespec_sub(uptime, tsk->start_time);
 	/* rebase elapsed time to usec */
 	ac_etime = timespec_to_ns(&ts);
 	do_div(ac_etime, NSEC_PER_USEC);
@@ -58,7 +58,10 @@ void bacct_add_tsk(struct taskstats *sta
 	stats->ac_uid	 = tsk->uid;
 	stats->ac_gid	 = tsk->gid;
 	stats->ac_pid	 = tsk->pid;
-	stats->ac_ppid	 = (tsk->parent) ? tsk->parent->pid : 0;
+	rcu_read_lock();
+	stats->ac_ppid	 = pid_alive(tsk) ?
+				rcu_dereference(tsk->real_parent)->tgid : 0;
+	rcu_read_unlock();
 	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
 	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
 	stats->ac_minflt = tsk->min_flt;


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH 2/6] bacct_add_tsk: fix unsafe and wrong parent/group_leader dereference
  2006-10-26 23:21 [PATCH 2/6] bacct_add_tsk: fix unsafe and wrong parent/group_leader dereference Oleg Nesterov
@ 2006-10-27 17:40 ` Jay Lan
  0 siblings, 0 replies; 2+ messages in thread
From: Jay Lan @ 2006-10-27 17:40 UTC (permalink / raw)
  To: Oleg Nesterov; +Cc: Andrew Morton, Shailabh Nagar, Balbir Singh, linux-kernel

Oleg Nesterov wrote:
> 1. ts = timespec_sub(uptime, current->group_leader->start_time);
> 
>    It is possible that current != tsk. Probably it was supposed
>    to be 'tsk->group_leader->start_time. But why we are reading
>    group_leader's start_time ? This accounting is per thread,
>    not per procees, I changed this to 'tsk->start_time.
>    Please corect me.

This is right. Thanks!

> 
> 2. stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0;
> 
>    tsk->parent never == NULL, and it is unsafe to dereference it.
>    Both the task and it's parent may exit after the caller unlocks
>    tasklist_lock, the memory could be unmapped (DEBUG_SLAB).
>    (And we should use ->real_parent->tgid in fact).
> 
> Q: I don't understand the 'if (thread_group_leader(tsk))' check.
> Why it is needed ?

The code was borrowed from kernel/acct.c. The CSA code was extended
from the BSD accounting, so we just borrowed the basic accounting
stuff from the code.

Thanks,
 - jay

> 
> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
> 
> --- STATS/kernel/tsacct.c~2_par_fix	2006-10-22 18:24:03.000000000 +0400
> +++ STATS/kernel/tsacct.c	2006-10-27 01:03:26.000000000 +0400
> @@ -36,7 +36,7 @@ void bacct_add_tsk(struct taskstats *sta
>  
>  	/* calculate task elapsed time in timespec */
>  	do_posix_clock_monotonic_gettime(&uptime);
> -	ts = timespec_sub(uptime, current->group_leader->start_time);
> +	ts = timespec_sub(uptime, tsk->start_time);
>  	/* rebase elapsed time to usec */
>  	ac_etime = timespec_to_ns(&ts);
>  	do_div(ac_etime, NSEC_PER_USEC);
> @@ -58,7 +58,10 @@ void bacct_add_tsk(struct taskstats *sta
>  	stats->ac_uid	 = tsk->uid;
>  	stats->ac_gid	 = tsk->gid;
>  	stats->ac_pid	 = tsk->pid;
> -	stats->ac_ppid	 = (tsk->parent) ? tsk->parent->pid : 0;
> +	rcu_read_lock();
> +	stats->ac_ppid	 = pid_alive(tsk) ?
> +				rcu_dereference(tsk->real_parent)->tgid : 0;
> +	rcu_read_unlock();
>  	stats->ac_utime	 = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
>  	stats->ac_stime	 = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
>  	stats->ac_minflt = tsk->min_flt;
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-10-27 17:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-26 23:21 [PATCH 2/6] bacct_add_tsk: fix unsafe and wrong parent/group_leader dereference Oleg Nesterov
2006-10-27 17:40 ` Jay Lan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox