mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-04 00:05:14 +00:00
- d_path path fix
- remove use of fgetattr - fix named transitions
This commit is contained in:
114
kernel-patches/for-mainline/__d_path-keep-connected.diff
Normal file
114
kernel-patches/for-mainline/__d_path-keep-connected.diff
Normal 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(¤t->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(¤t->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.. */
|
26
kernel-patches/for-mainline/fix-named-transitions.diff
Normal file
26
kernel-patches/for-mainline/fix-named-transitions.diff
Normal 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;
|
||||||
|
|
@@ -146,7 +146,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
|
|||||||
EXPORT_SYMBOL(notify_change);
|
EXPORT_SYMBOL(notify_change);
|
||||||
--- a/fs/fuse/dir.c
|
--- a/fs/fuse/dir.c
|
||||||
+++ b/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;
|
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;
|
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))
|
if (!(ivalid & ATTR_ATIME_SET))
|
||||||
arg->valid |= FATTR_ATIME_NOW;
|
arg->valid |= FATTR_ATIME_NOW;
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
|
|||||||
arg->valid |= FATTR_MTIME;
|
arg->valid |= FATTR_MTIME;
|
||||||
arg->mtime = iattr->ia_mtime.tv_sec;
|
arg->mtime = iattr->ia_mtime.tv_sec;
|
||||||
arg->mtimensec = iattr->ia_mtime.tv_nsec;
|
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
|
* vmtruncate() doesn't allow for this case, so do the rlimit checking
|
||||||
* and the actual truncation by hand.
|
* 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 inode *inode = entry->d_inode;
|
||||||
struct fuse_conn *fc = get_fuse_conn(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(&inarg, 0, sizeof(inarg));
|
||||||
memset(&outarg, 0, sizeof(outarg));
|
memset(&outarg, 0, sizeof(outarg));
|
||||||
@@ -201,7 +201,7 @@ Signed-off-by: John Johansen <jjohansen@suse.de> ---
|
|||||||
if (file) {
|
if (file) {
|
||||||
struct fuse_file *ff = file->private_data;
|
struct fuse_file *ff = file->private_data;
|
||||||
inarg.valid |= FATTR_FH;
|
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)
|
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,
|
static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
|
||||||
--- a/fs/fuse/file.c
|
--- a/fs/fuse/file.c
|
||||||
+++ b/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;
|
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 = {
|
static const struct file_operations fuse_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.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,
|
.lock = fuse_file_lock,
|
||||||
.flock = fuse_file_flock,
|
.flock = fuse_file_flock,
|
||||||
.fgetattr = fuse_file_fgetattr,
|
+ .fsetattr = fuse_fsetattr,
|
||||||
+ .fsetattr = fuse_fsetattr,
|
|
||||||
.splice_read = generic_file_splice_read,
|
.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,
|
.lock = fuse_file_lock,
|
||||||
.flock = fuse_file_flock,
|
.flock = fuse_file_flock,
|
||||||
.fgetattr = fuse_file_fgetattr,
|
+ .fsetattr = fuse_fsetattr,
|
||||||
+ .fsetattr = fuse_fsetattr,
|
|
||||||
/* no mmap and splice_read */
|
/* 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);
|
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 (*setlease)(struct file *, long, struct file_lock **);
|
||||||
int (*fgetattr)(struct file *, struct kstat *);
|
|
||||||
+ int (*fsetattr)(struct file *, struct iattr *);
|
+ int (*fsetattr)(struct file *, struct iattr *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct inode_operations {
|
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);
|
extern sector_t bmap(struct inode *, sector_t);
|
||||||
#endif
|
#endif
|
||||||
extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);
|
extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *);
|
||||||
|
@@ -32,7 +32,7 @@ security-removexattr.diff
|
|||||||
unambiguous-__d_path.diff
|
unambiguous-__d_path.diff
|
||||||
mount-consistent-__d_path.diff
|
mount-consistent-__d_path.diff
|
||||||
d_namespace_path.diff
|
d_namespace_path.diff
|
||||||
fgetattr.diff
|
__d_path-keep-connected.diff
|
||||||
fsetattr.diff
|
fsetattr.diff
|
||||||
#fix-fuse.diff
|
#fix-fuse.diff
|
||||||
fsetattr-reintro-ATTR_FILE.diff
|
fsetattr-reintro-ATTR_FILE.diff
|
||||||
@@ -115,3 +115,4 @@ apparmor-network.diff
|
|||||||
#fix-net.diff
|
#fix-net.diff
|
||||||
apparmor-rlimits.diff
|
apparmor-rlimits.diff
|
||||||
audit-log-type-in-syslog.diff
|
audit-log-type-in-syslog.diff
|
||||||
|
fix-named-transitions.diff
|
||||||
|
Reference in New Issue
Block a user