diff options
| -rw-r--r-- | fs/fcntl.c | 29 | ||||
| -rw-r--r-- | include/asm-generic/fcntl.h | 4 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 1 | 
3 files changed, 34 insertions, 0 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c index 81b70e665bf..887b5ba8c9b 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -20,6 +20,7 @@  #include <linux/signal.h>  #include <linux/rcupdate.h>  #include <linux/pid_namespace.h> +#include <linux/user_namespace.h>  #include <asm/poll.h>  #include <asm/siginfo.h> @@ -340,6 +341,31 @@ static int f_getown_ex(struct file *filp, unsigned long arg)  	return ret;  } +#ifdef CONFIG_CHECKPOINT_RESTORE +static int f_getowner_uids(struct file *filp, unsigned long arg) +{ +	struct user_namespace *user_ns = current_user_ns(); +	uid_t * __user dst = (void * __user)arg; +	uid_t src[2]; +	int err; + +	read_lock(&filp->f_owner.lock); +	src[0] = from_kuid(user_ns, filp->f_owner.uid); +	src[1] = from_kuid(user_ns, filp->f_owner.euid); +	read_unlock(&filp->f_owner.lock); + +	err  = put_user(src[0], &dst[0]); +	err |= put_user(src[1], &dst[1]); + +	return err; +} +#else +static int f_getowner_uids(struct file *filp, unsigned long arg) +{ +	return -EINVAL; +} +#endif +  static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,  		struct file *filp)  { @@ -396,6 +422,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,  	case F_SETOWN_EX:  		err = f_setown_ex(filp, arg);  		break; +	case F_GETOWNER_UIDS: +		err = f_getowner_uids(filp, arg); +		break;  	case F_GETSIG:  		err = filp->f_owner.signum;  		break; diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h index 9e5b0356e2b..a48937d4a5e 100644 --- a/include/asm-generic/fcntl.h +++ b/include/asm-generic/fcntl.h @@ -120,6 +120,10 @@  #define F_GETOWN_EX	16  #endif +#ifndef F_GETOWNER_UIDS +#define F_GETOWNER_UIDS	17 +#endif +  #define F_OWNER_TID	0  #define F_OWNER_PID	1  #define F_OWNER_PGRP	2 diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 94c45a1531a..ec43760a8a0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3180,6 +3180,7 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,  	case F_GETFL:  	case F_GETOWN:  	case F_GETSIG: +	case F_GETOWNER_UIDS:  		/* Just check FD__USE permission */  		err = file_has_perm(cred, file, 0);  		break;  |