return symname;
}
---- static void ll_put_link(struct inode *unused, void *cookie)
---- {
---- ptlrpc_req_finished(cookie);
---- }
----
----struct inode_operations ll_fast_symlink_inode_operations = {
++++const struct inode_operations ll_fast_symlink_inode_operations = {
.readlink = generic_readlink,
.setattr = ll_setattr,
---- .follow_link = ll_follow_link,
---- .put_link = ll_put_link,
++++ .get_link = ll_get_link,
.getattr = ll_getattr,
.permission = ll_inode_permission,
.setxattr = ll_setxattr,
#include <asm/fbio.h>
#endif
----static int w_long(unsigned int fd, unsigned int cmd,
---- compat_ulong_t __user *argp)
++++#define convert_in_user(srcptr, dstptr) \
++++({ \
++++ typeof(*srcptr) val; \
++++ \
++++ get_user(val, srcptr) || put_user(val, dstptr); \
++++})
++++
++++static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
- -- mm_segment_t old_fs = get_fs();
+ int err;
- -- unsigned long val;
+
- -- set_fs (KERNEL_DS);
- -- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- -- set_fs (old_fs);
- -- if (!err && put_user(val, argp))
++++ err = security_file_ioctl(file, cmd, arg);
++++ if (err)
++++ return err;
++++
++++ return vfs_ioctl(file, cmd, arg);
++++}
++++
++++static int w_long(struct file *file,
++++ unsigned int cmd, compat_ulong_t __user *argp)
+ ++{
- mm_segment_t old_fs = get_fs();
+ ++ int err;
- unsigned long val;
++++ unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp));
+ ++
- set_fs (KERNEL_DS);
- err = sys_ioctl(fd, cmd, (unsigned long)&val);
- set_fs (old_fs);
- if (!err && put_user(val, argp))
++++ if (valp == NULL)
return -EFAULT;
---- return err;
++++ err = do_ioctl(file, cmd, (unsigned long)valp);
++++ if (err)
++++ return err;
++++ if (convert_in_user(valp, argp))
++++ return -EFAULT;
++++ return 0;
}
struct compat_video_event {
{
typedef struct serial_struct32 SS32;
int err;
---- struct serial_struct ss;
---- mm_segment_t oldseg = get_fs();
++++ struct serial_struct __user *ss = compat_alloc_user_space(sizeof(*ss));
__u32 udata;
unsigned int base;
++++ unsigned char *iomem_base;
++++ if (ss == NULL)
++++ return -EFAULT;
if (cmd == TIOCSSERIAL) {
---- if (!access_ok(VERIFY_READ, ss32, sizeof(SS32)))
---- return -EFAULT;
---- if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
- -- return -EFAULT;
- -- if (__get_user(udata, &ss32->iomem_base))
++++ if (copy_in_user(ss, ss32, offsetof(SS32, iomem_base)) ||
++++ get_user(udata, &ss32->iomem_base))
return -EFAULT;
- -- ss.iomem_base = compat_ptr(udata);
- -- if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
- -- __get_user(ss.port_high, &ss32->port_high))
- if (__get_user(udata, &ss32->iomem_base))
++++ iomem_base = compat_ptr(udata);
++++ if (put_user(iomem_base, &ss->iomem_base) ||
++++ convert_in_user(&ss32->iomem_reg_shift,
++++ &ss->iomem_reg_shift) ||
++++ convert_in_user(&ss32->port_high, &ss->port_high) ||
++++ put_user(0UL, &ss->iomap_base))
return -EFAULT;
- ss.iomem_base = compat_ptr(udata);
- if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
- __get_user(ss.port_high, &ss32->port_high))
- return -EFAULT;
---- ss.iomap_base = 0UL;
}
---- set_fs(KERNEL_DS);
---- err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
---- set_fs(oldseg);
++++ err = do_ioctl(file, cmd, (unsigned long)ss);
if (cmd == TIOCGSERIAL && err >= 0) {
---- if (!access_ok(VERIFY_WRITE, ss32, sizeof(SS32)))
---- return -EFAULT;
---- if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
++++ if (copy_in_user(ss32, ss, offsetof(SS32, iomem_base)) ||
++++ get_user(iomem_base, &ss->iomem_base))
return -EFAULT;
---- base = (unsigned long)ss.iomem_base >> 32 ?
---- 0xffffffff : (unsigned)(unsigned long)ss.iomem_base;
---- if (__put_user(base, &ss32->iomem_base) ||
---- __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
---- __put_user(ss.port_high, &ss32->port_high))
++++ base = (unsigned long)iomem_base >> 32 ?
++++ 0xffffffff : (unsigned)(unsigned long)iomem_base;
++++ if (put_user(base, &ss32->iomem_base) ||
++++ convert_in_user(&ss->iomem_reg_shift,
++++ &ss32->iomem_reg_shift) ||
++++ convert_in_user(&ss->port_high, &ss32->port_high))
return -EFAULT;
}
return err;
nd->path.dentry = path->dentry;
}
++++static int nd_jump_root(struct nameidata *nd)
++++{
++++ if (nd->flags & LOOKUP_RCU) {
++++ struct dentry *d;
++++ nd->path = nd->root;
++++ d = nd->path.dentry;
++++ nd->inode = d->d_inode;
++++ nd->seq = nd->root_seq;
++++ if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
++++ return -ECHILD;
++++ } else {
++++ path_put(&nd->path);
++++ nd->path = nd->root;
++++ path_get(&nd->path);
++++ nd->inode = nd->path.dentry->d_inode;
++++ }
++++ nd->flags |= LOOKUP_JUMPED;
++++ return 0;
++++}
++++
/*
---- * Helper to directly jump to a known parsed path from ->follow_link,
++++ * Helper to directly jump to a known parsed path from ->get_link,
* caller must have taken a reference to path beforehand.
*/
void nd_jump_link(struct path *path)
nd->last_type = LAST_BIND;
res = inode->i_link;
if (!res) {
++++ const char * (*get)(struct dentry *, struct inode *,
++++ struct delayed_call *);
++++ get = inode->i_op->get_link;
if (nd->flags & LOOKUP_RCU) {
---- if (unlikely(unlazy_walk(nd, NULL, 0)))
---- return ERR_PTR(-ECHILD);
++++ res = get(NULL, inode, &last->done);
++++ if (res == ERR_PTR(-ECHILD)) {
++++ if (unlikely(unlazy_walk(nd, NULL, 0)))
++++ return ERR_PTR(-ECHILD);
++++ res = get(dentry, inode, &last->done);
++++ }
++++ } else {
++++ res = get(dentry, inode, &last->done);
}
---- res = inode->i_op->follow_link(dentry, &last->cookie);
---- if (IS_ERR_OR_NULL(res)) {
---- last->cookie = NULL;
++++ if (IS_ERR_OR_NULL(res))
return res;
---- }
}
if (*res == '/') {
---- if (nd->flags & LOOKUP_RCU) {
---- struct dentry *d;
---- if (!nd->root.mnt)
---- set_root_rcu(nd);
---- nd->path = nd->root;
---- d = nd->path.dentry;
---- nd->inode = d->d_inode;
---- nd->seq = nd->root_seq;
---- if (unlikely(read_seqcount_retry(&d->d_seq, nd->seq)))
---- return ERR_PTR(-ECHILD);
---- } else {
---- if (!nd->root.mnt)
---- set_root(nd);
---- path_put(&nd->path);
---- nd->path = nd->root;
---- path_get(&nd->root);
---- nd->inode = nd->path.dentry->d_inode;
---- }
---- nd->flags |= LOOKUP_JUMPED;
++++ if (!nd->root.mnt)
++++ set_root(nd);
++++ if (unlikely(nd_jump_root(nd)))
++++ return ERR_PTR(-ECHILD);
while (unlikely(*++res == '/'))
;
}
static const struct inode_operations shmem_short_symlink_operations = {
.readlink = generic_readlink,
---- .follow_link = simple_follow_link,
++++ .get_link = simple_get_link,
#ifdef CONFIG_TMPFS_XATTR
--- - .setxattr = shmem_setxattr,
--- - .getxattr = shmem_getxattr,
+++ + .setxattr = generic_setxattr,
+++ + .getxattr = generic_getxattr,
.listxattr = shmem_listxattr,
--- - .removexattr = shmem_removexattr,
+++ + .removexattr = generic_removexattr,
#endif
};
static const struct inode_operations shmem_symlink_inode_operations = {
.readlink = generic_readlink,
---- .follow_link = shmem_follow_link,
---- .put_link = shmem_put_link,
++++ .get_link = shmem_get_link,
#ifdef CONFIG_TMPFS_XATTR
--- - .setxattr = shmem_setxattr,
--- - .getxattr = shmem_getxattr,
+++ + .setxattr = generic_setxattr,
+++ + .getxattr = generic_getxattr,
.listxattr = shmem_listxattr,
--- - .removexattr = shmem_removexattr,
+++ + .removexattr = generic_removexattr,
#endif
};