From 30f11a80b583e0a29ed545027a6f973f8cc96ba8 Mon Sep 17 00:00:00 2001 From: Steve Muir Date: Thu, 18 Nov 2004 20:06:31 +0000 Subject: [PATCH] Need a way to manipulate vserver file attrs using a file descriptor --- fs/ioctl.c | 13 +++++++++++++ include/linux/vserver/inode.h | 9 ++++++++- kernel/vserver/inode.c | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index 96a1b601e..6404b0c10 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -173,6 +173,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 aa8852f43..e19632d08 100644 --- a/include/linux/vserver/inode.h +++ b/include/linux/vserver/inode.h @@ -39,7 +39,7 @@ struct vcmd_ctx_iattr_v1 { #define IATTR_IMMUTABLE 0x00040000 -#ifdef CONFIG_PROC_SECURE +#ifdef CONFIG_VSERVER_PROC_SECURE #define IATTR_PROC_DEFAULT ( IATTR_ADMIN | IATTR_HIDE ) #define IATTR_PROC_SYMLINK ( IATTR_ADMIN ) #else @@ -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,4 +68,7 @@ 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) + #endif /* _VX_INODE_H */ diff --git a/kernel/vserver/inode.c b/kernel/vserver/inode.c index 87e2849f3..d28749b91 100644 --- a/kernel/vserver/inode.c +++ b/kernel/vserver/inode.c @@ -10,7 +10,8 @@ */ #include -#include +#include +#include #include #include #include @@ -169,6 +170,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., the big + * kernel lock is held. + */ + 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 #include -- 2.47.0