aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyrill Gorcunov <gorcunov@openvz.org>2012-07-30 17:43:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-30 20:25:21 -0400
commit1d151c337d79fa3de88654d2514f58fbd916a8e0 (patch)
tree79f96ea4b081f310aa62246e879224467b092261
parent65fed8f6f23070b56d0ed3841173ddd410130a89 (diff)
c/r: fcntl: add F_GETOWNER_UIDS option
When we restore file descriptors we would like them to look exactly as they were at dumping time. With help of fcntl it's almost possible, the missing snippet is file owners UIDs. To be able to read their values the F_GETOWNER_UIDS is introduced. This option is valid iif CONFIG_CHECKPOINT_RESTORE is turned on, otherwise returning -EINVAL. Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/fcntl.c29
-rw-r--r--include/asm-generic/fcntl.h4
-rw-r--r--security/selinux/hooks.c1
3 files changed, 34 insertions, 0 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 81b70e665bf0..887b5ba8c9b5 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -20,6 +20,7 @@
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/rcupdate.h> 21#include <linux/rcupdate.h>
22#include <linux/pid_namespace.h> 22#include <linux/pid_namespace.h>
23#include <linux/user_namespace.h>
23 24
24#include <asm/poll.h> 25#include <asm/poll.h>
25#include <asm/siginfo.h> 26#include <asm/siginfo.h>
@@ -340,6 +341,31 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
340 return ret; 341 return ret;
341} 342}
342 343
344#ifdef CONFIG_CHECKPOINT_RESTORE
345static int f_getowner_uids(struct file *filp, unsigned long arg)
346{
347 struct user_namespace *user_ns = current_user_ns();
348 uid_t * __user dst = (void * __user)arg;
349 uid_t src[2];
350 int err;
351
352 read_lock(&filp->f_owner.lock);
353 src[0] = from_kuid(user_ns, filp->f_owner.uid);
354 src[1] = from_kuid(user_ns, filp->f_owner.euid);
355 read_unlock(&filp->f_owner.lock);
356
357 err = put_user(src[0], &dst[0]);
358 err |= put_user(src[1], &dst[1]);
359
360 return err;
361}
362#else
363static int f_getowner_uids(struct file *filp, unsigned long arg)
364{
365 return -EINVAL;
366}
367#endif
368
343static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, 369static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
344 struct file *filp) 370 struct file *filp)
345{ 371{
@@ -396,6 +422,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
396 case F_SETOWN_EX: 422 case F_SETOWN_EX:
397 err = f_setown_ex(filp, arg); 423 err = f_setown_ex(filp, arg);
398 break; 424 break;
425 case F_GETOWNER_UIDS:
426 err = f_getowner_uids(filp, arg);
427 break;
399 case F_GETSIG: 428 case F_GETSIG:
400 err = filp->f_owner.signum; 429 err = filp->f_owner.signum;
401 break; 430 break;
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h
index 9e5b0356e2bb..a48937d4a5ea 100644
--- a/include/asm-generic/fcntl.h
+++ b/include/asm-generic/fcntl.h
@@ -120,6 +120,10 @@
120#define F_GETOWN_EX 16 120#define F_GETOWN_EX 16
121#endif 121#endif
122 122
123#ifndef F_GETOWNER_UIDS
124#define F_GETOWNER_UIDS 17
125#endif
126
123#define F_OWNER_TID 0 127#define F_OWNER_TID 0
124#define F_OWNER_PID 1 128#define F_OWNER_PID 1
125#define F_OWNER_PGRP 2 129#define F_OWNER_PGRP 2
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 94c45a1531a4..ec43760a8a03 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,
3180 case F_GETFL: 3180 case F_GETFL:
3181 case F_GETOWN: 3181 case F_GETOWN:
3182 case F_GETSIG: 3182 case F_GETSIG:
3183 case F_GETOWNER_UIDS:
3183 /* Just check FD__USE permission */ 3184 /* Just check FD__USE permission */
3184 err = file_has_perm(cred, file, 0); 3185 err = file_has_perm(cred, file, 0);
3185 break; 3186 break;