diff options
Diffstat (limited to 'fs/fcntl.c')
-rw-r--r-- | fs/fcntl.c | 29 |
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 | ||
345 | static 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 | ||
363 | static int f_getowner_uids(struct file *filp, unsigned long arg) | ||
364 | { | ||
365 | return -EINVAL; | ||
366 | } | ||
367 | #endif | ||
368 | |||
343 | static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, | 369 | static 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; |