- d_path path fix

-  remove use of fgetattr
-  fix named transitions
This commit is contained in:
John Johansen 2008-04-24 17:31:08 +00:00
parent cbdea9c7c2
commit fe9ae3968b
4 changed files with 157 additions and 16 deletions

View file

@ -0,0 +1,114 @@
From: John Johansen <jjohansen@suse.de>
Subject: Fix __d_path to allow for old and new behavior bnc#380763
Fix __d_path so that it can be told whether or not to connect
disconnect path to the root. This is easier and more efficient
than trying to reconnect these paths for d_path and get_cwd
after the fact.
Signed-off-by: John Johansen <jjohansen@suse.de>
---
fs/dcache.c | 25 +++++++------------------
fs/namespace.c | 2 +-
include/linux/dcache.h | 2 +-
3 files changed, 9 insertions(+), 20 deletions(-)
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1772,6 +1772,7 @@ shouldnt_be_hashed:
* @buffer: buffer to return value in
* @buflen: buffer length
* @fail_deleted: what to return for deleted files
+ * @disconnect: don't return a path starting with / when disconnected
*
* Convert a dentry into an ASCII path name. If the entry has been deleted,
* then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
@@ -1784,7 +1785,7 @@ shouldnt_be_hashed:
*/
char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
struct dentry *root, struct vfsmount *rootmnt,
- char *buffer, int buflen, int fail_deleted)
+ char *buffer, int buflen, int fail_deleted, int disconnect)
{
int namelen, is_slash, vfsmount_locked = 0;
@@ -1848,7 +1849,7 @@ global_root:
*/
namelen = dentry->d_name.len;
is_slash = (namelen == 1 && *dentry->d_name.name == '/');
- if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
+ if (disconnect && (is_slash || (dentry->d_sb->s_flags & MS_NOUSER))) {
/*
* Make sure we won't return a pathname starting with '/'.
*
@@ -1863,6 +1864,8 @@ global_root:
}
if (is_slash)
goto out;
+ } else if (is_slash && *buffer == '/') {
+ goto out;
}
if (buflen < namelen)
goto Elong;
@@ -1875,18 +1878,6 @@ Elong:
goto out;
}
-static char *__connect_d_path(char *path, char *buffer)
-{
- if (!IS_ERR(path) && *path != '/') {
- /* Pretend that disconnected paths are hanging off the root. */
- if (path == buffer)
- path = ERR_PTR(-ENAMETOOLONG);
- else
- *--path = '/';
- }
- return path;
-}
-
/* write full pathname into buffer and return start of pathname */
char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
int buflen)
@@ -1909,8 +1900,7 @@ char *d_path(struct dentry *dentry, stru
rootmnt = mntget(current->fs->rootmnt);
root = dget(current->fs->root);
read_unlock(&current->fs->lock);
- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0);
- res = __connect_d_path(res, buf);
+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0, 0);
dput(root);
mntput(rootmnt);
return res;
@@ -1972,8 +1962,7 @@ asmlinkage long sys_getcwd(char __user *
root = dget(current->fs->root);
read_unlock(&current->fs->lock);
- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
- cwd = __connect_d_path(cwd, page);
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1, 0);
error = PTR_ERR(cwd);
if (IS_ERR(cwd))
goto out;
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1901,7 +1901,7 @@ char *d_namespace_path(struct dentry *de
mntput(rootmnt);
if (nsrootmnt)
root = dget(nsrootmnt->mnt_root);
- res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1);
+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1, 1);
dput(root);
mntput(nsrootmnt);
/* Prevent empty path for lazily unmounted filesystems. */
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -301,7 +301,7 @@ extern int d_validate(struct dentry *, s
extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *__d_path(struct dentry *, struct vfsmount *, struct dentry *,
- struct vfsmount *, char *, int, int);
+ struct vfsmount *, char *, int, int, int);
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
/* Allocation counts.. */

View file

