sys_chdir and sys_fchdir changes.
Signed-off-by: Jaroslav Sykora <jaroslav.sykora@gmail.com>
fs/open.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 73 insertions(+), 6 deletions(-)
--- orig/fs/open.c 2007-10-07 19:00:19.000000000 +0200
+++ new/fs/open.c 2007-10-16 21:04:56.000000000 +0200
@@ -476,13 +476,51 @@ asmlinkage long sys_access(const char __
return sys_faccessat(AT_FDCWD, filename, mode);
}
+static inline int read_fs_flags(void)
+{
+ int res;
+ read_lock(¤t->fs->lock);
+ res = current->fs->flags;
+ read_unlock(¤t->fs->lock);
+ return res;
+}
+
+void set_fs_shdwpwd(struct fs_struct *fs,
+ struct vfsmount *mnt, struct dentry *dentry)
+{
+ struct dentry *old_dentry;
+ struct vfsmount *old_mnt;
+
+ BUG_ON(dentry != NULL && mnt == NULL);
+ write_lock(&fs->lock);
+ /* set shadow pwd */
+ old_dentry = fs->shdwpwd;
+ old_mnt = fs->shdwpwdmnt;
+ fs->shdwpwd = dget(dentry);
+ if (dentry)
+ fs->shdwpwdmnt = mntget(mnt);
+ else
+ /* PTR_ERR flag */
+ fs->shdwpwdmnt = mnt;
+ write_unlock(&fs->lock);
+
+ if (old_dentry) {
+ mntput(old_mnt);
+ dput(old_dentry);
+ }
+}
+
asmlinkage long sys_chdir(const char __user * filename)
{
struct nameidata nd;
- int error;
+ char *tmp = getname(filename);
+ int error = PTR_ERR(tmp);;
+
+ if (IS_ERR(tmp))
+ goto out_badname;
- error = __user_walk(filename,
- LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
+ error = path_lookup(tmp, LOOKUP_FOLLOW | LOOKUP_DIRECTORY
+ | LOOKUP_CHDIR, &nd);
if (error)
goto out;
@@ -490,11 +528,23 @@ asmlinkage long sys_chdir(const char __u
if (error)
goto dput_and_out;
- set_fs_pwd(current->fs, nd.mnt, nd.dentry);
+ if (!(read_fs_flags() & SHDW_ENABLED))
+ goto set_std;
+ if (!(nd.flags & LOOKUP_INSHDW))
+ set_fs_shdwpwd(current->fs, NULL, NULL);
+ else
+ /* shadow == std */
+ set_fs_shdwpwd(current->fs, nd.mnt, nd.dentry);
+
+set_std:
+ /* set std cwd */
+ set_fs_pwd(current->fs, nd.mnt, nd.dentry);
dput_and_out:
path_release(&nd);
out:
+ putname(tmp);
+out_badname:
return error;
}
@@ -520,8 +570,25 @@ asmlinkage long sys_fchdir(unsigned int
goto out_putf;
error = file_permission(file, MAY_EXEC);
- if (!error)
- set_fs_pwd(current->fs, mnt, dentry);
+ if (error)
+ goto out_putf;
+
+ set_fs_pwd(current->fs, mnt, dentry);
+
+ if (!(read_fs_flags() & SHDW_ENABLED))
+ /* shadow dirs aren't enabled */
+ goto out_putf;
+
+ if (get_file_shdwdir(file, &dentry, &mnt))
+ /* some error ocured */
+ set_fs_shdwpwd(current->fs, NULL, NULL);
+ else {
+ /* ok */
+ set_fs_shdwpwd(current->fs, mnt, dentry);
+ mntput(mnt);
+ dput(dentry);
+ }
+
out_putf:
fput(file);
out:
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
| Linus Torvalds | Linux 2.6.27-rc8 |
| Jared Hulbert | [PATCH 00/10] AXFS: Advanced XIP filesystem |
| Eric Paris | Re: [malware-list] [RFC 0/5] [TALPA] Intro to a linux interface for on access scan... |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
git: | |
| Jakub Narebski | Re: VCS comparison table |
| Junio C Hamano | Re: [PATCH 0/2] Making "git commit" to mean "git commit -a". |
| Toby White | Using Filemerge.app as a git-diff viewer |
| Ismail | Re: [ANNOUNCE] GIT 1.5.3-rc4 |
| Leon Dippenaar | New tcp stack attack |
| Richard Stallman | Real men don't attack straw men |
| Predrag Punosevac | Skype on the OpenBSD |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Hugh Dickins | Re: [bug?] tg3: Failed to load firmware "tigon/tg3_tso.bin" |
| Jarek Poplawski | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Jon Smirl | e1000 tcp checksum incorrect, x86 64b |
| David Miller | [GIT]: Networking |
