On Mon, 2010-06-28 at 21:17 +0800, shenghui wrote: > Hi, > > I'm reading cfs code, and get the following potential bug. > > In kernel/sched_fair.c, we can get the following call thread: > > 1778static struct task_struct *pick_next_task_fair(struct rq *rq) > 1779{ > ... > 1787 do { > 1788 se = pick_next_entity(cfs_rq); > 1789 set_next_entity(cfs_rq, se); > 1790 cfs_rq = group_cfs_rq(se); > 1791 } while (cfs_rq); > ... > 1797} > > 925static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) > 926{ > 927 struct sched_entity *se = __pick_next_entity(cfs_rq); > ... > 941 return se; > 942} > > 377static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) > 378{ > 379 struct rb_node *left = cfs_rq->rb_leftmost; > 380 > 381 if (!left) > 382 return NULL; > ... > 385} > > To manipulate cfs_rq->rb_leftmost, __dequeue_entity does the following: > > 365static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) > 366{ > 367 if (cfs_rq->rb_leftmost == &se->run_node) { > 368 struct rb_node *next_node; > 369 > 370 next_node = rb_next(&se->run_node); > 371 cfs_rq->rb_leftmost = next_node; > 372 } > 373 > 374 rb_erase(&se->run_node, &cfs_rq->tasks_timeline); > 375} > > Here, if se->run_node is the root rb_node, next_node will be set NULL > by rb_next. > Then __pick_next_entity may get NULL on some call, and set_next_entity > may deference > NULL value. So if ->rb_leftmost is NULL, then the if (!left) check in __pick_next_entity() would return null. As to the NULL deref in in pick_next_task_fair()->set_next_entity() that should never happen because pick_next_task_fair() will bail on !->nr_running. Furthermore, you've failed to mention what kernel version you're looking at. -- To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html