|
@@ -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;
|