Messages in this thread | | | Date | Fri, 19 Jun 2009 22:24:31 +1000 | From | Paul Mackerras <> | Subject | Re: [tip:perfcounters/core] perf_counter: Simplify and fix task migration counting |
| |
Peter Zijlstra writes:
> static struct perf_counter_context *perf_pin_task_context(struct task_struct *task) > { > struct perf_counter_context *ctx; > unsigned long flags; > > ctx = perf_lock_task_context(task, &flags); > if (ctx) { > ++ctx->pin_count; > get_ctx(ctx); > spin_unlock_irqrestore(&ctx->lock, flags); > } > return ctx; > } > > Is buggy because perf_lock_task_context() can return a dead context. > > the RCU read lock in perf_lock_task_context() only guarantees the memory > won't get freed, it doesn't guarantee the object is valid (in our case > refcount > 0). > > Therefore we can return a locked object that can get freed the moment we > release the rcu read lock. > > perf_pin_task_context() then increases the refcount and does an unlock > on freed memory. > > That increased refcount will cause a double free, in case it started out > with 0.
Wow, good catch! Thanks for finding that.
Paul.
| |