d_namespace_path fix; rename aa_get_pathname back to aa_get_name. Add tell-files-from-dirs.diff.

This commit is contained in:
Andreas Gruenbacher 2007-02-23 07:38:14 +00:00
parent 79f88b5458
commit 4ca2496f50
15 changed files with 218 additions and 80 deletions

View file

@ -66,8 +66,8 @@ Index: b/security/apparmor/main.c
return ret;
}
+static char *aa_get_pathname(struct dentry *dentry, struct vfsmount *mnt,
+ char **buffer)
+static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
+ char **buffer)
+{
+ char *name;
+ int size = 256;
@ -77,7 +77,7 @@ Index: b/security/apparmor/main.c
+ if (!buf)
+ return ERR_PTR(-ENOMEM);
+
+ name = d_namespace_path(dentry, mnt, buf, size, 1);
+ name = d_namespace_path(dentry, mnt, buf, size);
+ if (!IS_ERR(name)) {
+ *buffer = buf;
+ return name;
@ -92,7 +92,7 @@ Index: b/security/apparmor/main.c
+ }
+}
+
+static inline void aa_put_pathname_buffer(char *buffer)
+static inline void aa_put_name_buffer(char *buffer)
+{
+ kfree(buffer);
+}
@ -104,7 +104,7 @@ Index: b/security/apparmor/main.c
int permerror, error;
- sa->name = aa_get_name(dentry, mnt);
+ sa->name = aa_get_pathname(dentry, mnt, &buffer);
+ sa->name = aa_get_name(dentry, mnt, &buffer);
if (IS_ERR(sa->name)) {
permerror = PTR_ERR(sa->name);
@ -113,7 +113,7 @@ Index: b/security/apparmor/main.c
error = aa_audit(profile, sa);
- aa_put_name(sa->name);
+ aa_put_pathname_buffer(buffer);
+ aa_put_name_buffer(buffer);
return error;
}
@ -137,7 +137,7 @@ Index: b/security/apparmor/main.c
- if (!page)
- return ERR_PTR(-ENOMEM);
-
- name = d_namespace_path(dentry, mnt, page, PAGE_SIZE, 1);
- name = d_namespace_path(dentry, mnt, page, PAGE_SIZE);
- if (IS_ERR(name))
- free_page((unsigned long)page);
-
@ -157,8 +157,8 @@ Index: b/security/apparmor/main.c
- sa.name = aa_get_name(link, link_mnt);
- sa.pval = aa_get_name(target, target_mnt);
+ sa.name = aa_get_pathname(link, link_mnt, &name_buffer);
+ sa.pval = aa_get_pathname(target, target_mnt, &pval_buffer);
+ sa.name = aa_get_name(link, link_mnt, &name_buffer);
+ sa.pval = aa_get_name(target, target_mnt, &pval_buffer);
if (IS_ERR(sa.name)) {
permerror = PTR_ERR(sa.name);
@ -168,8 +168,8 @@ Index: b/security/apparmor/main.c
- aa_put_name(sa.name);
- aa_put_name(sa.pval);
+ aa_put_pathname_buffer(name_buffer);
+ aa_put_pathname_buffer(pval_buffer);
+ aa_put_name_buffer(name_buffer);
+ aa_put_name_buffer(pval_buffer);
return error;
}
@ -178,26 +178,25 @@ Index: b/security/apparmor/main.c
int aa_register(struct linux_binprm *bprm)
{
- char *filename;
+ char *filename, *filename_buffer = NULL;
+ char *filename, *buffer = NULL;
struct file *filp = bprm->file;
struct aa_profile *profile;
struct aa_profile *newprofile = NULL, unconstrained_flag;
@@ -784,7 +794,8 @@ int aa_register(struct linux_binprm *bpr
@@ -784,7 +794,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_pathname(filp->f_dentry, filp->f_vfsmnt,
+ &filename_buffer);
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer);
if (IS_ERR(filename)) {
AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
goto out;
@@ -1036,7 +1047,7 @@ apply_profile:
@@ -1036,7 +1046,7 @@ apply_profile:
}
cleanup:
- aa_put_name(filename);
+ aa_put_pathname_buffer(filename_buffer);
+ aa_put_name_buffer(buffer);
aa_put_profile(profile);

View file

@ -35,7 +35,7 @@ Index: b/security/apparmor/main.c
- * The size > deleted_size and strcmp checks are redundant safe guards.
- */
- if (IS_ERR(name)) {
+ name = d_namespace_path(dentry, mnt, page, PAGE_SIZE, 1);
+ name = d_namespace_path(dentry, mnt, page, PAGE_SIZE);
+ if (IS_ERR(name))
free_page((unsigned long)page);
- } else {

View file

@ -6,7 +6,7 @@ Index: b/security/apparmor/main.c
===================================================================
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -1106,14 +1106,6 @@ static inline int do_change_hat(const ch
@@ -1105,14 +1105,6 @@ static inline int do_change_hat(const ch
aa_switch_to_profile(cxt, sub, hat_magic);
aa_put_profile(sub);
} else {
@ -21,7 +21,7 @@ Index: b/security/apparmor/main.c
if (APPARMOR_COMPLAIN(cxt)) {
LOG_HINT(cxt->profile, GFP_ATOMIC, HINT_UNKNOWN_HAT,
"%s pid=%d "
@@ -1133,7 +1125,15 @@ static inline int do_change_hat(const ch
@@ -1132,7 +1124,15 @@ static inline int do_change_hat(const ch
cxt->profile->name);
error = -EACCES;
}

View file

@ -48,9 +48,9 @@ Index: b/security/apparmor/main.c
/**
* aa_register - register a new program
* @bprm: binprm of program being registered
@@ -783,14 +822,8 @@ int aa_register(struct linux_binprm *bpr
@@ -783,156 +822,96 @@ int aa_register(struct linux_binprm *bpr
{
char *filename, *filename_buffer = NULL;
char *filename, *buffer = NULL;
struct file *filp = bprm->file;
- struct aa_profile *profile;
- struct aa_profile *newprofile = NULL, unconstrained_flag;
@ -65,8 +65,7 @@ Index: b/security/apparmor/main.c
AA_DEBUG("%s\n", __FUNCTION__);
@@ -798,142 +831,88 @@ int aa_register(struct linux_binprm *bpr
&filename_buffer);
filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer);
if (IS_ERR(filename)) {
AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
- goto out;
@ -271,7 +270,7 @@ Index: b/security/apparmor/main.c
/* grab a lock - this is to guarentee consistency against
* other writers of aa_task_context (replacement/removal)
*
@@ -962,7 +941,7 @@ apply_profile:
@@ -961,7 +940,7 @@ apply_profile:
if (!lazy_cxt) {
AA_ERROR("%s: Failed to allocate aa_task_context\n",
__FUNCTION__);
@ -280,7 +279,7 @@ Index: b/security/apparmor/main.c
goto cleanup;
}
}
@@ -1000,7 +979,7 @@ apply_profile:
@@ -999,7 +978,7 @@ apply_profile:
* Redo with error checking
*/
spin_unlock_irqrestore(&cxt_lock, flags);
@ -289,7 +288,7 @@ Index: b/security/apparmor/main.c
}
}
@@ -1013,7 +992,7 @@ apply_profile:
@@ -1012,7 +991,7 @@ apply_profile:
* Cases 2 and 3 are marked as requiring secure exec
* (unless policy specified "unsafe exec")
*/
@ -298,7 +297,7 @@ Index: b/security/apparmor/main.c
unsigned long bprm_flags;
bprm_flags = AA_SECURE_EXEC_NEEDED;
@@ -1022,7 +1001,6 @@ apply_profile:
@@ -1021,7 +1000,6 @@ apply_profile:
}
aa_switch_to_profile(cxt, newprofile, 0);
@ -306,10 +305,10 @@ Index: b/security/apparmor/main.c
if (complain && newprofile == null_complain_profile)
LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF,
@@ -1034,11 +1012,11 @@ apply_profile:
@@ -1033,11 +1011,11 @@ apply_profile:
cleanup:
aa_put_pathname_buffer(filename_buffer);
aa_put_name_buffer(buffer);
-
aa_put_profile(profile);
-

View file

@ -9,7 +9,7 @@ Index: b/security/apparmor/main.c
===================================================================
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -816,11 +816,12 @@ int aa_register(struct linux_binprm *bpr
@@ -815,11 +815,12 @@ int aa_register(struct linux_binprm *bpr
/* Confined task, determine what mode inherit, unconstrained or
* mandatory to load new profile
*/
@ -24,7 +24,7 @@ Index: b/security/apparmor/main.c
case AA_EXEC_INHERIT:
/* do nothing - setting of profile
* already handed in aa_fork
@@ -848,21 +849,6 @@ int aa_register(struct linux_binprm *bpr
@@ -847,21 +848,6 @@ int aa_register(struct linux_binprm *bpr
find_profile_mandatory = 1;
break;

View file

@ -38,7 +38,7 @@ Index: b/fs/namespace.c
}
+
+char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+ char *buf, int buflen, int fail_deleted)
+ char *buf, int buflen)
+{
+ char *res;
+ struct vfsmount *rootmnt, *nsrootmnt;
@ -52,7 +52,7 @@ Index: b/fs/namespace.c
+ root = dget(nsrootmnt->mnt_root);
+ spin_unlock(&vfsmount_lock);
+ mntput(rootmnt);
+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 0);
+ res = __d_path(dentry, vfsmnt, root, nsrootmnt, buf, buflen, 1);
+ dput(root);
+ mntput(nsrootmnt);
+ return res;
@ -66,7 +66,7 @@ Index: b/include/linux/mount.h
extern spinlock_t vfsmount_lock;
extern dev_t name_to_dev_t(char *name);
+extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int, int);
+extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int);
+
#endif
#endif /* _LINUX_MOUNT_H */

View file

@ -101,7 +101,7 @@ Index: b/security/apparmor/main.c
return ERR_PTR(-EPERM);
}
} else {
@@ -878,7 +878,7 @@ repeat:
@@ -877,7 +877,7 @@ repeat:
filename,
exec_mode & AA_EXEC_MODIFIERS,
current->comm, current->pid,
@ -110,7 +110,7 @@ Index: b/security/apparmor/main.c
profile->name);
newprofile = ERR_PTR(-EPERM);
break;
@@ -898,7 +898,7 @@ repeat:
@@ -897,7 +897,7 @@ repeat:
__FUNCTION__,
filename,
current->comm, current->pid,
@ -119,7 +119,7 @@ Index: b/security/apparmor/main.c
newprofile = ERR_PTR(-EPERM);
}
} else {
@@ -1067,7 +1067,7 @@ static inline int do_change_hat(const ch
@@ -1066,7 +1066,7 @@ static inline int do_change_hat(const ch
* Note: the profile and sub-profiles cannot go away under us here;
* no need to grab an additional reference count.
*/
@ -128,7 +128,7 @@ Index: b/security/apparmor/main.c
if (sub) {
/* change hat */
aa_switch_to_profile(cxt, sub, hat_magic);
@@ -1078,7 +1078,7 @@ static inline int do_change_hat(const ch
@@ -1077,7 +1077,7 @@ static inline int do_change_hat(const ch
"profile=%s active=%s\n",
hat_name,
current->pid,
@ -137,7 +137,7 @@ Index: b/security/apparmor/main.c
cxt->profile->name);
} else {
AA_DEBUG("%s: Unknown hatname '%s'. "
@@ -1087,7 +1087,7 @@ static inline int do_change_hat(const ch
@@ -1086,7 +1086,7 @@ static inline int do_change_hat(const ch
__FUNCTION__,
hat_name,
current->comm, current->pid,
@ -146,7 +146,7 @@ Index: b/security/apparmor/main.c
cxt->profile->name);
error = -EACCES;
}
@@ -1140,7 +1140,7 @@ int aa_change_hat(const char *hat_name,
@@ -1139,7 +1139,7 @@ int aa_change_hat(const char *hat_name,
}
/* check to see if the confined process has any hats. */
@ -155,7 +155,7 @@ Index: b/security/apparmor/main.c
!PROFILE_COMPLAIN(cxt->profile)) {
error = -ECHILD;
goto out;
@@ -1149,7 +1149,7 @@ int aa_change_hat(const char *hat_name,
@@ -1148,7 +1148,7 @@ int aa_change_hat(const char *hat_name,
/* Check whether current domain is parent
* or one of the sibling children
*/
@ -164,7 +164,7 @@ Index: b/security/apparmor/main.c
/*
* parent
*/
@@ -1204,7 +1204,7 @@ int aa_change_hat(const char *hat_name,
@@ -1203,7 +1203,7 @@ int aa_change_hat(const char *hat_name,
current->comm, current->pid,
hat_magic,
hat_name ? hat_name : "NULL",
@ -173,7 +173,7 @@ Index: b/security/apparmor/main.c
cxt->profile->name);
/* terminate current process */
@@ -1214,7 +1214,7 @@ int aa_change_hat(const char *hat_name,
@@ -1213,7 +1213,7 @@ int aa_change_hat(const char *hat_name,
"Task was confined to current subprofile "
"(profile %s active %s)\n",
current->comm, current->pid,

View file

@ -66,7 +66,7 @@ Index: b/security/apparmor/main.c
spin_unlock_irqrestore(&cxt_lock, flags);
if (APPARMOR_COMPLAIN(cxt) &&
@@ -1000,7 +1000,7 @@ repeat:
@@ -999,7 +999,7 @@ repeat:
((unsigned long)bprm->security | bprm_flags);
}
@ -75,7 +75,7 @@ Index: b/security/apparmor/main.c
if (complain && newprofile == null_complain_profile)
LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF,
@@ -1030,7 +1030,7 @@ cleanup:
@@ -1029,7 +1029,7 @@ cleanup:
* removing a profile from a aa_task_context. Once the aa_task_context has
* been removed from the aa_task_context_list, we are no longer racing other
* writers. There may still be other readers so we must still use
@ -84,7 +84,7 @@ Index: b/security/apparmor/main.c
*/
void aa_release(struct task_struct *task)
{
@@ -1039,7 +1039,7 @@ void aa_release(struct task_struct *task
@@ -1038,7 +1038,7 @@ void aa_release(struct task_struct *task
task->security = NULL;
aa_task_context_list_remove(cxt);
@ -93,7 +93,7 @@ Index: b/security/apparmor/main.c
kfree(cxt);
}
@@ -1070,7 +1070,7 @@ static inline int do_change_hat(const ch
@@ -1069,7 +1069,7 @@ static inline int do_change_hat(const ch
sub = __aa_find_profile(hat_name, &cxt->profile->parent->sub);
if (sub) {
/* change hat */
@ -102,7 +102,7 @@ Index: b/security/apparmor/main.c
} else {
if (APPARMOR_COMPLAIN(cxt)) {
LOG_HINT(cxt->profile, GFP_ATOMIC, HINT_UNKNOWN_HAT,
@@ -1098,8 +1098,7 @@ static inline int do_change_hat(const ch
@@ -1097,8 +1097,7 @@ static inline int do_change_hat(const ch
*
* In learning mode, this allows us to learn about new hats.
*/
@ -112,7 +112,7 @@ Index: b/security/apparmor/main.c
}
return error;
@@ -1187,8 +1186,7 @@ int aa_change_hat(const char *hat_name,
@@ -1186,8 +1185,7 @@ int aa_change_hat(const char *hat_name,
* Got here via changehat(NULL, magic)
* Return from subprofile, back to parent
*/

View file

@ -80,14 +80,14 @@ Index: b/security/apparmor/main.c
@@ -808,7 +813,7 @@ int aa_register(struct linux_binprm *bpr
{
char *filename, *filename_buffer = NULL;
char *filename, *buffer = NULL;
struct file *filp = bprm->file;
- struct aa_profile *profile, *newprofile = NULL;
+ struct aa_profile *profile, *old_profile, *new_profile = NULL;
int exec_mode = AA_EXEC_UNSAFE, complain = 0;
AA_DEBUG("%s\n", __FUNCTION__);
@@ -820,8 +825,8 @@ int aa_register(struct linux_binprm *bpr
@@ -819,8 +824,8 @@ int aa_register(struct linux_binprm *bpr
return -ENOENT;
}
@ -97,7 +97,7 @@ Index: b/security/apparmor/main.c
if (profile) {
complain = PROFILE_COMPLAIN(profile);
@@ -844,16 +849,16 @@ repeat:
@@ -843,16 +848,16 @@ repeat:
__FUNCTION__,
filename);
@ -118,7 +118,7 @@ Index: b/security/apparmor/main.c
break;
default:
@@ -866,7 +871,7 @@ repeat:
@@ -865,7 +870,7 @@ repeat:
current->comm, current->pid,
profile->parent->name,
profile->name);
@ -127,7 +127,7 @@ Index: b/security/apparmor/main.c
break;
}
@@ -875,7 +880,7 @@ repeat:
@@ -874,7 +879,7 @@ repeat:
* describing mode to execute image in.
* Drop into null-profile (disabling secure exec).
*/
@ -136,7 +136,7 @@ Index: b/security/apparmor/main.c
exec_mode |= AA_EXEC_UNSAFE;
} else {
AA_WARN("%s: Rejecting exec(2) of image '%s'. "
@@ -885,117 +890,58 @@ repeat:
@@ -884,117 +889,58 @@ repeat:
filename,
current->comm, current->pid,
profile->parent->name, profile->name);
@ -281,7 +281,7 @@ Index: b/security/apparmor/main.c
}
cleanup:
aa_put_pathname_buffer(filename_buffer);
aa_put_name_buffer(buffer);
- aa_put_profile(profile);
- if (IS_ERR(newprofile))
- return PTR_ERR(newprofile);
@ -292,7 +292,7 @@ Index: b/security/apparmor/main.c
return 0;
}
@@ -1007,7 +953,6 @@ cleanup:
@@ -1006,7 +952,6 @@ cleanup:
*/
void aa_release(struct task_struct *task)
{
@ -300,7 +300,7 @@ Index: b/security/apparmor/main.c
struct aa_profile *profile;
/*
@@ -1025,10 +970,12 @@ void aa_release(struct task_struct *task
@@ -1024,10 +969,12 @@ void aa_release(struct task_struct *task
repeat:
profile = aa_get_profile(task);
if (profile) {
@ -314,7 +314,7 @@ Index: b/security/apparmor/main.c
task_unlock(task);
unlock_profile(profile);
aa_put_profile(profile);
@@ -1043,8 +990,9 @@ repeat:
@@ -1042,8 +989,9 @@ repeat:
list_del(&cxt->list);
unlock_profile(profile);
aa_put_profile(profile);
@ -325,7 +325,7 @@ Index: b/security/apparmor/main.c
}
}
@@ -1075,14 +1023,16 @@ static inline int do_change_hat(const ch
@@ -1074,14 +1022,16 @@ static inline int do_change_hat(const ch
/* change hat */
aa_change_profile(cxt, sub, hat_magic);
} else {
@ -345,7 +345,7 @@ Index: b/security/apparmor/main.c
} else {
AA_DEBUG("%s: Unknown hatname '%s'. "
"Changing to NULL profile "
@@ -1090,8 +1040,8 @@ static inline int do_change_hat(const ch
@@ -1089,8 +1039,8 @@ static inline int do_change_hat(const ch
__FUNCTION__,
hat_name,
current->comm, current->pid,
@ -356,7 +356,7 @@ Index: b/security/apparmor/main.c
error = -EACCES;
}
/*
@@ -1120,57 +1070,49 @@ static inline int do_change_hat(const ch
@@ -1119,57 +1069,49 @@ static inline int do_change_hat(const ch
*/
int aa_change_hat(const char *hat_name, u32 hat_magic)
{
@ -435,7 +435,7 @@ Index: b/security/apparmor/main.c
*
* We used to simply update the magic cookie.
* That's an odd behaviour, so just do nothing.
@@ -1178,17 +1120,16 @@ int aa_change_hat(const char *hat_name,
@@ -1177,17 +1119,16 @@ int aa_change_hat(const char *hat_name,
}
} else {
/*
@ -460,7 +460,7 @@ Index: b/security/apparmor/main.c
aa_change_profile(cxt, cxt->profile->parent, 0);
} else {
/*
@@ -1205,8 +1146,8 @@ int aa_change_hat(const char *hat_name,
@@ -1204,8 +1145,8 @@ int aa_change_hat(const char *hat_name,
current->comm, current->pid,
hat_magic,
hat_name ? hat_name : "NULL",
@ -471,7 +471,7 @@ Index: b/security/apparmor/main.c
/* terminate current process */
(void)send_sig_info(SIGKILL, NULL, current);
@@ -1215,8 +1156,8 @@ int aa_change_hat(const char *hat_name,
@@ -1214,8 +1155,8 @@ int aa_change_hat(const char *hat_name,
"Task was confined to current subprofile "
"(profile %s active %s)\n",
current->comm, current->pid,
@ -482,7 +482,7 @@ Index: b/security/apparmor/main.c
/* terminate current process */
(void)send_sig_info(SIGKILL, NULL, current);
@@ -1225,5 +1166,61 @@ int aa_change_hat(const char *hat_name,
@@ -1224,5 +1165,61 @@ int aa_change_hat(const char *hat_name,
}
out:

View file

@ -329,7 +329,7 @@ Index: b/security/apparmor/main.c
if (APPARMOR_COMPLAIN(cxt) &&
cxt->profile == null_complain_profile)
@@ -911,7 +897,6 @@ repeat:
@@ -910,7 +896,6 @@ repeat:
/* Apply the new profile, or switch to unconfined if NULL. */
if (!IS_ERR(newprofile)) {
struct aa_task_context *cxt, *lazy_cxt = NULL;
@ -337,7 +337,7 @@ Index: b/security/apparmor/main.c
/* grab a lock - this is to guarentee consistency against
* other writers of aa_task_context (replacement/removal)
@@ -937,7 +922,7 @@ repeat:
@@ -936,7 +921,7 @@ repeat:
*/
if (!profile && !(cxt = aa_task_context(current))) {
@ -346,7 +346,7 @@ Index: b/security/apparmor/main.c
if (!lazy_cxt) {
AA_ERROR("%s: Failed to allocate aa_task_context\n",
__FUNCTION__);
@@ -946,13 +931,11 @@ repeat:
@@ -945,13 +930,11 @@ repeat:
}
}
@ -361,7 +361,7 @@ Index: b/security/apparmor/main.c
lazy_cxt = NULL;
} else {
/* Not rcu used to get the write barrier
@@ -978,7 +961,6 @@ repeat:
@@ -977,7 +960,6 @@ repeat:
/* Race, profile was removed, not replaced.
* Redo with error checking
*/
@ -369,7 +369,7 @@ Index: b/security/apparmor/main.c
goto repeat;
}
}
@@ -1006,8 +988,6 @@ repeat:
@@ -1005,8 +987,6 @@ repeat:
LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF,
"pid=%d\n",
current->pid);
@ -378,7 +378,7 @@ Index: b/security/apparmor/main.c
}
cleanup:
@@ -1020,28 +1000,51 @@ cleanup:
@@ -1019,28 +999,51 @@ cleanup:
}
/**

View file

@ -241,7 +241,7 @@ Index: b/security/apparmor/main.c
if (profile) {
AA_DEBUG("%s: setting profile %s\n",
__FUNCTION__, profile->name);
@@ -931,7 +931,7 @@ repeat:
@@ -930,7 +930,7 @@ repeat:
* the transition occured before replacement.
*
* - If newprofile points to an actual profile (result of
@ -250,7 +250,7 @@ Index: b/security/apparmor/main.c
* replaced. We need to fix it up. Doing this to avoid
* having to hold a lock around all this code.
*/
@@ -972,7 +972,7 @@ repeat:
@@ -971,7 +971,7 @@ repeat:
/* drop refcnt obtained from earlier aa_dup_profile */
aa_put_profile(newprofile);
@ -259,7 +259,7 @@ Index: b/security/apparmor/main.c
if (!newprofile) {
/* Race, profile was removed, not replaced.
@@ -1063,12 +1063,14 @@ static inline int do_change_hat(const ch
@@ -1062,12 +1062,14 @@ static inline int do_change_hat(const ch
struct aa_profile *sub;
int error = 0;

View file

@ -80,5 +80,6 @@ rework-locking.diff
rework-locking-2.diff
unreachabe-paths.diff
rename-aa_fork.diff
tell-files-from-dirs.diff
# ptrace.diff
# link-subset-check.diff

View file

@ -0,0 +1,139 @@
Append a slash to the pathname we check against whenever we check
for access to a directory (for whichever operation, not only mkdir
and rmdir). This allows us to tell directories from non-directories
in profiles if we care, e.g.,
/tmp/foo <= a non-directory
/tmp/foo/ <= a directory
/tmp/* <= any non-directory
/tmp/** <= files as well as directories
And more bizarre:
/tmp/**/ <= directories at any depth
/tmp/**[^/] <= non-directories at any depth (not currently
passed through by the pasrer, but you get the
idea)
This prevents proceses from creating directories where they shouldn't,
or dropping entire directory hierarchies into places with rename.
Index: b/security/apparmor/main.c
===================================================================
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -160,17 +160,20 @@ static int aa_link_perm(struct aa_profil
}
static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
- char **buffer)
+ char **buffer, int is_dir)
{
char *name;
int size = 256;
+ /* Make sure is_dir is either 0 or 1. */
+ is_dir = !!is_dir;
+
for (;;) {
char *buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
- name = d_namespace_path(dentry, mnt, buf, size);
+ name = d_namespace_path(dentry, mnt, buf, size - is_dir);
if (!IS_ERR(name)) {
if (name[0] != '/') {
/*
@@ -180,6 +183,16 @@ static char *aa_get_name(struct dentry *
kfree(buf);
return ERR_PTR(-ENOENT);
}
+ if (is_dir && name[1] != '\0') {
+ /*
+ * Append "/" to the pathname. The root
+ * directory is a special case; it already
+ * ends in slash.
+ */
+ buf[size - 2] = '/';
+ buf[size - 1] = '\0';
+ }
+
*buffer = buf;
return name;
}
@@ -199,12 +212,13 @@ static inline void aa_put_name_buffer(ch
}
static int _aa_perm_vfsmount(struct aa_profile *profile, struct dentry *dentry,
- struct vfsmount *mnt, struct aa_audit *sa, int mask)
+ struct vfsmount *mnt, struct aa_audit *sa, int mask,
+ int is_dir)
{
char *buffer = NULL;
int permerror, error;
- sa->name = aa_get_name(dentry, mnt, &buffer);
+ sa->name = aa_get_name(dentry, mnt, &buffer, is_dir);
if (IS_ERR(sa->name)) {
permerror = PTR_ERR(sa->name);
@@ -542,7 +556,8 @@ int aa_attr(struct aa_profile *profile,
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, MAY_WRITE);
+ error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, MAY_WRITE,
+ S_ISDIR(dentry->d_inode->i_mode));
return error;
}
@@ -569,7 +584,8 @@ int aa_perm_xattr(struct aa_profile *pro
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask);
+ error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask,
+ S_ISDIR(dentry->d_inode->i_mode));
return error;
}
@@ -610,7 +626,8 @@ int aa_perm(struct aa_profile *profile,
sa.mask = mask;
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask);
+ error = _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask,
+ S_ISDIR(inode->i_mode));
out:
return error;
@@ -638,7 +655,7 @@ int aa_perm_dir(struct aa_profile *profi
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- return _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask);
+ return _aa_perm_vfsmount(profile, dentry, mnt, &sa, mask, 1);
}
/**
@@ -691,8 +708,8 @@ int aa_link(struct aa_profile *profile,
int permerror = -EPERM, error;
struct aa_audit sa;
- sa.name = aa_get_name(link, link_mnt, &name_buffer);
- sa.pval = aa_get_name(target, target_mnt, &pval_buffer);
+ sa.name = aa_get_name(link, link_mnt, &name_buffer, 0);
+ sa.pval = aa_get_name(target, target_mnt, &pval_buffer, 0);
if (IS_ERR(sa.name)) {
permerror = PTR_ERR(sa.name);
@@ -828,7 +845,7 @@ int aa_register(struct linux_binprm *bpr
AA_DEBUG("%s\n", __FUNCTION__);
- filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer);
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
if (IS_ERR(filename)) {
AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
return -ENOENT;

View file

@ -2,7 +2,7 @@ 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
@@ -1086,7 +1086,7 @@ void aa_release(struct task_struct *task
/**
* do_change_hat - actually switch hats

View file

@ -5,11 +5,11 @@ Index: b/security/apparmor/main.c
===================================================================
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -172,6 +172,14 @@ static char *aa_get_pathname(struct dent
@@ -172,6 +172,14 @@ static char *aa_get_name(struct dentry *
name = d_namespace_path(dentry, mnt, buf, size, 1);
name = d_namespace_path(dentry, mnt, buf, size);
if (!IS_ERR(name)) {
+ if (*name != '/') {
+ if (name[0] != '/') {
+ /*
+ * This dentry is not connected to the
+ * namespace root -- reject access.