mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
d_namespace_path fix; rename aa_get_pathname back to aa_get_name. Add tell-files-from-dirs.diff.
This commit is contained in:
parent
79f88b5458
commit
4ca2496f50
15 changed files with 218 additions and 80 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
-
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
139
kernel-patches/for-mainline/tell-files-from-dirs.diff
Normal file
139
kernel-patches/for-mainline/tell-files-from-dirs.diff
Normal 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;
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue