patch-2.3.31 linux/fs/ncpfs/symlink.c
Next file: linux/fs/nfs/inode.c
Previous file: linux/fs/ncpfs/ncplib_kernel.h
Back to the patch index
Back to the overall index
- Lines: 144
- Date:
Tue Dec 7 10:21:10 1999
- Orig file:
v2.3.30/linux/fs/ncpfs/symlink.c
- Orig date:
Tue Dec 7 09:32:48 1999
diff -u --recursive --new-file v2.3.30/linux/fs/ncpfs/symlink.c linux/fs/ncpfs/symlink.c
@@ -74,8 +74,8 @@
unsigned int follow)
{
struct inode *inode=dentry->d_inode;
- int error, length, cnt;
- char *link;
+ int error, length, len, cnt;
+ char *link, *buf;
#ifdef DEBUG
PRINTK("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow);
@@ -91,7 +91,7 @@
return ERR_PTR(-EIO);
}
- for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1, GFP_NFS))==NULL; cnt++) {
+ for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) {
if (cnt > 10) {
dput(base);
return ERR_PTR(-EAGAIN); /* -ENOMEM? */
@@ -108,14 +108,25 @@
kfree(link);
return ERR_PTR(-EIO);
}
-
- link[length]=0;
- vol2io(NCP_SERVER(inode), link+8, 0);
+ len = NCP_MAX_SYMLINK_SIZE;
+ buf = (char *) kmalloc(len, GFP_NFS);
+ if (!buf) {
+ dput(base);
+ kfree(link);
+ return ERR_PTR(-EAGAIN);
+ }
+ error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0);
+ kfree(link);
+ if (error) {
+ dput(base);
+ kfree(buf);
+ return ERR_PTR(error);
+ }
/* UPDATE_ATIME(inode); */
- base=lookup_dentry(link+8, base, follow);
- kfree(link);
+ base = lookup_dentry(buf, base, follow);
+ kfree(buf);
return base;
}
@@ -125,8 +136,8 @@
static int ncp_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *inode=dentry->d_inode;
- char *link;
- int length,error;
+ char *link, *buf;
+ int length, len, error;
#ifdef DEBUG
PRINTK("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen);
@@ -138,7 +149,7 @@
if(ncp_make_open(inode,O_RDONLY))
return -EIO;
- if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1,GFP_NFS))==NULL)
+ if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE,GFP_NFS))==NULL)
return -ENOMEM;
error = ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle,
@@ -150,15 +161,25 @@
goto out;
}
- link[length] = 0;
+ len = NCP_MAX_SYMLINK_SIZE;
+ buf = (char *) kmalloc(len, GFP_NFS);
+ if (!buf) {
+ error = -ENOMEM;
+ goto out;
+ }
+ error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0);
+ if (error || buflen < len) {
+ error = -EIO;
+ kfree(buf);
+ goto out;
+ }
- vol2io(NCP_SERVER(inode), link+8, 0);
-
- error = length - 8;
- if(copy_to_user(buffer, link+8, error))
+ error = len;
+ if(copy_to_user(buffer, buf, error))
error = -EFAULT;
-
-out:;
+ kfree(buf);
+
+out:
kfree(link);
return error;
}
@@ -166,9 +187,9 @@
/* ----- create a new symbolic link -------------------------------------- */
int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) {
- int i,length;
struct inode *inode;
char *link;
+ int length, err, i;
#ifdef DEBUG
PRINTK("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname);
@@ -177,7 +198,7 @@
if (!(NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS))
return -EPERM; /* EPERM is returned by VFS if symlink procedure does not exist */
- if ((length=strlen(symname))>NCP_MAX_SYMLINK_SIZE)
+ if ((length=strlen(symname))>NCP_MAX_SYMLINK_SIZE-8)
return -EINVAL;
if ((link=(char *)kmalloc(length+9,GFP_NFS))==NULL)
@@ -192,12 +213,16 @@
((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0;
((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1;
- memcpy(link+8, symname, length+1); /* including last zero for io2vol */
/* map to/from server charset, do not touch upper/lower case as
symlink can point out of ncp filesystem */
- io2vol(NCP_SERVER(inode), link+8, 0);
-
+ length += 1;
+ err = ncp_io2vol(NCP_SERVER(inode),link+8,&length,symname,length-1,0);
+ if (err) {
+ kfree(link);
+ return err;
+ }
+
if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
0, length+8, link, &i) || i!=length+8) {
kfree(link);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)