Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180913] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180915-051650 config: i386-tinyconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): kernel/cred.o: In function `commit_creds': >> cred.c:(.text+0x1ae): undefined reference to `get_net_ns_by_pid' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180913] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180915-051650 config: i386-tinyconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): kernel/cred.o: In function `commit_creds': >> cred.c:(.text+0x1ae): undefined reference to `get_net_ns_by_pid' --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
On Fri, Sep 14, 2018 at 1:14 PM My Name <18650033...@163.com> wrote: > Adversaries often attack the Linux kernel via using > commit_creds(prepare_kernel_cred(0)) to submit ROOT > credential for the purpose of privilege escalation. > For processes inside the Linux container, the above > approach also works, because the container and the > host share the same Linux kernel. Therefore, we en- > force a check in commit_creds() before updating the > cred of the caller process. If the process is insi- > de a container (judging from the Namespace ID) and > try to submit credentials with higher privileges t- > han current (judging from the uid, gid, and cap_bset > in the new cred), we will stop the modification. We > consider that if the namespace ID of the process is > different from the init Namespace ID (enumed in /i- > nclude/linux/proc_ns.h), the process is inside a c- > ontainer. And if the uid/gid in the new cred is sm- > aller or the cap_bset (capability bounding set) in > the new cred is larger, it may be a privilege esca- > lation operation. You only sent this patch to the LKML list without CC'ing anyone. People are unlikely to see your patches this way; you may want to, for example, CC the kernel-hardening list and people who have touched the files your patch changes in the past. More information on this is at https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html#select-the-recipients-for-your-patch . You sent five different versions of this patch; when you send multiple versions of a patch, please ensure that the subject line contains the version of the patch, as described in https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html . I also disagree with the fundamental approach taken in your patch; in my opinion, it is pointless to attempt to prevent kernel exploitation by restricting usage of one specific function. > Signed-off-by: Xin Lin <18650033...@163.com> > --- > kernel/cred.c | 24 > 1 file changed, 24 insertions(+) > > diff --git a/kernel/cred.c b/kernel/cred.c > index ecf0365..b9a313d 100644 > --- a/kernel/cred.c > +++ b/kernel/cred.c > @@ -19,6 +19,12 @@ > #include > #include > #include > +#include > +#include > +#include "../fs/mount.h" > +#include > +#include > +#include > > #if 0 > #define kdebug(FMT, ...) \ > @@ -33,6 +39,8 @@ do { > \ > } while (0) > #endif > > +bool flag = true; > +static struct net *initnet; > static struct kmem_cache *cred_jar; > > /* init to 2 - one for init_task, one to ensure it is never freed */ > @@ -425,6 +433,22 @@ int commit_creds(struct cred *new) > struct task_struct *task = current; > const struct cred *old = task->real_cred; > > + if (flag) { > + initnet = get_net_ns_by_pid(1); > + flag = false; > + } > + if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || > + task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || > + task->nsproxy->mnt_ns->ns.inum != 0xF000U || > + task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || > + task->nsproxy->net_ns->ns.inum != initnet->ns.inum || > + old->user_ns->ns.inum != PROC_USER_INIT_INO || > + task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { > + if (new->uid.val < old->uid.val || new->gid.val < old->gid.val > + || new->cap_bset.cap[0] > old->cap_bset.cap[0]) > + return 0; > + } > + > kdebug("commit_creds(%p{%d,%d})", new, >atomic_read(>usage), >read_cred_subscribers(new)); > -- > 2.7.4 > > >
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
On Fri, Sep 14, 2018 at 1:14 PM My Name <18650033...@163.com> wrote: > Adversaries often attack the Linux kernel via using > commit_creds(prepare_kernel_cred(0)) to submit ROOT > credential for the purpose of privilege escalation. > For processes inside the Linux container, the above > approach also works, because the container and the > host share the same Linux kernel. Therefore, we en- > force a check in commit_creds() before updating the > cred of the caller process. If the process is insi- > de a container (judging from the Namespace ID) and > try to submit credentials with higher privileges t- > han current (judging from the uid, gid, and cap_bset > in the new cred), we will stop the modification. We > consider that if the namespace ID of the process is > different from the init Namespace ID (enumed in /i- > nclude/linux/proc_ns.h), the process is inside a c- > ontainer. And if the uid/gid in the new cred is sm- > aller or the cap_bset (capability bounding set) in > the new cred is larger, it may be a privilege esca- > lation operation. You only sent this patch to the LKML list without CC'ing anyone. People are unlikely to see your patches this way; you may want to, for example, CC the kernel-hardening list and people who have touched the files your patch changes in the past. More information on this is at https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html#select-the-recipients-for-your-patch . You sent five different versions of this patch; when you send multiple versions of a patch, please ensure that the subject line contains the version of the patch, as described in https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html . I also disagree with the fundamental approach taken in your patch; in my opinion, it is pointless to attempt to prevent kernel exploitation by restricting usage of one specific function. > Signed-off-by: Xin Lin <18650033...@163.com> > --- > kernel/cred.c | 24 > 1 file changed, 24 insertions(+) > > diff --git a/kernel/cred.c b/kernel/cred.c > index ecf0365..b9a313d 100644 > --- a/kernel/cred.c > +++ b/kernel/cred.c > @@ -19,6 +19,12 @@ > #include > #include > #include > +#include > +#include > +#include "../fs/mount.h" > +#include > +#include > +#include > > #if 0 > #define kdebug(FMT, ...) \ > @@ -33,6 +39,8 @@ do { > \ > } while (0) > #endif > > +bool flag = true; > +static struct net *initnet; > static struct kmem_cache *cred_jar; > > /* init to 2 - one for init_task, one to ensure it is never freed */ > @@ -425,6 +433,22 @@ int commit_creds(struct cred *new) > struct task_struct *task = current; > const struct cred *old = task->real_cred; > > + if (flag) { > + initnet = get_net_ns_by_pid(1); > + flag = false; > + } > + if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || > + task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || > + task->nsproxy->mnt_ns->ns.inum != 0xF000U || > + task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || > + task->nsproxy->net_ns->ns.inum != initnet->ns.inum || > + old->user_ns->ns.inum != PROC_USER_INIT_INO || > + task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { > + if (new->uid.val < old->uid.val || new->gid.val < old->gid.val > + || new->cap_bset.cap[0] > old->cap_bset.cap[0]) > + return 0; > + } > + > kdebug("commit_creds(%p{%d,%d})", new, >atomic_read(>usage), >read_cred_subscribers(new)); > -- > 2.7.4 > > >
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180913] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180914-164803 config: ia64-allnoconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 8.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=8.1.0 make.cross ARCH=ia64 All errors (new ones prefixed by >>): kernel/cred.c: In function 'commit_creds': kernel/cred.c:439:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ kernel/cred.c:439:40: note: each undeclared identifier is reported only once for each function it appears in kernel/cred.c:440:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in this function) task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ kernel/cred.c:442:49: error: 'PROC_PID_INIT_INO' undeclared (first use in this function) task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ kernel/cred.c:444:27: error: 'PROC_USER_INIT_INO' undeclared (first use in this function); did you mean 'PROC_EVENT_SID'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^~ PROC_EVENT_SID >> kernel/cred.c:445:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first use in >> this function); did you mean 'BPF_CGROUP_INET6_BIND'? task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~~~ BPF_CGROUP_INET6_BIND vim +445 kernel/cred.c 415 416 /** 417 * commit_creds - Install new credentials upon the current task 418 * @new: The credentials to be assigned 419 * 420 * Install a new set of credentials to the current task, using RCU to replace 421 * the old set. Both the objective and the subjective credentials pointers are 422 * updated. This function may not be called if the subjective credentials are 423 * in an overridden state. 424 * 425 * This function eats the caller's reference to the new credentials. 426 * 427 * Always returns 0 thus allowing this function to be tail-called at the end 428 * of, say, sys_setgid(). 429 */ 430 int commit_creds(struct cred *new) 431 { 432 struct task_struct *task = current; 433 const struct cred *old = task->real_cred; 434 435 if (flag) { 436 initnet = get_net_ns_by_pid(1); 437 flag = false; 438 } 439 if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || 440 task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || 441 task->nsproxy->mnt_ns->ns.inum != 0xF000U || > 442 task->nsproxy->pid_ns_for_children->ns.inum != > PROC_PID_INIT_INO || 443 task->nsproxy->net_ns->ns.inum != initnet->ns.inum || 444 old->user_ns->ns.inum != PROC_USER_INIT_INO || > 445 task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { 446 if (new->uid.val < old->uid.val || new->gid.val < old->gid.val 447 || new->cap_bset.cap[0] > old->cap_bset.cap[0]) 448 return 0; 449 } 450 451 kdebug("commit_creds(%p{%d,%d})", new, 452 atomic_read(>usage), 453 read_cred_subscribers(new)); 454 455 BUG_ON(task->cred != old); 456 #ifdef CONFIG_DEBUG_CREDENTIALS 457 BUG_ON(read_cred_subscribers(old) < 2); 458 validate_creds(old); 459 validate_creds(new); 460 #endif 461 BUG_ON(atomic_read(>usage) < 1); 462 463 get_cred(new); /* we will require a ref for the subj creds too */ 464 465 /* dumpability changes */ 466 if (!uid_eq(old->euid, new->euid) || 467 !gid_eq(old->egid, new->egid) || 468 !uid_eq(old->fsuid, new->fsuid) || 469 !gid_eq(old->fsgid, new->fsgid) || 470 !cred_cap_issubset(old, new)) { 471 if (task->mm) 472 set_dumpable(task->mm, suid_dumpable); 473 task->pdeath_signal = 0; 474
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180913] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180914-164803 config: ia64-allnoconfig (attached as .config) compiler: ia64-linux-gcc (GCC) 8.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=8.1.0 make.cross ARCH=ia64 All errors (new ones prefixed by >>): kernel/cred.c: In function 'commit_creds': kernel/cred.c:439:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ kernel/cred.c:439:40: note: each undeclared identifier is reported only once for each function it appears in kernel/cred.c:440:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in this function) task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ kernel/cred.c:442:49: error: 'PROC_PID_INIT_INO' undeclared (first use in this function) task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ kernel/cred.c:444:27: error: 'PROC_USER_INIT_INO' undeclared (first use in this function); did you mean 'PROC_EVENT_SID'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^~ PROC_EVENT_SID >> kernel/cred.c:445:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first use in >> this function); did you mean 'BPF_CGROUP_INET6_BIND'? task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~~~ BPF_CGROUP_INET6_BIND vim +445 kernel/cred.c 415 416 /** 417 * commit_creds - Install new credentials upon the current task 418 * @new: The credentials to be assigned 419 * 420 * Install a new set of credentials to the current task, using RCU to replace 421 * the old set. Both the objective and the subjective credentials pointers are 422 * updated. This function may not be called if the subjective credentials are 423 * in an overridden state. 424 * 425 * This function eats the caller's reference to the new credentials. 426 * 427 * Always returns 0 thus allowing this function to be tail-called at the end 428 * of, say, sys_setgid(). 429 */ 430 int commit_creds(struct cred *new) 431 { 432 struct task_struct *task = current; 433 const struct cred *old = task->real_cred; 434 435 if (flag) { 436 initnet = get_net_ns_by_pid(1); 437 flag = false; 438 } 439 if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || 440 task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || 441 task->nsproxy->mnt_ns->ns.inum != 0xF000U || > 442 task->nsproxy->pid_ns_for_children->ns.inum != > PROC_PID_INIT_INO || 443 task->nsproxy->net_ns->ns.inum != initnet->ns.inum || 444 old->user_ns->ns.inum != PROC_USER_INIT_INO || > 445 task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { 446 if (new->uid.val < old->uid.val || new->gid.val < old->gid.val 447 || new->cap_bset.cap[0] > old->cap_bset.cap[0]) 448 return 0; 449 } 450 451 kdebug("commit_creds(%p{%d,%d})", new, 452 atomic_read(>usage), 453 read_cred_subscribers(new)); 454 455 BUG_ON(task->cred != old); 456 #ifdef CONFIG_DEBUG_CREDENTIALS 457 BUG_ON(read_cred_subscribers(old) < 2); 458 validate_creds(old); 459 validate_creds(new); 460 #endif 461 BUG_ON(atomic_read(>usage) < 1); 462 463 get_cred(new); /* we will require a ref for the subj creds too */ 464 465 /* dumpability changes */ 466 if (!uid_eq(old->euid, new->euid) || 467 !gid_eq(old->egid, new->egid) || 468 !uid_eq(old->fsuid, new->fsuid) || 469 !gid_eq(old->fsgid, new->fsgid) || 470 !cred_cap_issubset(old, new)) { 471 if (task->mm) 472 set_dumpable(task->mm, suid_dumpable); 473 task->pdeath_signal = 0; 474
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180910] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180911-135856 config: x86_64-randconfig-x019-201836 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): kernel/cred.c: In function 'commit_creds': >> kernel/cred.c:428:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in >> this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ kernel/cred.c:428:40: note: each undeclared identifier is reported only once for each function it appears in >> kernel/cred.c:429:23: error: dereferencing pointer to incomplete type >> 'struct ipc_namespace' task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^~ >> kernel/cred.c:429:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_UTS_INIT_INO'? task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ PROC_UTS_INIT_INO >> kernel/cred.c:430:23: error: dereferencing pointer to incomplete type >> 'struct mnt_namespace' task->nsproxy->mnt_ns->ns.inum != 0xF000U || ^~ >> kernel/cred.c:431:49: error: 'PROC_PID_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_IPC_INIT_INO'? task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ PROC_IPC_INIT_INO >> kernel/cred.c:433:27: error: 'PROC_USER_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_UTS_INIT_INO'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^~ PROC_UTS_INIT_INO >> kernel/cred.c:434:26: error: dereferencing pointer to incomplete type >> 'struct cgroup_namespace' task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~ >> kernel/cred.c:434:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_USER_INIT_INO'? task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~~~ PROC_USER_INIT_INO vim +/PROC_UTS_INIT_INO +428 kernel/cred.c 408 409 /** 410 * commit_creds - Install new credentials upon the current task 411 * @new: The credentials to be assigned 412 * 413 * Install a new set of credentials to the current task, using RCU to replace 414 * the old set. Both the objective and the subjective credentials pointers are 415 * updated. This function may not be called if the subjective credentials are 416 * in an overridden state. 417 * 418 * This function eats the caller's reference to the new credentials. 419 * 420 * Always returns 0 thus allowing this function to be tail-called at the end 421 * of, say, sys_setgid(). 422 */ 423 int commit_creds(struct cred *new) 424 { 425 struct task_struct *task = current; 426 const struct cred *old = task->real_cred; 427 > 428 if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || > 429 task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || > 430 task->nsproxy->mnt_ns->ns.inum != 0xF000U || > 431 task->nsproxy->pid_ns_for_children->ns.inum != > PROC_PID_INIT_INO || 432 task->nsproxy->net_ns->ns.inum != 0xF075U || > 433 old->user_ns->ns.inum != PROC_USER_INIT_INO || > 434 task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { 435 if (new->uid.val < old->uid.val || new->gid.val < old->gid.val 436 || new->cap_bset.cap[0] > old->cap_bset.cap[0]) 437 return 0; 438 } 439 440 kdebug("commit_creds(%p{%d,%d})", new, 441 atomic_read(>usage), 442 read_cred_subscribers(new)); 443 444 BUG_ON(task->cred != old); 445 #ifdef CONFIG_DEBUG_CREDENTIALS 446 BUG_ON(read_cred_subscribers(old) < 2); 447 validate_creds(old); 448 validate_creds(new); 449 #endif 450 BUG_ON(atomic_read(>usage) < 1); 451 452 get_cred(new); /* we will require a ref for the subj creds too
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.19-rc3 next-20180910] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180911-135856 config: x86_64-randconfig-x019-201836 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): kernel/cred.c: In function 'commit_creds': >> kernel/cred.c:428:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in >> this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ kernel/cred.c:428:40: note: each undeclared identifier is reported only once for each function it appears in >> kernel/cred.c:429:23: error: dereferencing pointer to incomplete type >> 'struct ipc_namespace' task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^~ >> kernel/cred.c:429:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_UTS_INIT_INO'? task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ PROC_UTS_INIT_INO >> kernel/cred.c:430:23: error: dereferencing pointer to incomplete type >> 'struct mnt_namespace' task->nsproxy->mnt_ns->ns.inum != 0xF000U || ^~ >> kernel/cred.c:431:49: error: 'PROC_PID_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_IPC_INIT_INO'? task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ PROC_IPC_INIT_INO >> kernel/cred.c:433:27: error: 'PROC_USER_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_UTS_INIT_INO'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^~ PROC_UTS_INIT_INO >> kernel/cred.c:434:26: error: dereferencing pointer to incomplete type >> 'struct cgroup_namespace' task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~ >> kernel/cred.c:434:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first use in >> this function); did you mean 'PROC_USER_INIT_INO'? task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^~~~ PROC_USER_INIT_INO vim +/PROC_UTS_INIT_INO +428 kernel/cred.c 408 409 /** 410 * commit_creds - Install new credentials upon the current task 411 * @new: The credentials to be assigned 412 * 413 * Install a new set of credentials to the current task, using RCU to replace 414 * the old set. Both the objective and the subjective credentials pointers are 415 * updated. This function may not be called if the subjective credentials are 416 * in an overridden state. 417 * 418 * This function eats the caller's reference to the new credentials. 419 * 420 * Always returns 0 thus allowing this function to be tail-called at the end 421 * of, say, sys_setgid(). 422 */ 423 int commit_creds(struct cred *new) 424 { 425 struct task_struct *task = current; 426 const struct cred *old = task->real_cred; 427 > 428 if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || > 429 task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || > 430 task->nsproxy->mnt_ns->ns.inum != 0xF000U || > 431 task->nsproxy->pid_ns_for_children->ns.inum != > PROC_PID_INIT_INO || 432 task->nsproxy->net_ns->ns.inum != 0xF075U || > 433 old->user_ns->ns.inum != PROC_USER_INIT_INO || > 434 task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { 435 if (new->uid.val < old->uid.val || new->gid.val < old->gid.val 436 || new->cap_bset.cap[0] > old->cap_bset.cap[0]) 437 return 0; 438 } 439 440 kdebug("commit_creds(%p{%d,%d})", new, 441 atomic_read(>usage), 442 read_cred_subscribers(new)); 443 444 BUG_ON(task->cred != old); 445 #ifdef CONFIG_DEBUG_CREDENTIALS 446 BUG_ON(read_cred_subscribers(old) < 2); 447 validate_creds(old); 448 validate_creds(new); 449 #endif 450 BUG_ON(atomic_read(>usage) < 1); 451 452 get_cred(new); /* we will require a ref for the subj creds too
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.19-rc3 next-20180910] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180911-135856 config: x86_64-randconfig-x009-201836 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/linux/init.h:5:0, from include/linux/cred.h:16, from kernel/cred.c:12: kernel/cred.c: In function 'commit_creds': kernel/cred.c:428:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:428:40: note: each undeclared identifier is reported only once for each function it appears in if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:429:23: error: dereferencing pointer to incomplete type 'struct ipc_namespace' task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:429:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in this function); did you mean 'PROC_UTS_INIT_INO'? task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:430:23: error: dereferencing pointer to incomplete type 'struct mnt_namespace' task->nsproxy->mnt_ns->ns.inum != 0xF000U || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:431:49: error: 'PROC_PID_INIT_INO' undeclared (first use in this function); did you mean 'PROC_IPC_INIT_INO'? task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:433:27: error: 'PROC_USER_INIT_INO' undeclared (first use in this function); did you mean 'PROC_UTS_INIT_INO'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:434:26: error: dereferencing pointer to incomplete type 'struct cgroup_namespace' task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:434:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first
Re: [PATCH] kernel: prevent submission of creds with higher privileges inside container
Hi Xin, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on linus/master] [also build test WARNING on v4.19-rc3 next-20180910] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/My-Name/kernel-prevent-submission-of-creds-with-higher-privileges-inside-container/20180911-135856 config: x86_64-randconfig-x009-201836 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): In file included from include/linux/init.h:5:0, from include/linux/cred.h:16, from kernel/cred.c:12: kernel/cred.c: In function 'commit_creds': kernel/cred.c:428:40: error: 'PROC_UTS_INIT_INO' undeclared (first use in this function) if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:428:40: note: each undeclared identifier is reported only once for each function it appears in if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:429:23: error: dereferencing pointer to incomplete type 'struct ipc_namespace' task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:429:36: error: 'PROC_IPC_INIT_INO' undeclared (first use in this function); did you mean 'PROC_UTS_INIT_INO'? task->nsproxy->ipc_ns->ns.inum != PROC_IPC_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:430:23: error: dereferencing pointer to incomplete type 'struct mnt_namespace' task->nsproxy->mnt_ns->ns.inum != 0xF000U || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:431:49: error: 'PROC_PID_INIT_INO' undeclared (first use in this function); did you mean 'PROC_IPC_INIT_INO'? task->nsproxy->pid_ns_for_children->ns.inum != PROC_PID_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:433:27: error: 'PROC_USER_INIT_INO' undeclared (first use in this function); did you mean 'PROC_UTS_INIT_INO'? old->user_ns->ns.inum != PROC_USER_INIT_INO || ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:434:26: error: dereferencing pointer to incomplete type 'struct cgroup_namespace' task->nsproxy->cgroup_ns->ns.inum != PROC_CGROUP_INIT_INO) { ^ include/linux/compiler.h:58:30: note: in definition of macro '__trace_if' if (__builtin_constant_p(!!(cond)) ? !!(cond) : \ ^~~~ >> kernel/cred.c:428:2: note: in expansion of macro 'if' if (task->nsproxy->uts_ns->ns.inum != PROC_UTS_INIT_INO || ^~ kernel/cred.c:434:39: error: 'PROC_CGROUP_INIT_INO' undeclared (first