On 09/23/2013 11:06 PM, Tejun Heo wrote: > Hello, > > (I have no idea about this but Andrew tagged me, probably thinking it > was related to cgroups, so here it goes ;) >
First, thank you for spending your time resource to discuss this patch. > On Tue, Aug 20, 2013 at 11:01:14AM +0800, Chen Gang wrote: >> groups_alloc() can return NULL for 'group_info', also group_search() >> already considers about NULL for 'group_info', so can assume the caller >> has right to use all related extern functions when 'group_info' is NULL. >> >> For groups_free(), need check NULL to match groups_alloc(), just like >> kmalloc/free(). > > While it is somewhat customary to make free routines handle NULL > inputs, the convention isn't a very strong one and given that the > above change doesn't actually benefit any of the existing use cases, > it seems gratuituous. > Hmm... can user be permitted to call other system call (e.g. getgroups) before call groups_alloc()? (may the user space already give check, but for our kernel, we can not only depend on their checking). According to group_alloc() and setgroups() usage in kernel source code, 'group_info' may be not set if kernel/process is running (although user space may be sure "if kernel is running, 'group_info' must be set"). The below is the proof for "kernel itself can not be sure 'group_info' must be set during kernel/process is running", please check, thanks. The related usage of group_alloc() is below: arch/s390/kernel/compat_linux.c:257: group_info = groups_alloc(gidsetsize); drivers/staging/lustre/lustre/include/linux/lustre_common.h:10: ginfo = groups_alloc(0); drivers/staging/lustre/lustre/ptlrpc/service.c:2287: ginfo = groups_alloc(0); fs/nfsd/auth.c:46: gi = groups_alloc(0); fs/nfsd/auth.c:55: gi = groups_alloc(rqgi->ngroups); kernel/uid16.c:184: group_info = groups_alloc(gidsetsize); /* called by setgroups16 */ kernel/groups.c:241: group_info = groups_alloc(gidsetsize); /* called by setgroups */ net/sunrpc/svcauth_unix.c:506: ug.gi = groups_alloc(gids); net/sunrpc/svcauth_unix.c:752: cred->cr_group_info = groups_alloc(0); net/sunrpc/svcauth_unix.c:823: cred->cr_group_info = groups_alloc(slen); net/sunrpc/auth_gss/gss_rpc_xdr.c:218: creds->cr_group_info = groups_alloc(N); net/sunrpc/auth_gss/svcauth_gss.c:467: rsci.cred.cr_group_info = groups_alloc(N); except "kernel/*", others are all related with sub-systems or architectures, so we need search 'setgroups'. The related usage of setgroups() is below: arch/ia64/include/uapi/asm/unistd.h:69:#define __NR_setgroups 1078 arch/ia64/kernel/entry.S:1531: data8 sys_setgroups arch/ia64/kernel/fsys.S:606: data8 0 // setgroups arch/microblaze/include/uapi/asm/unistd.h:95:#define __NR_setgroups 81 /* ok */ arch/microblaze/include/uapi/asm/unistd.h:222:#define __NR_setgroups32 206 /* ok - without 32 */ arch/microblaze/kernel/syscall_table.S:84: .long sys_setgroups arch/microblaze/kernel/syscall_table.S:209: .long sys_setgroups arch/arm64/include/asm/unistd32.h:105:__SYSCALL(81, sys_setgroups16) arch/arm64/include/asm/unistd32.h:230:__SYSCALL(206, sys_setgroups) arch/mn10300/include/uapi/asm/unistd.h:95:#define __NR_setgroups 81 arch/mn10300/include/uapi/asm/unistd.h:220:#define __NR_setgroups32 206 arch/mn10300/kernel/entry.S:511: .long sys_setgroups16 arch/mn10300/kernel/entry.S:636: .long sys_setgroups arch/m68k/include/uapi/asm/unistd.h:89:#define __NR_setgroups 81 arch/m68k/include/uapi/asm/unistd.h:214:#define __NR_setgroups32 206 arch/m68k/kernel/syscalltable.S:104: .long sys_setgroups16 arch/m68k/kernel/syscalltable.S:229: .long sys_setgroups arch/sparc/include/uapi/asm/unistd.h:120:#define __NR_setgroups 80 /* Common */ arch/sparc/include/uapi/asm/unistd.h:123:#define __NR_setgroups32 82 /* Linux sparc32, setpgrp under SunOS */ arch/sparc/kernel/systbls_64.S:37:/*80*/ .word sys_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64 arch/sparc/kernel/systbls_64.S:115:/*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall arch/sparc/kernel/systbls_32.S:35:/*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64 arch/alpha/include/uapi/asm/unistd.h:84:#define __NR_setgroups 80 arch/alpha/kernel/systbls.S:94: .quad sys_setgroups /* 80 */ arch/sh/include/uapi/asm/unistd_64.h:98:#define __NR_setgroups 81 arch/sh/include/uapi/asm/unistd_64.h:223:#define __NR_setgroups32 206 arch/sh/include/uapi/asm/unistd_32.h:93:#define __NR_setgroups 81 arch/sh/include/uapi/asm/unistd_32.h:218:#define __NR_setgroups32 206 arch/sh/kernel/syscalls_64.S:104: .long sys_setgroups16 arch/sh/kernel/syscalls_64.S:229: .long sys_setgroups arch/sh/kernel/syscalls_32.S:100: .long sys_setgroups16 arch/sh/kernel/syscalls_32.S:225: .long sys_setgroups arch/m32r/include/uapi/asm/unistd.h:214:#define __NR_setgroups32 206 arch/m32r/include/asm/unistd.h:39:#define __IGNORE_setgroups arch/m32r/kernel/syscall_table.S:83: .long sys_ni_syscall /* setgroups16 syscall holder */ arch/m32r/kernel/syscall_table.S:208: .long sys_setgroups arch/xtensa/include/uapi/asm/unistd.h:431:#define __NR_setgroups 197 arch/xtensa/include/uapi/asm/unistd.h:432:__SYSCALL(197, sys_setgroups, 2) arch/mips/include/uapi/asm/unistd.h:104:#define __NR_setgroups (__NR_Linux + 81) arch/mips/include/uapi/asm/unistd.h:503:#define __NR_setgroups (__NR_Linux + 114) arch/mips/include/uapi/asm/unistd.h:829:#define __NR_setgroups (__NR_Linux + 114) arch/mips/kernel/scall64-64.S:232: PTR sys_setgroups arch/mips/kernel/scall64-n32.S:221: PTR sys_setgroups arch/mips/kernel/scall32-o32.S:317: sys sys_setgroups 2 arch/mips/kernel/scall64-o32.S:276: PTR sys_setgroups arch/frv/include/uapi/asm/unistd.h:89:#define __NR_setgroups 81 arch/frv/include/uapi/asm/unistd.h:215:#define __NR_setgroups32 206 arch/frv/kernel/entry.S:1261: .long sys_setgroups16 arch/frv/kernel/entry.S:1386: .long sys_setgroups arch/parisc/hpux/sys_hpux.c:561: "setgroups", /* 80 */ arch/parisc/include/uapi/asm/unistd.h:91:#define __NR_HPUX_setgroups 80 arch/parisc/include/uapi/asm/unistd.h:574:#define __NR_setgroups (__NR_Linux + 81) arch/parisc/kernel/syscall_table.S:155: ENTRY_SAME(setgroups) arch/s390/include/uapi/asm/unistd.h:305:#define __NR_setgroups 81 arch/s390/include/uapi/asm/unistd.h:332:#define __NR_setgroups32 206 arch/s390/include/uapi/asm/unistd.h:360:#define __NR_setgroups 206 arch/s390/kernel/compat_linux.c:247:asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) arch/s390/kernel/compat_wrapper.S:276:ENTRY(sys32_setgroups16_wrapper) arch/s390/kernel/compat_wrapper.S:279: jg sys32_setgroups16 # branch to system call arch/s390/kernel/compat_wrapper.S:696:ENTRY(sys32_setgroups_wrapper) arch/s390/kernel/compat_wrapper.S:699: jg sys_setgroups # branch to system call arch/s390/kernel/syscalls.S:92:SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */ arch/s390/kernel/syscalls.S:217:SYSCALL(sys_setgroups,sys_setgroups,sys32_setgroups_wrapper) arch/s390/kernel/compat_linux.h:92:long sys32_setgroups16(int gidsetsize, u16 __user *grouplist); arch/powerpc/include/uapi/asm/unistd.h:94:#define __NR_setgroups 81 arch/powerpc/include/asm/systbl.h:88:SYSCALL_SPU(setgroups) arch/arm/include/uapi/asm/unistd.h:109:#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) arch/arm/include/uapi/asm/unistd.h:234:#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) arch/arm/kernel/calls.S:93: CALL(sys_setgroups16) arch/arm/kernel/calls.S:218: CALL(sys_setgroups) arch/cris/arch-v10/kernel/entry.S:687: .long sys_setgroups16 arch/cris/arch-v10/kernel/entry.S:812: .long sys_setgroups arch/cris/include/uapi/asm/unistd.h:89:#define __NR_setgroups 81 arch/cris/include/uapi/asm/unistd.h:214:#define __NR_setgroups32 206 arch/cris/arch-v32/kernel/entry.S:633: .long sys_setgroups16 arch/cris/arch-v32/kernel/entry.S:758: .long sys_setgroups arch/avr32/include/uapi/asm/unistd.h:96:#define __NR_setgroups 81 arch/avr32/kernel/syscall_table.S:97: .long sys_setgroups arch/x86/syscalls/syscall_32.tbl:90:81 i386 setgroups sys_setgroups16 arch/x86/syscalls/syscall_32.tbl:215:206 i386 setgroups32 sys_setgroups arch/x86/syscalls/syscall_64.tbl:125:116 common setgroups sys_setgroups arch/blackfin/include/uapi/asm/unistd.h:93:#define __NR_setgroups 81 arch/blackfin/include/uapi/asm/unistd.h:218:#define __NR_setgroups32 206 arch/blackfin/mach-common/entry.S:1395: .long _sys_setgroups /* setgroups16 */ arch/blackfin/mach-common/entry.S:1520: .long _sys_setgroups include/uapi/linux/capability.h:134:/* Allows setgroups(2) */ include/uapi/asm-generic/unistd.h:456:#define __NR_setgroups 159 include/uapi/asm-generic/unistd.h:457:__SYSCALL(__NR_setgroups, sys_setgroups) include/linux/syscalls.h:236:asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist); include/linux/syscalls.h:521:asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist); kernel/sys_ni.c:132:cond_syscall(sys_setgroups16); kernel/uid16.c:174:SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) kernel/groups.c:231:SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) all of them are for definitions or declarations. The related conclusion: during kernel startup or process creation, kernel does not intend to set 'group_info'. >> For set_groups(), can allow the caller to set NULL parameter to new >> 'cred'. >> >> For system call getgroups(), if 'cred->group_info' is NULL, need return >> the related error code (no related data), also need change the related >> man page ("man 2 getgroups") to complete the return value. > > How can cred->group_info be NULL? Can you please describe what issue > this patch is trying to solve / improve? The patch description > explains what's being changed but doesn't really offer why such > changes are being made. Can you please explain why this change is > beneficial? > In extern function groups_search (which also called by export function in_group_p and in_egroup_p), it checks "if 'cred->group_info' is NULL". So "kernel/groups.c" have 9 extern/export/system-call functions, and 4/9 notice about "if 'cred->group_info' is NULL" (e.g. groups_alloc, groups_search, in_group_p, in_egroup_p). So for API self-consistency, all of extern/export/system-call functions need notice about it. > Thanks. > Thanks -- Chen Gang -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/