Name: Group Reference Counting Debug Patch Status: Tested on 21 May 2004 Someone is dropping refcnt of current->group_info too many times. This should catch the culprit. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .14959-linux-ppc64-2.5/include/linux/sched.h .14959-linux-ppc64-2.5.updated/include/linux/sched.h --- .14959-linux-ppc64-2.5/include/linux/sched.h 2004-05-18 07:04:54.000000000 +1000 +++ .14959-linux-ppc64-2.5.updated/include/linux/sched.h 2004-05-21 11:06:50.000000000 +1000 @@ -365,11 +365,7 @@ struct group_info { atomic_inc(&(group_info)->usage); \ } while (0) -#define put_group_info(group_info) do { \ - if (atomic_dec_and_test(&(group_info)->usage)) \ - groups_free(group_info); \ -} while (0) - +extern void put_group_info(struct group_info *); struct group_info *groups_alloc(int gidsetsize); void groups_free(struct group_info *group_info); int set_current_groups(struct group_info *group_info); diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .14959-linux-ppc64-2.5/kernel/sys.c .14959-linux-ppc64-2.5.updated/kernel/sys.c --- .14959-linux-ppc64-2.5/kernel/sys.c 2004-05-20 22:05:02.000000000 +1000 +++ .14959-linux-ppc64-2.5.updated/kernel/sys.c 2004-05-21 11:12:54.000000000 +1000 @@ -1158,6 +1158,16 @@ out_undo_partial_alloc: EXPORT_SYMBOL(groups_alloc); +void put_group_info(struct group_info *group_info) +{ + if (atomic_dec_and_test(&group_info->usage)) { + /* Can't free underneath ourselves. */ + BUG_ON(group_info == current->group_info); + groups_free(group_info); + } +} +EXPORT_SYMBOL(put_group_info); + void groups_free(struct group_info *group_info) { if (group_info->blocks[0] != group_info->small_block) { @@ -1268,6 +1278,8 @@ int set_current_groups(struct group_info int retval; struct group_info *old_info; + BUG_ON(atomic_read(&group_info->usage) <= 0); + retval = security_task_setgroups(group_info); if (retval) return retval;