From 389308f769748feeb69d8b6429a983f490bbe55d Mon Sep 17 00:00:00 2001 From: Steve Muir Date: Mon, 18 Apr 2005 17:58:17 +0000 Subject: [PATCH] Resurrect patches to support Proper --- fs/ioctl.c | 13 +++++++++++++ include/linux/vserver/inode.h | 7 +++++++ kernel/vserver/inode.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/fs/ioctl.c b/fs/ioctl.c index 19e902dc3..6af7a74c8 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -174,6 +174,19 @@ asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); break; #endif + case FIOC_SETIATTR: + case FIOC_GETIATTR: + /* + * Verify that this filp is a file object, + * not (say) a socket. + */ + error = -ENOTTY; + if (S_ISREG(filp->f_dentry->d_inode->i_mode) || + S_ISDIR(filp->f_dentry->d_inode->i_mode)) + error = vc_iattr_ioctl(filp->f_dentry, + cmd, arg); + break; + default: error = -ENOTTY; if (S_ISREG(filp->f_dentry->d_inode->i_mode)) diff --git a/include/linux/vserver/inode.h b/include/linux/vserver/inode.h index a1054e831..d9587f219 100644 --- a/include/linux/vserver/inode.h +++ b/include/linux/vserver/inode.h @@ -57,6 +57,10 @@ extern int vc_set_iattr_v0(uint32_t, void __user *); extern int vc_get_iattr(uint32_t, void __user *); extern int vc_set_iattr(uint32_t, void __user *); +extern int vc_iattr_ioctl(struct dentry *de, + unsigned int cmd, + unsigned long arg); + #endif /* __KERNEL__ */ /* inode ioctls */ @@ -64,6 +68,9 @@ extern int vc_set_iattr(uint32_t, void __user *); #define FIOC_GETXFLG _IOR('x', 5, long) #define FIOC_SETXFLG _IOW('x', 6, long) +#define FIOC_GETIATTR _IOR('x', 7, long) +#define FIOC_SETIATTR _IOR('x', 8, long) + #else /* _VX_INODE_H */ #warning duplicate inclusion #endif /* _VX_INODE_H */ diff --git a/kernel/vserver/inode.c b/kernel/vserver/inode.c index 8fdd30c62..ca16e0cd4 100644 --- a/kernel/vserver/inode.c +++ b/kernel/vserver/inode.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -188,6 +189,37 @@ int vc_set_iattr(uint32_t id, void __user *data) return ret; } +int vc_iattr_ioctl(struct dentry *de, unsigned int cmd, unsigned long arg) +{ + void __user *data = (void __user *)arg; + struct vcmd_ctx_iattr_v1 vc_data; + int ret; + + /* + * I don't think we need any dget/dput pairs in here as long as + * this function is always called from sys_ioctl i.e., de is + * a field of a struct file that is guaranteed not to be freed. + */ + if (cmd == FIOC_SETIATTR) { + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE)) + return -EPERM; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + ret = __vc_set_iattr(de, + &vc_data.xid, &vc_data.flags, &vc_data.mask); + } + else { + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + ret = __vc_get_iattr(de->d_inode, + &vc_data.xid, &vc_data.flags, &vc_data.mask); + } + + if (!ret && copy_to_user (data, &vc_data, sizeof(vc_data))) + ret = -EFAULT; + return ret; +} + #ifdef CONFIG_VSERVER_LEGACY -- 2.47.0