mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 14:25:52 +00:00
Some more minor cleanups
This commit is contained in:
@@ -1,169 +0,0 @@
|
||||
Index: linux-2.6/security/apparmor/apparmor.h
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/apparmor.h
|
||||
+++ linux-2.6/security/apparmor/apparmor.h
|
||||
@@ -218,7 +218,8 @@ extern int aa_audit_message(struct aapro
|
||||
extern int aa_audit_syscallreject(struct aaprofile *active, gfp_t gfp,
|
||||
const char *);
|
||||
extern int aa_audit(struct aaprofile *active, const struct aa_audit *);
|
||||
-extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt);
|
||||
+extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
|
||||
+ char **addr);
|
||||
|
||||
extern int aa_attr(struct aaprofile *active, struct dentry *dentry,
|
||||
struct vfsmount *mnt, struct iattr *iattr);
|
||||
Index: linux-2.6/security/apparmor/inline.h
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/inline.h
|
||||
+++ linux-2.6/security/apparmor/inline.h
|
||||
@@ -214,9 +214,12 @@ static inline struct aaprofile *alloc_aa
|
||||
* Release space (free_page) allocated to hold pathname
|
||||
* name may be NULL (checked for by free_page)
|
||||
*/
|
||||
-static inline void aa_put_name(const char *name)
|
||||
+static inline void aa_put_name(const char *name, char *addr)
|
||||
{
|
||||
- aa_put_path((char *)name);
|
||||
+ if (addr)
|
||||
+ kfree(addr);
|
||||
+ else
|
||||
+ aa_put_path((char *)name);
|
||||
}
|
||||
|
||||
/** __aa_find_profile
|
||||
Index: linux-2.6/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/main.c
|
||||
+++ linux-2.6/security/apparmor/main.c
|
||||
@@ -318,8 +318,9 @@ static int _aa_perm_vfsmount(struct aapr
|
||||
struct vfsmount *mnt, struct aa_audit *sa, int mask)
|
||||
{
|
||||
int permerror, error;
|
||||
+ char *addr;
|
||||
|
||||
- sa->name = aa_get_name(dentry, mnt);
|
||||
+ sa->name = aa_get_name(dentry, mnt, &addr);
|
||||
|
||||
if (IS_ERR(sa->name)) {
|
||||
permerror = PTR_ERR(sa->name);
|
||||
@@ -332,7 +333,7 @@ static int _aa_perm_vfsmount(struct aapr
|
||||
|
||||
error = aa_audit(active, sa);
|
||||
|
||||
- aa_put_name(sa->name);
|
||||
+ aa_put_name(sa->name, addr);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -658,27 +659,37 @@ out:
|
||||
* aa_get_name - retrieve fully qualified path name
|
||||
* @dentry: relative path element
|
||||
* @mnt: where in tree
|
||||
- *
|
||||
+ * @addr: the true start address of returned names buffer if buffer > a
|
||||
+ * single page
|
||||
* Returns fully qualified path name on sucess, NULL on failure.
|
||||
* aa_put_name must be used to free allocated buffer.
|
||||
*/
|
||||
-char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt)
|
||||
+char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, char **addr)
|
||||
{
|
||||
- char *page, *name;
|
||||
+ char *buffer, *name;
|
||||
+ int order = 0;
|
||||
|
||||
- page = (char *)aa_get_path(GFP_KERNEL);
|
||||
- if (!page) {
|
||||
+ *addr = NULL;
|
||||
+ buffer = (char *)aa_get_path(GFP_KERNEL);
|
||||
+ retry:
|
||||
+ if (!buffer) {
|
||||
name = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
- name = d_path(dentry, mnt, page, PAGE_SIZE);
|
||||
+ name = d_path(dentry, mnt, buffer, PAGE_SIZE << order);
|
||||
/* check for (deleted) that d_path appends to pathnames if the dentry
|
||||
* has been removed from the cache.
|
||||
* The size > deleted_size and strcmp checks are redundant safe guards.
|
||||
*/
|
||||
if (IS_ERR(name)) {
|
||||
- aa_put_path(page);
|
||||
+ if (order == 0)
|
||||
+ aa_put_path(buffer);
|
||||
+ else
|
||||
+ kfree(buffer);
|
||||
+ order++;
|
||||
+ buffer = kmalloc(PAGE_SIZE << order, GFP_KERNEL);
|
||||
+ goto retry;
|
||||
} else {
|
||||
const char deleted_str[] = " (deleted)";
|
||||
const size_t deleted_size = sizeof(deleted_str) - 1;
|
||||
@@ -692,6 +703,8 @@ char *aa_get_name(struct dentry *dentry,
|
||||
}
|
||||
|
||||
out:
|
||||
+ if (order > 0)
|
||||
+ *addr = buffer;
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -766,6 +779,7 @@ int aa_perm(struct aaprofile *active, st
|
||||
{
|
||||
int error = 0;
|
||||
struct aa_audit sa;
|
||||
+ char *addr;
|
||||
|
||||
if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
|
||||
goto out;
|
||||
@@ -850,9 +864,10 @@ int aa_link(struct aaprofile *active,
|
||||
{
|
||||
int permerror = -EPERM, error;
|
||||
struct aa_audit sa;
|
||||
+ char *addr, *paddr;
|
||||
|
||||
- sa.name = aa_get_name(link, link_mnt);
|
||||
- sa.pval = aa_get_name(target, target_mnt);
|
||||
+ sa.name = aa_get_name(link, link_mnt, &addr);
|
||||
+ sa.pval = aa_get_name(target, target_mnt, &paddr);
|
||||
|
||||
if (IS_ERR(sa.name)) {
|
||||
permerror = PTR_ERR(sa.name);
|
||||
@@ -874,8 +889,8 @@ int aa_link(struct aaprofile *active,
|
||||
|
||||
error = aa_audit(active, &sa);
|
||||
|
||||
- aa_put_name(sa.name);
|
||||
- aa_put_name(sa.pval);
|
||||
+ aa_put_name(sa.name, addr);
|
||||
+ aa_put_name(sa.pval, paddr);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -942,6 +957,7 @@ int aa_fork(struct task_struct *p)
|
||||
int aa_register(struct linux_binprm *bprm)
|
||||
{
|
||||
char *filename;
|
||||
+ char *addr;
|
||||
struct file *filp = bprm->file;
|
||||
struct aaprofile *active;
|
||||
struct aaprofile *newprofile = NULL, unconstrained_flag;
|
||||
@@ -954,7 +970,7 @@ int aa_register(struct linux_binprm *bpr
|
||||
|
||||
AA_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
- filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt);
|
||||
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &addr);
|
||||
if (IS_ERR(filename)) {
|
||||
AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
|
||||
goto out;
|
||||
@@ -1206,7 +1222,7 @@ apply_profile:
|
||||
}
|
||||
|
||||
cleanup:
|
||||
- aa_put_name(filename);
|
||||
+ aa_put_name(filename, addr);
|
||||
|
||||
put_aaprofile(active);
|
||||
|
@@ -1,218 +0,0 @@
|
||||
Index: linux-2.6/security/apparmor/apparmor.h
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/apparmor.h
|
||||
+++ linux-2.6/security/apparmor/apparmor.h
|
||||
@@ -197,7 +197,19 @@ enum aa_xattroptype {
|
||||
#define BASE_PROFILE(p) ((p)->parent ? (p)->parent : (p))
|
||||
#define IN_SUBPROFILE(p) ((p)->parent)
|
||||
|
||||
+/* path name buffer cache */
|
||||
+#define AAPATH_CACHE_MAX_COUNT 2
|
||||
+
|
||||
+struct aa_path_cache_head {
|
||||
+ unsigned int count;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
/* main.c */
|
||||
+extern void aa_destroy_path_cache(void);
|
||||
+extern int aa_init_path_cache(void);
|
||||
+extern char *aa_get_path(gfp_t gfp);
|
||||
+extern void aa_put_path(char *path);
|
||||
extern int alloc_null_complain_profile(void);
|
||||
extern void free_null_complain_profile(void);
|
||||
extern int attach_nullprofile(struct aaprofile *profile);
|
||||
Index: linux-2.6/security/apparmor/inline.h
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/inline.h
|
||||
+++ linux-2.6/security/apparmor/inline.h
|
||||
@@ -216,7 +216,7 @@ static inline struct aaprofile *alloc_aa
|
||||
*/
|
||||
static inline void aa_put_name(const char *name)
|
||||
{
|
||||
- free_page((unsigned long)name);
|
||||
+ aa_put_path((char *)name);
|
||||
}
|
||||
|
||||
/** __aa_find_profile
|
||||
Index: linux-2.6/security/apparmor/lsm.c
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/lsm.c
|
||||
+++ linux-2.6/security/apparmor/lsm.c
|
||||
@@ -816,6 +816,11 @@ static int __init apparmor_init(void)
|
||||
goto alloc_out;
|
||||
}
|
||||
|
||||
+ if ((error = aa_init_path_cache())) {
|
||||
+ AA_ERROR("Unable to allocate path cache\n");
|
||||
+ goto path_out;
|
||||
+ }
|
||||
+
|
||||
if ((error = register_security(&apparmor_ops))) {
|
||||
AA_ERROR("Unable to load AppArmor\n");
|
||||
goto register_security_out;
|
||||
@@ -830,6 +835,9 @@ static int __init apparmor_init(void)
|
||||
return error;
|
||||
|
||||
register_security_out:
|
||||
+ aa_destroy_path_cache();
|
||||
+
|
||||
+path_out:
|
||||
free_null_complain_profile();
|
||||
|
||||
alloc_out:
|
||||
Index: linux-2.6/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- linux-2.6.orig/security/apparmor/main.c
|
||||
+++ linux-2.6/security/apparmor/main.c
|
||||
@@ -12,11 +12,132 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/audit.h>
|
||||
+#include <linux/mm.h>
|
||||
|
||||
#include "apparmor.h"
|
||||
|
||||
#include "inline.h"
|
||||
|
||||
+static DEFINE_PER_CPU(struct aa_path_cache_head, aa_path_cache);
|
||||
+
|
||||
+/**
|
||||
+ * aa_destroy_path_cache - destroy the path cache initialized
|
||||
+ */
|
||||
+void aa_destroy_path_cache(void)
|
||||
+{
|
||||
+ int cpu;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ struct list_head *n, *tmp;
|
||||
+ if (per_cpu(aa_path_cache, cpu).count == 0)
|
||||
+ continue;
|
||||
+ per_cpu(aa_path_cache, cpu).count = 0;
|
||||
+ list_for_each_safe(n, tmp, &per_cpu(aa_path_cache, cpu).list) {
|
||||
+ list_del(n);
|
||||
+ free_page((unsigned long) n);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define ALIGN_TO_PAGE(X) (((unsigned long)(X)) & PAGE_MASK)
|
||||
+
|
||||
+static inline int aa_push_path(struct aa_path_cache_head *cache, char *path)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (cache->count < AAPATH_CACHE_MAX_COUNT) {
|
||||
+ list_add((struct list_head *) ALIGN_TO_PAGE(path),
|
||||
+ &cache->list);
|
||||
+ cache->count++;
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_init_path_cache - initialize AA's path cache
|
||||
+ */
|
||||
+int aa_init_path_cache(void)
|
||||
+{
|
||||
+ int cpu;
|
||||
+ int error = -ENOMEM;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ per_cpu(aa_path_cache, cpu).count = 0;
|
||||
+ INIT_LIST_HEAD(&per_cpu(aa_path_cache, cpu).list);
|
||||
+ }
|
||||
+
|
||||
+ /* initialize the path cache with 2 pages/cpu */
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ char *page;
|
||||
+
|
||||
+ page = (char *) __get_free_page(GFP_KERNEL);
|
||||
+ if (!page)
|
||||
+ goto out;
|
||||
+ aa_push_path(&per_cpu(aa_path_cache, cpu), page);
|
||||
+ page = (char *) __get_free_page(GFP_KERNEL);
|
||||
+ if (!page)
|
||||
+ goto out;
|
||||
+ aa_push_path(&per_cpu(aa_path_cache, cpu), page);
|
||||
+ error = 0;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_get_path - get a path buffer for use in path lookups
|
||||
+ * @gfp: the type of memory allocation to perform if no buffer available in
|
||||
+ * the cache.
|
||||
+ */
|
||||
+char *aa_get_path(gfp_t gfp)
|
||||
+{
|
||||
+ struct aa_path_cache_head *cache;
|
||||
+ char *path;
|
||||
+
|
||||
+ cache = &get_cpu_var(aa_path_cache);
|
||||
+ if (cache->count) {
|
||||
+ struct list_head *node;
|
||||
+ list_for_each(node, &cache->list) {
|
||||
+ list_del(node);
|
||||
+ break;
|
||||
+ }
|
||||
+ cache->count--;
|
||||
+ path = (char *) node;
|
||||
+ put_cpu_var(aa_path_cache);
|
||||
+ } else {
|
||||
+ put_cpu_var(aa_path_cache);
|
||||
+ path = (char *) __get_free_page(gfp);
|
||||
+ }
|
||||
+ return path;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * aa_put_path - put a path buffer obtained with aa_get_path
|
||||
+ * @path: the path buffer to return to the path buffer cache
|
||||
+ */
|
||||
+void aa_put_path(char *path)
|
||||
+{
|
||||
+ if (!path)
|
||||
+ goto out;
|
||||
+
|
||||
+ /* does the path buffer belong on the current cpu's node */
|
||||
+ if (cpu_to_node(smp_processor_id()) ==
|
||||
+ page_to_nid(virt_to_page(path))) {
|
||||
+ struct aa_path_cache_head *cache = &get_cpu_var(aa_path_cache);
|
||||
+ int success = aa_push_path(cache, path);
|
||||
+ put_cpu_var(aa_path_cache);
|
||||
+ if (success)
|
||||
+ goto out;
|
||||
+ }
|
||||
+ free_page((unsigned long) path);
|
||||
+
|
||||
+out:
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
/* NULL complain profile
|
||||
*
|
||||
* Used when in complain mode, to emit Permitting messages for non-existant
|
||||
@@ -545,7 +666,7 @@ char *aa_get_name(struct dentry *dentry,
|
||||
{
|
||||
char *page, *name;
|
||||
|
||||
- page = (char *)__get_free_page(GFP_KERNEL);
|
||||
+ page = (char *)aa_get_path(GFP_KERNEL);
|
||||
if (!page) {
|
||||
name = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
@@ -557,7 +678,7 @@ char *aa_get_name(struct dentry *dentry,
|
||||
* The size > deleted_size and strcmp checks are redundant safe guards.
|
||||
*/
|
||||
if (IS_ERR(name)) {
|
||||
- free_page((unsigned long)page);
|
||||
+ aa_put_path(page);
|
||||
} else {
|
||||
const char deleted_str[] = " (deleted)";
|
||||
const size_t deleted_size = sizeof(deleted_str) - 1;
|
@@ -1,43 +1,87 @@
|
||||
Index: linux-2.6/fs/dcache.c
|
||||
Fix __d_path() for lazy unmounts and make it unambiguous
|
||||
|
||||
First, when d_path() hits a lazily unmounted mount point, it tries to
|
||||
prepend the name of the lazily unmounted dentry to the path name. It
|
||||
gets this wrong, and also overwrites the slash that separates the name
|
||||
from the following pathname component.
|
||||
|
||||
Second, it isn't always possible to tell from the __d_path result
|
||||
whether the specified root and rootmnt (i.e., the chroot) was reached:
|
||||
lazy unmounts of bind mounts will produce a path that does start with a
|
||||
non-slash so we can tell from that, but other lazy unmounts will produce
|
||||
a path that starts with a slash, just like "ordinary" paths.
|
||||
|
||||
Third, sys_getcwd() shouldn't return disconnected paths. The patch
|
||||
checks for that, and makes it fail with -ENOENT in that case.
|
||||
|
||||
The attached patch cleans up __d_path() to fix the bug with overlapping
|
||||
pathname components. It also adds a @fail_deleted argument, which allows
|
||||
to get rid of some of the mess in sys_getcwd(). We make sure that paths
|
||||
will only start with a slash if the path leads all the way up to the
|
||||
root. If the resulting path would otherwise be empty, we return "."
|
||||
instead so that some users of seq_path for files in /proc won't break.
|
||||
|
||||
The @fail_deleted argument allows sys_getcwd() to be simplified.
|
||||
Grabbing the dcache_lock can be moved into __d_path().
|
||||
|
||||
The @fail_deleted argument could be added to d_path() as well: this would
|
||||
allow callers to recognize deleted files without having to resort to the
|
||||
ambiguous check for the " (deleted)" string at the end of the pathnames.
|
||||
This is not currently done, but it might be worthwhile.
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
Reviewed-by: NeilBrown <neilb@suse.de>
|
||||
|
||||
Index: b/fs/dcache.c
|
||||
===================================================================
|
||||
--- linux-2.6.orig/fs/dcache.c
|
||||
+++ linux-2.6/fs/dcache.c
|
||||
@@ -1739,45 +1739,43 @@ shouldnt_be_hashed:
|
||||
--- a/fs/dcache.c
|
||||
+++ b/fs/dcache.c
|
||||
@@ -1732,52 +1732,51 @@ shouldnt_be_hashed:
|
||||
}
|
||||
|
||||
/**
|
||||
- * d_path - return the path of a dentry
|
||||
+ * __d_path - return the path of a dentry
|
||||
* @dentry: dentry to report
|
||||
* @vfsmnt: vfsmnt to which the dentry belongs
|
||||
* @root: root dentry
|
||||
* @rootmnt: vfsmnt to which the root dentry belongs
|
||||
* @buffer: buffer to return value in
|
||||
* @buflen: buffer length
|
||||
+ * @fail_deleted: what to return when hitting a deleted dentry
|
||||
+ * @fail_deleted: what to return for deleted files
|
||||
*
|
||||
- * Convert a dentry into an ASCII path name. If the entry has been deleted
|
||||
- * the string " (deleted)" is appended. Note that this is ambiguous.
|
||||
+ * 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,
|
||||
+ * the the string " (deleted)" is appended. Note that this is ambiguous.
|
||||
* the string " (deleted)" is appended. Note that this is ambiguous.
|
||||
*
|
||||
- * Returns the buffer or an error code if the path was too long.
|
||||
- *
|
||||
+ * If @dentry is not connected to @root, the path returned will be relative
|
||||
+ * (i.e., it will not start with a slash).
|
||||
*
|
||||
- * "buflen" should be positive. Caller holds the dcache_lock.
|
||||
+ * Returns the buffer or an error code.
|
||||
*/
|
||||
-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
- struct dentry *root, struct vfsmount *rootmnt,
|
||||
- char *buffer, int buflen)
|
||||
-{
|
||||
- char * end = buffer+buflen;
|
||||
- char * retval;
|
||||
- int namelen;
|
||||
+static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
|
||||
+ struct dentry *root, struct vfsmount *rootmnt,
|
||||
+ char *buffer, int buflen, int fail_deleted)
|
||||
{
|
||||
- char * end = buffer+buflen;
|
||||
- char * retval;
|
||||
+ char *end = buffer + buflen - 1;
|
||||
int namelen;
|
||||
|
||||
- *--end = '\0';
|
||||
+ buffer = end;
|
||||
+{
|
||||
+ int namelen, is_slash;
|
||||
+
|
||||
+ if (buflen < 2)
|
||||
+ return ERR_PTR(-ENAMETOOLONG);
|
||||
+ *end = '\0';
|
||||
buflen--;
|
||||
+
|
||||
+ buffer += --buflen;
|
||||
+ *buffer = '\0';
|
||||
|
||||
- *--end = '\0';
|
||||
- buflen--;
|
||||
+ spin_lock(&dcache_lock);
|
||||
if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
|
||||
- buflen -= 10;
|
||||
@@ -72,26 +116,26 @@ Index: linux-2.6/fs/dcache.c
|
||||
spin_lock(&vfsmount_lock);
|
||||
if (vfsmnt->mnt_parent == vfsmnt) {
|
||||
spin_unlock(&vfsmount_lock);
|
||||
@@ -1791,33 +1789,49 @@ static char * __d_path( struct dentry *d
|
||||
@@ -1791,33 +1790,63 @@ static char * __d_path( struct dentry *d
|
||||
parent = dentry->d_parent;
|
||||
prefetch(parent);
|
||||
namelen = dentry->d_name.len;
|
||||
- buflen -= namelen + 1;
|
||||
- if (buflen < 0)
|
||||
+ if (buflen <= namelen)
|
||||
+ if (buflen < namelen + 1)
|
||||
goto Elong;
|
||||
- end -= namelen;
|
||||
- memcpy(end, dentry->d_name.name, namelen);
|
||||
- *--end = '/';
|
||||
- retval = end;
|
||||
+ buflen -= namelen + 1;
|
||||
+ buffer -= namelen;
|
||||
+ buffer -= namelen + 1;
|
||||
+ memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ *--buffer = '/';
|
||||
+ *buffer = '/';
|
||||
dentry = parent;
|
||||
}
|
||||
+ /* Get '/' right */
|
||||
+ if (buffer == end)
|
||||
+ /* Get '/' right. */
|
||||
+ if (*buffer != '/')
|
||||
+ *--buffer = '/';
|
||||
|
||||
- return retval;
|
||||
@@ -101,27 +145,40 @@ Index: linux-2.6/fs/dcache.c
|
||||
|
||||
global_root:
|
||||
+ /*
|
||||
+ * We went past the (vfsmount, dentry) we were loking for and have
|
||||
+ * either hit a root dentry, a lazily unmounted dentry, or an
|
||||
+ * unconnected dentry. Make sure we won't return a pathname rooted
|
||||
+ * in '/'.
|
||||
+ * We went past the (vfsmount, dentry) we were looking for and have
|
||||
+ * either hit a root dentry, a lazily unmounted dentry, an
|
||||
+ * unconnected dentry, or the file is on a pseudo filesystem.
|
||||
+ */
|
||||
namelen = dentry->d_name.len;
|
||||
- buflen -= namelen;
|
||||
- if (buflen < 0)
|
||||
- goto Elong;
|
||||
+ is_slash = (namelen == 1 && *dentry->d_name.name == '/');
|
||||
+ if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
|
||||
+ /*
|
||||
+ * Make sure we won't return a pathname starting with '/'.
|
||||
+ *
|
||||
+ * Historically, we also glue together the root dentry and
|
||||
+ * remaining name for pseudo filesystems like pipefs, which
|
||||
+ * have the MS_NOUSER flag set. This results in pathnames
|
||||
+ * like "pipe:[439336]".
|
||||
+ */
|
||||
+ if (*buffer == '/') {
|
||||
+ buffer++;
|
||||
+ buflen++;
|
||||
+ }
|
||||
+ if (is_slash) {
|
||||
+ if (*buffer == '\0')
|
||||
+ *--buffer = '.';
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ if (buflen < namelen)
|
||||
goto Elong;
|
||||
- retval -= namelen-1; /* hit the slash */
|
||||
- memcpy(retval, dentry->d_name.name, namelen);
|
||||
- return retval;
|
||||
+ if (namelen == 1 && *dentry->d_name.name == '/') {
|
||||
+ if (buffer != end)
|
||||
+ buffer++;
|
||||
+ } else {
|
||||
+ if (buflen < namelen)
|
||||
+ goto Elong;
|
||||
+ buffer -= namelen;
|
||||
+ memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ }
|
||||
+ buffer -= namelen;
|
||||
+ memcpy(buffer, dentry->d_name.name, namelen);
|
||||
+ goto out;
|
||||
+
|
||||
Elong:
|
||||
@@ -138,7 +195,7 @@ Index: linux-2.6/fs/dcache.c
|
||||
{
|
||||
char *res;
|
||||
struct vfsmount *rootmnt;
|
||||
@@ -1827,9 +1841,7 @@ char * d_path(struct dentry *dentry, str
|
||||
@@ -1827,9 +1856,7 @@ char * d_path(struct dentry *dentry, str
|
||||
rootmnt = mntget(current->fs->rootmnt);
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
@@ -149,7 +206,7 @@ Index: linux-2.6/fs/dcache.c
|
||||
dput(root);
|
||||
mntput(rootmnt);
|
||||
return res;
|
||||
@@ -1855,10 +1867,10 @@ char * d_path(struct dentry *dentry, str
|
||||
@@ -1855,10 +1882,10 @@ char * d_path(struct dentry *dentry, str
|
||||
*/
|
||||
asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
|
||||
{
|
||||
@@ -162,11 +219,15 @@ Index: linux-2.6/fs/dcache.c
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
@@ -1870,29 +1882,18 @@ asmlinkage long sys_getcwd(char __user *
|
||||
@@ -1870,29 +1897,21 @@ asmlinkage long sys_getcwd(char __user *
|
||||
root = dget(current->fs->root);
|
||||
read_unlock(¤t->fs->lock);
|
||||
|
||||
- error = -ENOENT;
|
||||
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
|
||||
+ error = PTR_ERR(cwd);
|
||||
+ if (IS_ERR(cwd))
|
||||
+ goto out;
|
||||
error = -ENOENT;
|
||||
- /* Has the current directory has been unlinked? */
|
||||
- spin_lock(&dcache_lock);
|
||||
- if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
|
||||
@@ -179,7 +240,9 @@ Index: linux-2.6/fs/dcache.c
|
||||
- error = PTR_ERR(cwd);
|
||||
- if (IS_ERR(cwd))
|
||||
- goto out;
|
||||
-
|
||||
+ if (*cwd != '/')
|
||||
+ goto out;
|
||||
|
||||
- error = -ERANGE;
|
||||
- len = PAGE_SIZE + page - cwd;
|
||||
- if (len <= size) {
|
||||
@@ -189,11 +252,6 @@ Index: linux-2.6/fs/dcache.c
|
||||
- }
|
||||
- } else
|
||||
- spin_unlock(&dcache_lock);
|
||||
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
|
||||
+ error = PTR_ERR(cwd);
|
||||
+ if (IS_ERR(cwd))
|
||||
+ goto out;
|
||||
+
|
||||
+ error = -ERANGE;
|
||||
+ len = PAGE_SIZE + page - cwd;
|
||||
+ if (len <= size) {
|
||||
|
92
kernel-patches/for-mainline/match-changes.diff
Normal file
92
kernel-patches/for-mainline/match-changes.diff
Normal file
@@ -0,0 +1,92 @@
|
||||
Index: b/security/apparmor/match.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -160,7 +160,7 @@ int verify_dfa(struct aa_dfa *dfa)
|
||||
if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
|
||||
goto out;
|
||||
|
||||
- /* if equivalence classes then its table must be 256 */
|
||||
+ /* if equivalence classes then its table size must be 256 */
|
||||
if (dfa->tables[YYTD_ID_EC - 1] &&
|
||||
dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
|
||||
goto out;
|
||||
@@ -201,67 +201,46 @@ void aa_match_free(struct aa_dfa *dfa)
|
||||
}
|
||||
|
||||
/**
|
||||
- * aadfa_label - return the permissions associated with @state
|
||||
- * @dfa: dfa to get state permission from
|
||||
- * @state: state in the dfa for which to get a label
|
||||
- *
|
||||
- * Assumes that state is a valid state of the dfa
|
||||
- *
|
||||
- * Returns the label associated with @state. 0 indicates the state
|
||||
- * is no-accepting/provides no permissions.
|
||||
- */
|
||||
-inline unsigned int aadfa_label(struct aa_dfa *dfa, int state)
|
||||
-{
|
||||
- return ACCEPT_TABLE(dfa)[state];
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
* aa_dfa_match - match @path against @dfa starting in @state
|
||||
* @dfa: the dfa to match @path against
|
||||
* @state: the state to start matching in
|
||||
* @path: the path to match against the dfa
|
||||
*
|
||||
* aa_dfa_match will match the full path length and return the state it
|
||||
- * finished matching in. The final state returned can be used to
|
||||
- * lookup the accepting label or as a starting point to continue matching
|
||||
- * with a new string if the path has been broken into multiple components.
|
||||
+ * finished matching in. The final state is used to look up the accepting
|
||||
+ * label.
|
||||
*/
|
||||
-inline unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int state,
|
||||
- const char *path)
|
||||
+inline unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str)
|
||||
{
|
||||
- u8 *s = (u8 *) path;
|
||||
u16 *def = DEFAULT_TABLE(dfa);
|
||||
u32 *base = BASE_TABLE(dfa);
|
||||
u16 *next = NEXT_TABLE(dfa);
|
||||
u16 *check = CHECK_TABLE(dfa);
|
||||
- unsigned int pos;
|
||||
+ unsigned int state = 1, pos;
|
||||
|
||||
- /* current state is <state>, matching character *s */
|
||||
+ /* current state is <state>, matching character *str */
|
||||
if (dfa->tables[YYTD_ID_EC - 1]) {
|
||||
u8 *equiv = EQUIV_TABLE(dfa);
|
||||
- for ( ; *s; ++s) {
|
||||
- pos = base[state] + equiv[*s];
|
||||
+ while (*str) {
|
||||
+ pos = base[state] + equiv[(u8)*str++];
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
}
|
||||
} else {
|
||||
- for ( ; *s; ++s) {
|
||||
- pos = base[state] + *s;
|
||||
+ while (*str) {
|
||||
+ pos = base[state] + (u8)*str++;
|
||||
if (check[pos] == state)
|
||||
state = next[pos];
|
||||
else
|
||||
state = def[state];
|
||||
}
|
||||
}
|
||||
- return state;
|
||||
+ return ACCEPT_TABLE(dfa)[state];
|
||||
}
|
||||
|
||||
unsigned int aa_match(struct aa_dfa *dfa, const char *pathname)
|
||||
{
|
||||
- if (dfa)
|
||||
- return aadfa_label(dfa, aa_dfa_match(dfa, 1, pathname));
|
||||
-
|
||||
- return 0;
|
||||
+ return dfa ? aa_dfa_match(dfa, pathname) : 0;
|
||||
}
|
52
kernel-patches/for-mainline/match-features.diff
Normal file
52
kernel-patches/for-mainline/match-features.diff
Normal file
@@ -0,0 +1,52 @@
|
||||
Remove some remains of the matcher modules.
|
||||
|
||||
Index: b/security/apparmor/apparmor.h
|
||||
===================================================================
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -278,7 +278,6 @@ struct aa_dfa *aa_match_alloc(void);
|
||||
void aa_match_free(struct aa_dfa *dfa);
|
||||
int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size);
|
||||
int verify_dfa(struct aa_dfa *dfa);
|
||||
-const char *aa_match_features(void);
|
||||
unsigned int aa_match(struct aa_dfa *dfa, const char *pathname);
|
||||
|
||||
#endif /* __APPARMOR_H */
|
||||
Index: b/security/apparmor/apparmorfs.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/apparmorfs.c
|
||||
+++ b/security/apparmor/apparmorfs.c
|
||||
@@ -141,7 +141,7 @@ static int aa_prof_release(struct inode
|
||||
static ssize_t aa_matching_read(struct file *file, char __user *buf,
|
||||
size_t size, loff_t *ppos)
|
||||
{
|
||||
- const char *matching = aa_match_features();
|
||||
+ const char *matching = "pattern=aadfa";
|
||||
|
||||
return simple_read_from_buffer(buf, size, ppos, matching,
|
||||
strlen(matching));
|
||||
Index: b/security/apparmor/match.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/match.c
|
||||
+++ b/security/apparmor/match.c
|
||||
@@ -16,8 +16,6 @@
|
||||
#include <linux/module.h>
|
||||
#include "match.h"
|
||||
|
||||
-static const char *features="pattern=aadfa";
|
||||
-
|
||||
static struct table_header *unpack_table(void *blob, size_t bsize)
|
||||
{
|
||||
struct table_header *table = NULL;
|
||||
@@ -202,11 +200,6 @@ void aa_match_free(struct aa_dfa *dfa)
|
||||
kfree(dfa);
|
||||
}
|
||||
|
||||
-const char *aa_match_features(void)
|
||||
-{
|
||||
- return features;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* aadfa_label - return the permissions associated with @state
|
||||
* @dfa: dfa to get state permission from
|
181
kernel-patches/for-mainline/no-unreachable-paths.diff
Normal file
181
kernel-patches/for-mainline/no-unreachable-paths.diff
Normal file
@@ -0,0 +1,181 @@
|
||||
Hide unreachable mount points in /proc/mounts and /proc/$PID/mountstats
|
||||
|
||||
What's mounted on unreachable mount points isn't interesting to
|
||||
processes: they can't get there in the first place. This patch hides
|
||||
unreachable mounts from processes.
|
||||
|
||||
Processes living in the root namespace whill still see all mounts they
|
||||
were seeing before except for the rootfs mount, which is never reachable
|
||||
from an "ordinary" process.
|
||||
|
||||
Only the initial initrd init process will actually have access to the
|
||||
rootfs mount. For this process that mount *is* reachable, and so it will
|
||||
show in.
|
||||
|
||||
This patch also removes some code duplication between mounts_open() and
|
||||
mountstats_open().
|
||||
|
||||
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
|
||||
|
||||
Index: b/fs/namespace.c
|
||||
===================================================================
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -348,8 +348,16 @@ static inline void mangle(struct seq_fil
|
||||
seq_escape(m, s, " \t\n\\");
|
||||
}
|
||||
|
||||
+/* Keep in sync with fs/proc/base.c! */
|
||||
+struct proc_mounts {
|
||||
+ struct seq_file m;
|
||||
+ void *page;
|
||||
+ int event;
|
||||
+};
|
||||
+
|
||||
static int show_vfsmnt(struct seq_file *m, void *v)
|
||||
{
|
||||
+ void *page = container_of(m, struct proc_mounts, m)->page;
|
||||
struct vfsmount *mnt = v;
|
||||
int err = 0;
|
||||
static struct proc_fs_info {
|
||||
@@ -372,9 +380,13 @@ static int show_vfsmnt(struct seq_file *
|
||||
};
|
||||
struct proc_fs_info *fs_infop;
|
||||
|
||||
+ char *path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE);
|
||||
+ if (IS_ERR(path) || *path != '/')
|
||||
+ return err;
|
||||
+
|
||||
mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none");
|
||||
seq_putc(m, ' ');
|
||||
- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
|
||||
+ mangle(m, path);
|
||||
seq_putc(m, ' ');
|
||||
mangle(m, mnt->mnt_sb->s_type->name);
|
||||
seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw");
|
||||
@@ -401,9 +413,14 @@ struct seq_operations mounts_op = {
|
||||
|
||||
static int show_vfsstat(struct seq_file *m, void *v)
|
||||
{
|
||||
+ void *page = container_of(m, struct proc_mounts, m)->page;
|
||||
struct vfsmount *mnt = v;
|
||||
int err = 0;
|
||||
|
||||
+ char *path = d_path(mnt->mnt_root, mnt, page, PAGE_SIZE);
|
||||
+ if (IS_ERR(path) || *path != '/')
|
||||
+ return err; /* error or path unreachable from chroot */
|
||||
+
|
||||
/* device */
|
||||
if (mnt->mnt_devname) {
|
||||
seq_puts(m, "device ");
|
||||
@@ -413,7 +430,7 @@ static int show_vfsstat(struct seq_file
|
||||
|
||||
/* mount point */
|
||||
seq_puts(m, " mounted on ");
|
||||
- seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
|
||||
+ mangle(m, path);
|
||||
seq_putc(m, ' ');
|
||||
|
||||
/* file system type */
|
||||
Index: b/fs/proc/base.c
|
||||
===================================================================
|
||||
--- a/fs/proc/base.c
|
||||
+++ b/fs/proc/base.c
|
||||
@@ -356,13 +356,16 @@ static const struct inode_operations pro
|
||||
.setattr = proc_setattr,
|
||||
};
|
||||
|
||||
+/* Keep in sync with fs/namespace.c! */
|
||||
extern struct seq_operations mounts_op;
|
||||
struct proc_mounts {
|
||||
struct seq_file m;
|
||||
+ void *page;
|
||||
int event;
|
||||
};
|
||||
|
||||
-static int mounts_open(struct inode *inode, struct file *file)
|
||||
+static int __mounts_open(struct inode *inode, struct file *file,
|
||||
+ struct seq_operations *seq_ops)
|
||||
{
|
||||
struct task_struct *task = get_proc_task(inode);
|
||||
struct mnt_namespace *ns = NULL;
|
||||
@@ -385,12 +388,16 @@ static int mounts_open(struct inode *ino
|
||||
p = kmalloc(sizeof(struct proc_mounts), GFP_KERNEL);
|
||||
if (p) {
|
||||
file->private_data = &p->m;
|
||||
- ret = seq_open(file, &mounts_op);
|
||||
+ p->page = (void *)__get_free_page(GFP_KERNEL);
|
||||
+ if (p->page)
|
||||
+ ret = seq_open(file, seq_ops);
|
||||
if (!ret) {
|
||||
p->m.private = ns;
|
||||
p->event = ns->event;
|
||||
return 0;
|
||||
}
|
||||
+ if (p->page)
|
||||
+ free_page((unsigned long)p->page);
|
||||
kfree(p);
|
||||
}
|
||||
put_mnt_ns(ns);
|
||||
@@ -398,17 +405,25 @@ static int mounts_open(struct inode *ino
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int mounts_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ return __mounts_open(inode, file, &mounts_op);
|
||||
+}
|
||||
+
|
||||
static int mounts_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
- struct seq_file *m = file->private_data;
|
||||
- struct mnt_namespace *ns = m->private;
|
||||
+ struct proc_mounts *p =
|
||||
+ container_of(file->private_data, struct proc_mounts, m);
|
||||
+ struct mnt_namespace *ns = p->m.private;
|
||||
+ free_page((unsigned long)p->page);
|
||||
put_mnt_ns(ns);
|
||||
return seq_release(inode, file);
|
||||
}
|
||||
|
||||
static unsigned mounts_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
- struct proc_mounts *p = file->private_data;
|
||||
+ struct proc_mounts *p =
|
||||
+ container_of(file->private_data, struct proc_mounts, m);
|
||||
struct mnt_namespace *ns = p->m.private;
|
||||
unsigned res = 0;
|
||||
|
||||
@@ -435,31 +450,7 @@ static const struct file_operations proc
|
||||
extern struct seq_operations mountstats_op;
|
||||
static int mountstats_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
- int ret = seq_open(file, &mountstats_op);
|
||||
-
|
||||
- if (!ret) {
|
||||
- struct seq_file *m = file->private_data;
|
||||
- struct mnt_namespace *mnt_ns = NULL;
|
||||
- struct task_struct *task = get_proc_task(inode);
|
||||
-
|
||||
- if (task) {
|
||||
- task_lock(task);
|
||||
- if (task->nsproxy)
|
||||
- mnt_ns = task->nsproxy->mnt_ns;
|
||||
- if (mnt_ns)
|
||||
- get_mnt_ns(mnt_ns);
|
||||
- task_unlock(task);
|
||||
- put_task_struct(task);
|
||||
- }
|
||||
-
|
||||
- if (mnt_ns)
|
||||
- m->private = mnt_ns;
|
||||
- else {
|
||||
- seq_release(inode, file);
|
||||
- ret = -EINVAL;
|
||||
- }
|
||||
- }
|
||||
- return ret;
|
||||
+ return __mounts_open(inode, file, &mountstats_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_mountstats_operations = {
|
72
kernel-patches/for-mainline/reintroduce-revalidation.diff
Normal file
72
kernel-patches/for-mainline/reintroduce-revalidation.diff
Normal file
@@ -0,0 +1,72 @@
|
||||
Reintroduce revalidation.
|
||||
|
||||
Index: b/security/apparmor/lsm.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -445,6 +445,55 @@ static int apparmor_inode_removexattr(st
|
||||
MAY_WRITE);
|
||||
}
|
||||
|
||||
+static int apparmor_file_permission(struct file *file, int mask)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
|
||||
+ int error = 0;
|
||||
+
|
||||
+ if (!file_profile)
|
||||
+ goto out;
|
||||
+
|
||||
+ /*
|
||||
+ * If this file was opened under a different profile, we
|
||||
+ * revalidate the access against the current profile.
|
||||
+ */
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile && file_profile != profile) {
|
||||
+ struct dentry *dentry = file->f_dentry;
|
||||
+ struct vfsmount *mnt = file->f_vfsmnt;
|
||||
+
|
||||
+ /*
|
||||
+ * FIXME: We should remember which profiles we revalidated
|
||||
+ * against.
|
||||
+ */
|
||||
+ mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
|
||||
+ error = aa_permission(dentry->d_inode, dentry, mnt, mask, 1);
|
||||
+ }
|
||||
+ aa_put_profile(profile);
|
||||
+
|
||||
+out:
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int apparmor_file_alloc_security(struct file *file)
|
||||
+{
|
||||
+ struct aa_profile *profile;
|
||||
+
|
||||
+ profile = aa_get_profile(current);
|
||||
+ if (profile)
|
||||
+ file->f_security = profile;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void apparmor_file_free_security(struct file *file)
|
||||
+{
|
||||
+ struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
|
||||
+
|
||||
+ aa_put_profile(file_profile);
|
||||
+}
|
||||
+
|
||||
static inline int aa_mmap(struct file *file, unsigned long prot,
|
||||
unsigned long flags)
|
||||
{
|
||||
@@ -668,6 +717,9 @@ struct security_operations apparmor_ops
|
||||
.inode_getxattr = apparmor_inode_getxattr,
|
||||
.inode_listxattr = apparmor_inode_listxattr,
|
||||
.inode_removexattr = apparmor_inode_removexattr,
|
||||
+ .file_permission = apparmor_file_permission,
|
||||
+ .file_alloc_security = apparmor_file_alloc_security,
|
||||
+ .file_free_security = apparmor_file_free_security,
|
||||
.file_mmap = apparmor_file_mmap,
|
||||
.file_mprotect = apparmor_file_mprotect,
|
||||
|
25
kernel-patches/for-mainline/remove-debug-flag.diff
Normal file
25
kernel-patches/for-mainline/remove-debug-flag.diff
Normal file
@@ -0,0 +1,25 @@
|
||||
Index: b/security/apparmor/module_interface.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -383,7 +383,7 @@ static struct aa_profile *aa_activate_pr
|
||||
error_string = "Invalid flags";
|
||||
/* per profile debug flags (debug, complain, audit) */
|
||||
AA_READ_X(e, AA_STRUCT, NULL, "flags");
|
||||
- AA_READ_X(e, AA_U32, &(profile->flags.debug), NULL);
|
||||
+ AA_READ_X(e, AA_U32, NULL, NULL);
|
||||
AA_READ_X(e, AA_U32, &(profile->flags.complain), NULL);
|
||||
AA_READ_X(e, AA_U32, &(profile->flags.audit), NULL);
|
||||
AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
|
||||
Index: b/security/apparmor/apparmor.h
|
||||
===================================================================
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -108,7 +108,6 @@ struct aa_profile {
|
||||
struct list_head list;
|
||||
struct list_head sub;
|
||||
struct {
|
||||
- int debug;
|
||||
int complain;
|
||||
int audit;
|
||||
} flags;
|
112
kernel-patches/for-mainline/rename-profile-lock.diff
Normal file
112
kernel-patches/for-mainline/rename-profile-lock.diff
Normal file
@@ -0,0 +1,112 @@
|
||||
Index: b/security/apparmor/list.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/list.c
|
||||
+++ b/security/apparmor/list.c
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
/* list of all profiles and lock */
|
||||
static LIST_HEAD(profile_list);
|
||||
-static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
|
||||
+static rwlock_t profile_list_lock = RW_LOCK_UNLOCKED;
|
||||
|
||||
/* list of all task_contexts and lock */
|
||||
static LIST_HEAD(task_context_list);
|
||||
@@ -32,9 +32,9 @@ struct aa_profile *aa_profilelist_find(c
|
||||
{
|
||||
struct aa_profile *p = NULL;
|
||||
if (name) {
|
||||
- read_lock(&profile_lock);
|
||||
+ read_lock(&profile_list_lock);
|
||||
p = __aa_find_profile(name, &profile_list);
|
||||
- read_unlock(&profile_lock);
|
||||
+ read_unlock(&profile_list_lock);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ int aa_profilelist_add(struct aa_profile
|
||||
if (!profile)
|
||||
goto out;
|
||||
|
||||
- write_lock(&profile_lock);
|
||||
+ write_lock(&profile_list_lock);
|
||||
old_profile = __aa_find_profile(profile->name, &profile_list);
|
||||
if (old_profile) {
|
||||
aa_put_profile(old_profile);
|
||||
@@ -67,7 +67,7 @@ int aa_profilelist_add(struct aa_profile
|
||||
list_add(&profile->list, &profile_list);
|
||||
ret = 1;
|
||||
out:
|
||||
- write_unlock(&profile_lock);
|
||||
+ write_unlock(&profile_list_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ struct aa_profile *aa_profilelist_remove
|
||||
if (!name)
|
||||
goto out;
|
||||
|
||||
- write_lock(&profile_lock);
|
||||
+ write_lock(&profile_list_lock);
|
||||
list_for_each_entry_safe(p, tmp, &profile_list, list) {
|
||||
if (!strcmp(p->name, name)) {
|
||||
list_del_init(&p->list);
|
||||
@@ -97,7 +97,7 @@ struct aa_profile *aa_profilelist_remove
|
||||
break;
|
||||
}
|
||||
}
|
||||
- write_unlock(&profile_lock);
|
||||
+ write_unlock(&profile_list_lock);
|
||||
|
||||
out:
|
||||
return profile;
|
||||
@@ -118,7 +118,7 @@ struct aa_profile *aa_profilelist_replac
|
||||
{
|
||||
struct aa_profile *oldprofile;
|
||||
|
||||
- write_lock(&profile_lock);
|
||||
+ write_lock(&profile_list_lock);
|
||||
oldprofile = __aa_find_profile(profile->name, &profile_list);
|
||||
if (oldprofile) {
|
||||
list_del_init(&oldprofile->list);
|
||||
@@ -130,7 +130,7 @@ struct aa_profile *aa_profilelist_replac
|
||||
}
|
||||
|
||||
list_add(&profile->list, &profile_list);
|
||||
- write_unlock(&profile_lock);
|
||||
+ write_unlock(&profile_list_lock);
|
||||
|
||||
return oldprofile;
|
||||
}
|
||||
@@ -142,12 +142,12 @@ void aa_profilelist_release(void)
|
||||
{
|
||||
struct aa_profile *p, *tmp;
|
||||
|
||||
- write_lock(&profile_lock);
|
||||
+ write_lock(&profile_list_lock);
|
||||
list_for_each_entry_safe(p, tmp, &profile_list, list) {
|
||||
list_del_init(&p->list);
|
||||
aa_put_profile(p);
|
||||
}
|
||||
- write_unlock(&profile_lock);
|
||||
+ write_unlock(&profile_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +233,7 @@ static void *p_start(struct seq_file *f,
|
||||
struct aa_profile *node;
|
||||
loff_t l = *pos;
|
||||
|
||||
- read_lock(&profile_lock);
|
||||
+ read_lock(&profile_list_lock);
|
||||
list_for_each_entry(node, &profile_list, list)
|
||||
if (!l--)
|
||||
return node;
|
||||
@@ -250,7 +250,7 @@ static void *p_next(struct seq_file *f,
|
||||
|
||||
static void p_stop(struct seq_file *f, void *v)
|
||||
{
|
||||
- read_unlock(&profile_lock);
|
||||
+ read_unlock(&profile_list_lock);
|
||||
}
|
||||
|
||||
static int seq_show_profile(struct seq_file *f, void *v)
|
@@ -27,6 +27,7 @@ security-listxattr.diff
|
||||
vfs-removexattr.diff
|
||||
security-removexattr.diff
|
||||
d_path-lazy-unmounts.diff
|
||||
no-unreachable-paths.diff
|
||||
# security_chroot.diff
|
||||
apparmor-audit.diff
|
||||
apparmor-intree.diff
|
||||
@@ -58,5 +59,9 @@ d_namespace_path.diff
|
||||
apparmor-d_namespace.diff
|
||||
alloc-pathnames.diff
|
||||
# fix-change_hat.diff
|
||||
# apparmor-percpu_path_cache.diff
|
||||
# apparmor-path_resize.diff
|
||||
typo.diff
|
||||
reintroduce-revalidation.diff
|
||||
remove-debug-flag.diff
|
||||
rename-profile-lock.diff
|
||||
match-features.diff
|
||||
match-changes.diff
|
||||
|
13
kernel-patches/for-mainline/typo.diff
Normal file
13
kernel-patches/for-mainline/typo.diff
Normal file
@@ -0,0 +1,13 @@
|
||||
Index: b/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -1087,7 +1087,7 @@ void aa_release(struct task_struct *task
|
||||
|
||||
/**
|
||||
* do_change_hat - actually switch hats
|
||||
- * @hat_name: name of hat to swtich to
|
||||
+ * @hat_name: name of hat to switch to
|
||||
* @cxt: current aa_task_context
|
||||
*
|
||||
* Switch to a new hat. Return %0 on success, error otherwise.
|
Reference in New Issue
Block a user