@ -0,0 +1,26 @@
---
security/apparmor/main.c | 2 +-
security/apparmor/module_interface.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -1119,7 +1119,7 @@ aa_x_to_profile(struct aa_profile *profi
default:
/* all other indexes are named transitions */
index = AA_EXEC_INDEX(xmode);
- if (index - 4 > profile->exec_table_size) {
+ if (index - 4 >= profile->exec_table_size) {
sa->info = "invalid named transition - exec failed";
sa->error_code = -EACCES;
new_profile = ERR_PTR(-EACCES);
--- a/security/apparmor/module_interface.c
+++ b/security/apparmor/module_interface.c
@@ -319,6 +319,7 @@ static int aa_unpack_exec_table(struct a
goto fail;
if (!aa_is_nameX(e, AA_STRUCTEND, NULL))
goto fail;
+ profile->exec_table_size = size;
}
return 1;

View file

@ -146,7 +146,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
EXPORT_SYMBOL(notify_change);
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1032,21 +1032,22 @@ static int fuse_dir_fsync(struct file *f
@@ -1063,21 +1063,22 @@ static int fuse_dir_fsync(struct file *f
return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
}
@ -172,7 +172,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
{
unsigned ivalid = iattr->ia_valid;
@@ -1065,7 +1066,7 @@ static void iattr_to_fattr(struct iattr
@@ -1096,7 +1097,7 @@ static void iattr_to_fattr(struct iattr
if (!(ivalid & ATTR_ATIME_SET))
arg->valid |= FATTR_ATIME_NOW;
}
@ -181,7 +181,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
arg->valid |= FATTR_MTIME;
arg->mtime = iattr->ia_mtime.tv_sec;
arg->mtimensec = iattr->ia_mtime.tv_nsec;
@@ -1082,8 +1083,8 @@ static void iattr_to_fattr(struct iattr
@@ -1113,8 +1114,8 @@ static void iattr_to_fattr(struct iattr
* vmtruncate() doesn't allow for this case, so do the rlimit checking
* and the actual truncation by hand.
*/
@ -192,7 +192,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
@@ -1121,7 +1122,7 @@ static int fuse_do_setattr(struct dentry
@@ -1152,7 +1153,7 @@ static int fuse_do_setattr(struct dentry
memset(&inarg, 0, sizeof(inarg));
memset(&outarg, 0, sizeof(outarg));
@ -201,7 +201,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
if (file) {
struct fuse_file *ff = file->private_data;
inarg.valid |= FATTR_FH;
@@ -1163,10 +1164,7 @@ static int fuse_do_setattr(struct dentry
@@ -1194,10 +1195,7 @@ static int fuse_do_setattr(struct dentry
static int fuse_setattr(struct dentry *entry, struct iattr *attr)
{
@ -215,7 +215,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -894,6 +894,11 @@ static sector_t fuse_bmap(struct address
@@ -907,6 +907,11 @@ static sector_t fuse_bmap(struct address
return err ? 0 : outarg.block;
}
@ -227,19 +227,19 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
static const struct file_operations fuse_file_operations = {
.llseek = generic_file_llseek,
.read = do_sync_read,
@@ -908,6 +913,7 @@ static const struct file_operations fuse
@@ -920,6 +925,7 @@ static const struct file_operations fuse
.fsync = fuse_fsync,
.lock = fuse_file_lock,
.flock = fuse_file_flock,
.fgetattr = fuse_file_fgetattr,
+ .fsetattr = fuse_fsetattr,
+ .fsetattr = fuse_fsetattr,
.splice_read = generic_file_splice_read,
};
@@ -922,6 +928,7 @@ static const struct file_operations fuse
@@ -933,6 +939,7 @@ static const struct file_operations fuse
.fsync = fuse_fsync,
.lock = fuse_file_lock,
.flock = fuse_file_flock,
.fgetattr = fuse_file_fgetattr,
+ .fsetattr = fuse_fsetattr,
+ .fsetattr = fuse_fsetattr,
/* no mmap and splice_read */
};
@ -374,15 +374,15 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
};
/*
@@ -1189,6 +1181,7 @@ struct file_operations {
@@ -1188,6 +1180,7 @@ struct file_operations {
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
int (*fgetattr)(struct file *, struct kstat *);
+ int (*fsetattr)(struct file *, struct iattr *);
};
struct inode_operations {
@@ -1695,6 +1688,7 @@ extern int do_remount_sb(struct super_bl
@@ -1694,6 +1687,7 @@ extern int do_remount_sb(struct super_bl
extern sector_t bmap(struct inode *, sector_t);
#endif
extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);

View file

@ -32,7 +32,7 @@ security-removexattr.diff
unambiguous-__d_path.diff
mount-consistent-__d_path.diff
d_namespace_path.diff
fgetattr.diff
__d_path-keep-connected.diff
fsetattr.diff
#fix-fuse.diff
fsetattr-reintro-ATTR_FILE.diff
@ -115,3 +115,4 @@ apparmor-network.diff
#fix-net.diff
apparmor-rlimits.diff
audit-log-type-in-syslog.diff
fix-named-transitions.diff