(3/9) symlink patchkit (against -bk current)
Subsystems (4)
PATCH 1/1 (3/9) symlink patchkit (against -bk current)
trivial cases - ones where we have no need to clean up after
pathname traversal (link body embedded into inode, etc.). Plugged leak in devfs_follow_link(), while we are at it.
fs/autofs/symlink.c +3 -8
@@ -12,19 +12,14 @@#include "autofs_i.h" -static int autofs_readlink (struct dentry *dentry,char *buffer,int buflen) -{ -char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; -return vfs_readlink (dentry, buffer, buflen, s); -} -static int autofs_follow_link (struct dentry *dentry,struct nameidata *nd) {char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; -return vfs_follow_link (nd, s); +nd_set_link (nd, s); +return 0 ; }struct inode_operations autofs_symlink_inode_operations = { - .readlink = autofs_readlink, + .readlink = generic_readlink, .follow_link = autofs_follow_link };
fs/autofs4/symlink.c +3 -10
@@ -12,21 +12,14 @@#include "autofs_i.h" -static int autofs4_readlink (struct dentry *dentry,char *buffer,int buflen) -{ -struct autofs_info *ino =autofs4_dentry_ino (dentry); - -return vfs_readlink (dentry, buffer, buflen, ino->u.symlink); -} -static int autofs4_follow_link (struct dentry *dentry,struct nameidata *nd) {struct autofs_info *ino =autofs4_dentry_ino (dentry); - -return vfs_follow_link (nd, ino->u.symlink); +nd_set_link (nd, (char *)ino->u.symlink); +return 0 ; }struct inode_operations autofs4_symlink_inode_operations = { - .readlink = autofs4_readlink, + .readlink = generic_readlink, .follow_link = autofs4_follow_link };
fs/bad_inode.c +3 -1
@@ -13,6 +13,7 @@#include <linux/stat.h> #include <linux/time.h> #include <linux/smp_lock.h> +#include <linux/namei.h> /* * The follow_link operation is special: it must behave as a no-op
@@ -21,7 +22,8 @@*/ static int bad_follow_link (struct dentry *dent,struct nameidata *nd) { -return vfs_follow_link (nd,ERR_PTR (-EIO )); +nd_set_link (nd,ERR_PTR (-EIO )); +return 0 ; }static int return_EIO (void )
fs/devfs/base.c +4 -22
@@ -2490,29 +2490,11 @@return 0 ; }/* End Function devfs_mknod */ -static int devfs_readlink (struct dentry *dentry,char __user *buffer, -int buflen) -{ -int err; -struct devfs_entry *de; - - de =get_devfs_entry_from_vfs_inode (dentry->d_inode); -if (!de) -return -ENODEV ; - err =vfs_readlink (dentry, buffer, buflen, de->u.symlink.linkname); -return err; -}/* End Function devfs_readlink */ -static int devfs_follow_link (struct dentry *dentry,struct nameidata *nd) { -int err; -struct devfs_entry *de; - - de =get_devfs_entry_from_vfs_inode (dentry->d_inode); -if (!de) -return -ENODEV ; - err =vfs_follow_link (nd, de->u.symlink.linkname); -return err; +struct devfs_entry *p =get_devfs_entry_from_vfs_inode (dentry->d_inode); +nd_set_link (nd, p ? p->u.symlink.linkname :ERR_PTR (-ENODEV )); +return 0 ; }/* End Function devfs_follow_link */ static struct inode_operations devfs_iops = {
@@ -2530,7 +2512,7 @@ };static struct inode_operations devfs_symlink_iops = { - .readlink = devfs_readlink, + .readlink = generic_readlink, .follow_link = devfs_follow_link, .setattr = devfs_notify_change, };
fs/freevxfs/vxfs_immed.c +4 -26
@@ -32,12 +32,12 @@*/ #include <linux/fs.h> #include <linux/pagemap.h> +#include <linux/namei.h> #include "vxfs.h" #include "vxfs_inode.h" -static int vxfs_immed_readlink (struct dentry *,char __user *,int );static int vxfs_immed_follow_link (struct dentry *,struct nameidata *);static int vxfs_immed_readpage (struct file *,struct page *);
@@ -49,7 +49,7 @@* but do all work directly on the inode. */ struct inode_operations vxfs_immed_symlink_iops = { - .readlink = vxfs_immed_readlink, + .readlink = generic_readlink, .follow_link = vxfs_immed_follow_link, };
@@ -60,28 +60,6 @@ .readpage = vxfs_immed_readpage, }; - -/** -* vxfs_immed_readlink - read immed symlink -* @dp: dentry for the link -* @bp: output buffer -* @buflen: length of @bp -* -* Description: -* vxfs_immed_readlink calls vfs_readlink to read the link -* described by @dp into userspace. -* -* Returns: -* Number of bytes successfully copied to userspace. -*/ -static int -vxfs_immed_readlink (struct dentry *dp,char __user *bp,int buflen) -{ -struct vxfs_inode_info *vip =VXFS_INO (dp->d_inode); - -return (vfs_readlink (dp, bp, buflen, vip->vii_immed.vi_immed)); -} -/** * vxfs_immed_follow_link - follow immed symlink * @dp: dentry for the link
@@ -98,8 +76,8 @@ vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) { struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); - -return (vfs_follow_link (np, vip->vii_immed.vi_immed)); +nd_set_link (np, vip->vii_immed.vi_immed); +return 0 ; }/**
fs/jfs/symlink.c +4 -8
@@ -17,23 +17,19 @@*/ #include <linux/fs.h> +#include <linux/namei.h> #include "jfs_incore.h" #include "jfs_xattr.h" static int jfs_follow_link (struct dentry *dentry,struct nameidata *nd) {char *s =JFS_IP (dentry->d_inode)->i_inline; -return vfs_follow_link (nd, s); -} - -static int jfs_readlink (struct dentry *dentry,char __user *buffer,int buflen) -{ -char *s =JFS_IP (dentry->d_inode)->i_inline; -return vfs_readlink (dentry, buffer, buflen, s); +nd_set_link (nd, s); +return 0 ; }struct inode_operations jfs_symlink_inode_operations = { - .readlink = jfs_readlink, + .readlink = generic_readlink, .follow_link = jfs_follow_link, .setxattr = jfs_setxattr, .getxattr = jfs_getxattr,
fs/proc/generic.c +4 -10
@@ -17,6 +17,7 @@#include <linux/smp_lock.h> #include <linux/init.h> #include <linux/idr.h> +#include <linux/namei.h> #include <asm/uaccess.h> #include <asm/bitops.h>
@@ -321,21 +322,14 @@spin_unlock (&proc_inum_lock); } -static int -proc_readlink (struct dentry *dentry,char __user *buffer,int buflen) -{ -char *s =PDE (dentry->d_inode)->data; -return vfs_readlink (dentry, buffer, buflen, s); -} -static int proc_follow_link (struct dentry *dentry,struct nameidata *nd) { -char *s =PDE (dentry->d_inode)->data; -return vfs_follow_link (nd, s); +nd_set_link (nd,PDE (dentry->d_inode)->data); +return 0 ; }static struct inode_operations proc_link_inode_operations = { - .readlink = proc_readlink, + .readlink = generic_readlink, .follow_link = proc_follow_link, };
fs/sysv/symlink.c +4 -9
@@ -6,20 +6,15 @@*/ #include "sysv.h" - -static int sysv_readlink (struct dentry *dentry,char *buffer,int buflen) -{ -char *s = (char *)SYSV_I (dentry->d_inode)->i_data; -return vfs_readlink (dentry, buffer, buflen, s); -} +#include <linux/namei.h> static int sysv_follow_link (struct dentry *dentry,struct nameidata *nd) { -char *s = (char *)SYSV_I (dentry->d_inode)->i_data; -return vfs_follow_link (nd, s); +nd_set_link (nd, (char *)SYSV_I (dentry->d_inode)->i_data); +return 0 ; }struct inode_operations sysv_fast_symlink_inode_operations = { - .readlink = sysv_readlink, + .readlink = generic_readlink, .follow_link = sysv_follow_link, };
fs/ufs/symlink.c +4 -8
@@ -26,21 +26,17 @@*/ #include <linux/fs.h> +#include <linux/namei.h> #include <linux/ufs_fs.h> -static int ufs_readlink (struct dentry *dentry,char *buffer,int buflen) -{ -struct ufs_inode_info *p =UFS_I (dentry->d_inode); -return vfs_readlink (dentry, buffer, buflen, (char *)p->i_u1.i_symlink); -} -static int ufs_follow_link (struct dentry *dentry,struct nameidata *nd) {struct ufs_inode_info *p =UFS_I (dentry->d_inode); -return vfs_follow_link (nd, (char *)p->i_u1.i_symlink); +nd_set_link (nd, (char *)p->i_u1.i_symlink); +return 0 ; }struct inode_operations ufs_fast_symlink_inode_operations = { - .readlink = ufs_readlink, + .readlink = generic_readlink, .follow_link = ufs_follow_link, };