aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fcntl.c
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 /fs/fcntl.c
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>
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r--fs/fcntl.c29
1 files changed, 29 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;