mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
fixes to issues that came up in updating the regression tests
This commit is contained in:
parent
063bb1b26e
commit
e102bd2651
7 changed files with 338 additions and 16 deletions
166
kernel-patches/for-mainline/64bit-changehat.diff
Normal file
166
kernel-patches/for-mainline/64bit-changehat.diff
Normal file
|
@ -0,0 +1,166 @@
|
|||
Index: b/security/apparmor/apparmor.h
|
||||
===================================================================
|
||||
--- a/security/apparmor/apparmor.h
|
||||
+++ b/security/apparmor/apparmor.h
|
||||
@@ -141,7 +141,7 @@ extern rwlock_t profile_list_lock;
|
||||
*/
|
||||
struct aa_task_context {
|
||||
struct aa_profile *profile; /* The current profile */
|
||||
- u32 hat_magic; /* used with change_hat */
|
||||
+ u64 hat_magic; /* used with change_hat */
|
||||
struct list_head list;
|
||||
struct task_struct *task;
|
||||
kernel_cap_t caps_logged;
|
||||
@@ -235,7 +235,7 @@ extern int aa_link(struct aa_profile *pr
|
||||
extern int aa_clone(struct task_struct *task);
|
||||
extern int aa_register(struct linux_binprm *bprm);
|
||||
extern void aa_release(struct task_struct *task);
|
||||
-extern int aa_change_hat(const char *id, u32 hat_magic);
|
||||
+extern int aa_change_hat(const char *id, u64 hat_magic);
|
||||
extern struct aa_profile *__aa_find_profile(const char *name,
|
||||
struct list_head *list);
|
||||
extern struct aa_profile *aa_replace_profile(struct task_struct *task,
|
||||
Index: b/security/apparmor/inline.h
|
||||
===================================================================
|
||||
--- a/security/apparmor/inline.h
|
||||
+++ b/security/apparmor/inline.h
|
||||
@@ -69,7 +69,7 @@ static inline struct aa_profile *aa_find
|
||||
*/
|
||||
static inline void aa_change_profile(struct aa_task_context *cxt,
|
||||
struct aa_profile *profile,
|
||||
- u32 hat_magic)
|
||||
+ u64 hat_magic)
|
||||
{
|
||||
struct aa_profile *old_profile = cxt->profile;
|
||||
|
||||
Index: b/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -1035,7 +1035,7 @@ repeat:
|
||||
*/
|
||||
static inline int do_change_hat(const char *hat_name,
|
||||
struct aa_task_context *cxt,
|
||||
- u32 hat_magic)
|
||||
+ u64 hat_magic)
|
||||
{
|
||||
struct aa_profile *sub;
|
||||
int error = 0;
|
||||
@@ -1110,7 +1110,7 @@ static inline int do_change_hat(const ch
|
||||
* return to original top level profile. Returns %0 on success, error
|
||||
* otherwise.
|
||||
*/
|
||||
-int aa_change_hat(const char *hat_name, u32 hat_magic)
|
||||
+int aa_change_hat(const char *hat_name, u64 hat_magic)
|
||||
{
|
||||
struct aa_task_context *cxt;
|
||||
struct aa_profile *profile;
|
||||
@@ -1118,7 +1118,7 @@ int aa_change_hat(const char *hat_name,
|
||||
|
||||
/* Dump out above debugging in WARN mode if we are in AUDIT mode */
|
||||
if (APPARMOR_AUDIT(aa_task_context(current))) {
|
||||
- AA_WARN("%s: %s, 0x%x (pid %d)\n",
|
||||
+ AA_WARN("%s: %s, 0x%llx (pid %d)\n",
|
||||
__FUNCTION__, hat_name ? hat_name : "NULL",
|
||||
hat_magic, current->pid);
|
||||
}
|
||||
@@ -1148,7 +1148,7 @@ repeat:
|
||||
if (profile == profile->parent) {
|
||||
/* We are in the parent profile. */
|
||||
if (hat_name) {
|
||||
- AA_DEBUG("%s: switching to %s, 0x%x\n",
|
||||
+ AA_DEBUG("%s: switching to %s, 0x%llx\n",
|
||||
__FUNCTION__,
|
||||
hat_name,
|
||||
hat_magic);
|
||||
@@ -1188,7 +1188,7 @@ repeat:
|
||||
}
|
||||
} else if (cxt->hat_magic) {
|
||||
AA_ERROR("KILLING process %s(%d) "
|
||||
- "Invalid change_hat() magic# 0x%x "
|
||||
+ "Invalid change_hat() magic# 0x%llx "
|
||||
"(hatname %s profile %s active %s)\n",
|
||||
current->comm, current->pid,
|
||||
hat_magic,
|
||||
Index: b/security/apparmor/procattr.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/procattr.c
|
||||
+++ b/security/apparmor/procattr.c
|
||||
@@ -79,9 +79,8 @@ size_t aa_getprocattr(struct aa_profile
|
||||
int aa_setprocattr_changehat(char *hatinfo, size_t infosize)
|
||||
{
|
||||
int error = -EINVAL;
|
||||
- char *token = NULL, *hat, *smagic, *tmp;
|
||||
- u32 magic;
|
||||
- int rc, len, consumed;
|
||||
+ char *token = NULL, *hat;
|
||||
+ u64 magic;
|
||||
|
||||
AA_DEBUG("%s: %p %zd\n", __FUNCTION__, hatinfo, infosize);
|
||||
|
||||
@@ -92,7 +91,7 @@ int aa_setprocattr_changehat(char *hatin
|
||||
}
|
||||
|
||||
if (infosize == 0)
|
||||
- goto out;
|
||||
+ return -EINVAL;
|
||||
|
||||
/*
|
||||
* Copy string to a new buffer so we can play with it
|
||||
@@ -100,50 +99,19 @@ int aa_setprocattr_changehat(char *hatin
|
||||
* for 100% safety
|
||||
*/
|
||||
token = kmalloc(infosize + 1, GFP_KERNEL);
|
||||
-
|
||||
- if (!token) {
|
||||
- error = -ENOMEM;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
+ if (!token)
|
||||
+ return -ENOMEM;
|
||||
memcpy(token, hatinfo, infosize);
|
||||
token[infosize] = 0;
|
||||
|
||||
- /* error is INVAL until we have at least parsed something */
|
||||
- error = -EINVAL;
|
||||
-
|
||||
- tmp = token;
|
||||
- while (*tmp && *tmp != '^') {
|
||||
- tmp++;
|
||||
- }
|
||||
-
|
||||
- if (!*tmp || tmp == token) {
|
||||
+ magic = simple_strtoull(token, &hat, 16);
|
||||
+ if (hat == token || *hat != '^') {
|
||||
AA_WARN("%s: Invalid input '%s'\n", __FUNCTION__, token);
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* split magic and hat into two strings */
|
||||
- *tmp = 0;
|
||||
- smagic = token;
|
||||
-
|
||||
- /*
|
||||
- * Initially set consumed=strlen(magic), as if sscanf
|
||||
- * consumes all input via the %x it will not process the %n
|
||||
- * directive. Otherwise, if sscanf does not consume all the
|
||||
- * input it will process the %n and update consumed.
|
||||
- */
|
||||
- consumed = len = strlen(smagic);
|
||||
-
|
||||
- rc = sscanf(smagic, "%x%n", &magic, &consumed);
|
||||
-
|
||||
- if (rc != 1 || consumed != len) {
|
||||
- AA_WARN("%s: Invalid hex magic %s\n",
|
||||
- __FUNCTION__,
|
||||
- smagic);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- hat = tmp + 1;
|
||||
+ /* skip ^ */
|
||||
+ hat++;
|
||||
|
||||
if (!*hat)
|
||||
hat = NULL;
|
|
@ -2,21 +2,12 @@ Index: b/security/apparmor/lsm.c
|
|||
===================================================================
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -150,7 +150,7 @@ static int apparmor_sysctl(struct ctl_ta
|
||||
int error = 0;
|
||||
|
||||
if ((op & 002) && !capable(CAP_SYS_ADMIN))
|
||||
- error = aa_reject_syscall(current, GFP_KERNEL,
|
||||
+ error = aa_reject_syscall(current, GFP_ATOMIC,
|
||||
"sysctl (write)");
|
||||
|
||||
return error;
|
||||
@@ -202,7 +202,7 @@ static int apparmor_bprm_secureexec(stru
|
||||
static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
|
||||
unsigned long flags, void *data)
|
||||
{
|
||||
- return aa_reject_syscall(current, GFP_KERNEL, "mount");
|
||||
+ return aa_reject_syscall(current, GFP_ATOMIC, "mount");
|
||||
}
|
||||
@@ -207,7 +207,7 @@ static int apparmor_sb_mount(char *dev_n
|
||||
|
||||
static int apparmor_umount(struct vfsmount *mnt, int flags)
|
||||
{
|
||||
- return aa_reject_syscall(current, GFP_ATOMIC, "umount");
|
||||
+ return aa_reject_syscall(current, GFP_KERNEL, "umount");
|
||||
}
|
||||
|
||||
static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry,
|
||||
|
|
14
kernel-patches/for-mainline/dir-leaf-nodes.diff
Normal file
14
kernel-patches/for-mainline/dir-leaf-nodes.diff
Normal file
|
@ -0,0 +1,14 @@
|
|||
Index: b/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -649,7 +649,8 @@ int aa_perm_dir(struct aa_profile *profi
|
||||
sa.flags = 0;
|
||||
sa.gfp_mask = GFP_KERNEL;
|
||||
|
||||
- return aa_perm_dentry(profile, dentry, mnt, &sa, mask, AA_CHECK_DIR);
|
||||
+ return aa_perm_dentry(profile, dentry, mnt, &sa, mask,
|
||||
+ AA_CHECK_DIR | AA_CHECK_LEAF);
|
||||
}
|
||||
|
||||
/**
|
90
kernel-patches/for-mainline/fix-change_hat-replacement.diff
Normal file
90
kernel-patches/for-mainline/fix-change_hat-replacement.diff
Normal file
|
@ -0,0 +1,90 @@
|
|||
Index: b/security/apparmor/main.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/main.c
|
||||
+++ b/security/apparmor/main.c
|
||||
@@ -1048,6 +1048,14 @@ static inline int do_change_hat(const ch
|
||||
if (sub) {
|
||||
/* change hat */
|
||||
aa_change_profile(cxt, sub, hat_magic);
|
||||
+ /*
|
||||
+ * aa_change_profile switches profile lists but we don't
|
||||
+ * want this for change_hat. Switch back to the parents
|
||||
+ * list.
|
||||
+ * FIXME: update to a full profile change mechanism
|
||||
+ * to get rid of this special casing
|
||||
+ */
|
||||
+ list_move(&cxt->list, &sub->parent->task_contexts);
|
||||
} else {
|
||||
struct aa_profile *profile = cxt->profile;
|
||||
|
||||
@@ -1078,6 +1086,14 @@ static inline int do_change_hat(const ch
|
||||
* In learning mode, this allows us to learn about new hats.
|
||||
*/
|
||||
aa_change_profile(cxt, cxt->profile->null_profile, hat_magic);
|
||||
+ /*
|
||||
+ * aa_change_profile switches profile lists but we don't
|
||||
+ * want this for change_hat. Switch back to the parents
|
||||
+ * list.
|
||||
+ * FIXME: update to a full profile change mechanism
|
||||
+ * to get rid of this special casing
|
||||
+ */
|
||||
+ list_move(&cxt->list, &cxt->profile->parent->task_contexts);
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -1157,6 +1173,11 @@ repeat:
|
||||
if (!hat_name) {
|
||||
/* Return from subprofile back to parent. */
|
||||
aa_change_profile(cxt, cxt->profile->parent, 0);
|
||||
+ /*
|
||||
+ * switching lists is not needed here because
|
||||
+ * aa_change_profile list move will leave the
|
||||
+ * cxt on the correct list
|
||||
+ */
|
||||
} else {
|
||||
/*
|
||||
* Change to another (sibling) profile, and
|
||||
Index: b/security/apparmor/module_interface.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/module_interface.c
|
||||
+++ b/security/apparmor/module_interface.c
|
||||
@@ -57,6 +57,14 @@ static inline void task_replace(struct a
|
||||
hat = aa_dup_profile(new_profile->null_profile);
|
||||
|
||||
aa_change_profile(cxt, hat, cxt->hat_magic);
|
||||
+ /*
|
||||
+ * aa_change_profile switches profile lists but we don't
|
||||
+ * want this for change_hat. Switch back to the parents
|
||||
+ * list.
|
||||
+ * FIXME: update to a full profile change mechanism
|
||||
+ * to get rid of this special casing
|
||||
+ */
|
||||
+ list_move(&cxt->list, &hat->parent->task_contexts);
|
||||
aa_put_profile(hat);
|
||||
} else
|
||||
aa_change_profile(cxt, new_profile, cxt->hat_magic);
|
||||
@@ -451,7 +459,14 @@ ssize_t aa_file_prof_replace(void *udata
|
||||
write_lock(&profile_list_lock);
|
||||
old_profile = __aa_find_profile(new_profile->name, &profile_list);
|
||||
if (old_profile) {
|
||||
- lock_profile(old_profile);
|
||||
+ /*
|
||||
+ * new_profile needs to be locked in the case that there
|
||||
+ * are multiple tasks on old_profiles list, this avoids
|
||||
+ * a race between an already replaced task changing its
|
||||
+ * profile (updating the list) and replacement updating
|
||||
+ * the list
|
||||
+ */
|
||||
+ lock_both_profiles(old_profile, new_profile);
|
||||
old_profile->isstale = 1;
|
||||
while (!list_empty(&old_profile->task_contexts)) {
|
||||
struct aa_task_context *cxt =
|
||||
@@ -461,7 +476,7 @@ ssize_t aa_file_prof_replace(void *udata
|
||||
task_replace(cxt, new_profile);
|
||||
task_unlock(cxt->task);
|
||||
}
|
||||
- unlock_profile(old_profile);
|
||||
+ unlock_both_profiles(old_profile, new_profile);
|
||||
|
||||
list_del_init(&old_profile->list);
|
||||
aa_put_profile(old_profile);
|
31
kernel-patches/for-mainline/fix-vfs_rmdir.diff
Normal file
31
kernel-patches/for-mainline/fix-vfs_rmdir.diff
Normal file
|
@ -0,0 +1,31 @@
|
|||
Index: b/fs/namei.c
|
||||
===================================================================
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -2016,6 +2016,10 @@ int vfs_rmdir(struct inode *dir, struct
|
||||
if (!dir->i_op || !dir->i_op->rmdir)
|
||||
return -EPERM;
|
||||
|
||||
+ error = security_inode_rmdir(dir, dentry, mnt);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
DQUOT_INIT(dir);
|
||||
|
||||
mutex_lock(&dentry->d_inode->i_mutex);
|
||||
@@ -2023,12 +2027,9 @@ int vfs_rmdir(struct inode *dir, struct
|
||||
if (d_mountpoint(dentry))
|
||||
error = -EBUSY;
|
||||
else {
|
||||
- error = security_inode_rmdir(dir, dentry, mnt);
|
||||
- if (!error) {
|
||||
- error = dir->i_op->rmdir(dir, dentry);
|
||||
- if (!error)
|
||||
- dentry->d_inode->i_flags |= S_DEAD;
|
||||
- }
|
||||
+ error = dir->i_op->rmdir(dir, dentry);
|
||||
+ if (!error)
|
||||
+ dentry->d_inode->i_flags |= S_DEAD;
|
||||
}
|
||||
mutex_unlock(&dentry->d_inode->i_mutex);
|
||||
if (!error) {
|
|
@ -0,0 +1,25 @@
|
|||
Index: b/security/apparmor/lsm.c
|
||||
===================================================================
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -333,9 +333,18 @@ static int apparmor_inode_rename(struct
|
||||
error = aa_perm(profile, old_dentry, old_mnt,
|
||||
MAY_READ | MAY_WRITE, AA_CHECK_LEAF);
|
||||
|
||||
- if (!error && new_mnt)
|
||||
+ if (!error && new_mnt) {
|
||||
+ int check = 0;
|
||||
+ /*
|
||||
+ * if the new_dentry doesn't exist force it to be the
|
||||
+ * same file/dir type as old_dentry
|
||||
+ */
|
||||
+ if (!new_dentry->d_inode && old_dentry->d_inode &&
|
||||
+ S_ISDIR(old_dentry->d_inode->i_mode))
|
||||
+ check = AA_CHECK_DIR;
|
||||
error = aa_perm(profile, new_dentry, new_mnt,
|
||||
- MAY_WRITE, AA_CHECK_LEAF);
|
||||
+ MAY_WRITE, check | AA_CHECK_LEAF);
|
||||
+ }
|
||||
}
|
||||
|
||||
aa_put_profile(profile);
|
|
@ -102,3 +102,8 @@ file-handle-ops.diff
|
|||
file-handle-ops-2.diff
|
||||
# unlink.diff
|
||||
coding-style.diff
|
||||
dir-leaf-nodes.diff
|
||||
force_dir_on_negative_dentry.diff
|
||||
fix-vfs_rmdir.diff
|
||||
fix-change_hat-replacement.diff
|
||||
64bit-changehat.diff
|
||||
|
|
Loading…
Add table
Reference in a new issue