Commit 28b6394d authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] properly handle too long pathnames in d_path

Forward port of a 2.4 patch by Christoph Hellwig.

See http://cert.uni-stuttgart.de/archive/bugtraq/2002/03/msg00384.html
for the security implications.
parent 3b149cc7
...@@ -1147,21 +1147,24 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt, ...@@ -1147,21 +1147,24 @@ static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
namelen = dentry->d_name.len; namelen = dentry->d_name.len;
buflen -= namelen + 1; buflen -= namelen + 1;
if (buflen < 0) if (buflen < 0)
break; return ERR_PTR(-ENAMETOOLONG);
end -= namelen; end -= namelen;
memcpy(end, dentry->d_name.name, namelen); memcpy(end, dentry->d_name.name, namelen);
*--end = '/'; *--end = '/';
retval = end; retval = end;
dentry = parent; dentry = parent;
} }
return retval; return retval;
global_root: global_root:
namelen = dentry->d_name.len; namelen = dentry->d_name.len;
buflen -= namelen; buflen -= namelen;
if (buflen >= 0) { if (buflen >= 0) {
retval -= namelen-1; /* hit the slash */ retval -= namelen-1; /* hit the slash */
memcpy(retval, dentry->d_name.name, namelen); memcpy(retval, dentry->d_name.name, namelen);
} } else
retval = ERR_PTR(-ENAMETOOLONG);
return retval; return retval;
} }
...@@ -1229,6 +1232,10 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size) ...@@ -1229,6 +1232,10 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size)
cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
error = PTR_ERR(cwd);
if (IS_ERR(cwd))
goto out;
error = -ERANGE; error = -ERANGE;
len = PAGE_SIZE + page - cwd; len = PAGE_SIZE + page - cwd;
if (len <= size) { if (len <= size) {
...@@ -1238,6 +1245,8 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size) ...@@ -1238,6 +1245,8 @@ asmlinkage long sys_getcwd(char *buf, unsigned long size)
} }
} else } else
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
out:
dput(pwd); dput(pwd);
mntput(pwdmnt); mntput(pwdmnt);
dput(root); dput(root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment