mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-05 08:45:22 +00:00
162 lines
4.8 KiB
Diff
162 lines
4.8 KiB
Diff
Index: linux-2.6/security/apparmor/apparmor.h
|
|
===================================================================
|
|
--- linux-2.6.orig/security/apparmor/apparmor.h
|
|
+++ linux-2.6/security/apparmor/apparmor.h
|
|
@@ -255,7 +255,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
|
|
@@ -220,9 +220,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
|
|
@@ -454,8 +454,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);
|
|
@@ -468,7 +469,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;
|
|
}
|
|
@@ -794,27 +795,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;
|
|
@@ -828,6 +839,8 @@ char *aa_get_name(struct dentry *dentry,
|
|
}
|
|
|
|
out:
|
|
+ if (order > 0)
|
|
+ *addr = buffer;
|
|
return name;
|
|
}
|
|
|
|
@@ -986,9 +999,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);
|
|
@@ -1010,8 +1024,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;
|
|
}
|
|
@@ -1078,6 +1092,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;
|
|
@@ -1090,7 +1105,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;
|
|
@@ -1339,7 +1354,7 @@ apply_profile:
|
|
}
|
|
|
|
cleanup:
|
|
- aa_put_name(filename);
|
|
+ aa_put_name(filename, addr);
|
|
|
|
put_aaprofile(active);
|
|
|