2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 22:05:27 +00:00

Add missing patches; new mostly-cosmetic one

This commit is contained in:
Andreas Gruenbacher
2007-04-08 17:50:13 +00:00
parent 6c06fbe63c
commit 9597b4192f
8 changed files with 953 additions and 10 deletions

View File

@@ -0,0 +1,237 @@
---
security/apparmor/apparmorfs.c | 10 ++++++----
security/apparmor/locking.txt | 14 ++++++++++----
security/apparmor/lsm.c | 4 +---
security/apparmor/match.c | 31 +++++++++++++------------------
security/apparmor/module_interface.c | 26 +++++++++++++++++---------
5 files changed, 47 insertions(+), 38 deletions(-)
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -31,7 +31,8 @@ static char *aa_simple_write_to_buffer(c
goto out;
}
- /* Don't allow confined processes to load/replace/remove profiles.
+ /*
+ * Don't allow confined processes to load/replace/remove profiles.
* No sane person would add rules allowing this to a profile
* but we enforce the restriction anyways.
*/
@@ -151,10 +152,11 @@ static ssize_t aa_profile_remove(struct
char *data;
ssize_t error;
- /* aa_file_prof_remove needs a null terminated string so 1 extra
- * byte is allocated and the copied data is then null terminated
+ /*
+ * aa_remove_profile needs a null terminated string so 1 extra
+ * byte is allocated and the copied data is null terminated.
*/
- data = aa_simple_write_to_buffer(buf, size+1, size, pos, "removal");
+ data = aa_simple_write_to_buffer(buf, size + 1, size, pos, "removal");
error = PTR_ERR(data);
if (!IS_ERR(data)) {
--- a/security/apparmor/locking.txt
+++ b/security/apparmor/locking.txt
@@ -3,9 +3,10 @@ Locking in AppArmor
Lock hierarchy:
- profile_list_lock
- aa_profile->lock
- task_lock()
+ aa_interface_lock
+ profile_list_lock
+ aa_profile->lock
+ task_lock()
Which lock protects what?
@@ -13,7 +14,7 @@ Which lock protects what?
/-----------------------+-------------------------------\
| Variable | Lock |
>-----------------------+-------------------------------<
- | profile_list, | profile_list_lock |
+ | profile_list | profile_list_lock |
+-----------------------+-------------------------------+
| aa_profile | (reference count) |
+-----------------------+-------------------------------+
@@ -44,3 +45,8 @@ is used.
Profiles on profile_list are never stale: when a profile becomes stale,
it is removed from profile_list at the same time (under profile_list_lock
and aa_profile->lock).
+
+The aa_interface_lock is taken whenever user-space modifies the profile
+list, and can sleep. This ensures that profile loading/replacement/removal
+won't race with itself. We release the profile_list_lock as soon as
+possible to avoid stalling exec during profile loading/replacement/removal.
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -6,9 +6,7 @@
* published by the Free Software Foundation, version 2 of the
* License.
*
- * http://forge.novell.com/modules/xfmod/project/?apparmor
- *
- * Immunix AppArmor LSM interface
+ * AppArmor LSM interface
*/
#include <linux/security.h>
--- a/security/apparmor/match.c
+++ b/security/apparmor/match.c
@@ -6,14 +6,12 @@
* published by the Free Software Foundation, version 2 of the
* License.
*
- * http://forge.novell.com/modules/xfmod/project/?apparmor
- *
- * AppArmor aa_match submodule (w/ pattern expansion).
- *
+ * Regular expression transition table matching
*/
-#include <asm/unaligned.h>
-#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
#include "match.h"
static struct table_header *unpack_table(void *blob, size_t bsize)
@@ -75,6 +73,7 @@ int unpack_dfa(struct aa_dfa *dfa, void
blob += hsize;
size -= hsize;
+ error = -EPROTO;
while (size > 0) {
struct table_header *table;
table = unpack_table(blob, size);
@@ -86,37 +85,33 @@ int unpack_dfa(struct aa_dfa *dfa, void
case YYTD_ID_BASE:
dfa->tables[table->td_id - 1] = table;
if (table->td_flags != YYTD_DATA32)
- goto fail_proto;
+ goto fail;
break;
case YYTD_ID_DEF:
case YYTD_ID_NXT:
case YYTD_ID_CHK:
dfa->tables[table->td_id - 1] = table;
if (table->td_flags != YYTD_DATA16)
- goto fail_proto;
+ goto fail;
break;
case YYTD_ID_EC:
dfa->tables[table->td_id - 1] = table;
if (table->td_flags != YYTD_DATA8)
- goto fail_proto;
+ goto fail;
break;
default:
kfree(table);
- goto fail_proto;
+ goto fail;
}
blob += table_size(table->td_lolen, table->td_flags);
size -= table_size(table->td_lolen, table->td_flags);
}
- error = 0;
-
- return error;
+ return 0;
-fail_proto:
- error = -EPROTO;
fail:
- for (i = 0; i < YYTD_ID_NXT; i++) {
+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
if (dfa->tables[i]) {
kfree(dfa->tables[i]);
dfa->tables[i] = NULL;
@@ -189,9 +184,9 @@ void aa_match_free(struct aa_dfa *dfa)
{
if (dfa) {
int i;
- for (i = 0; i < YYTD_ID_NXT; i++) {
+
+ for (i = 0; i < ARRAY_SIZE(dfa->tables); i++)
kfree(dfa->tables[i]);
- }
}
kfree(dfa);
}
--- a/security/apparmor/module_interface.c
+++ b/security/apparmor/module_interface.c
@@ -23,7 +23,8 @@
*/
DEFINE_MUTEX(aa_interface_lock);
-/* The AppArmor interface treats data as a type byte followed by the
+/*
+ * The AppArmor interface treats data as a type byte followed by the
* actual data. The interface has the notion of a a named entry
* which has a name (AA_NAME typecode followed by name string) followed by
* the entries typecode and data. Named types allow for optional
@@ -45,7 +46,8 @@ enum aa_code {
AA_LISTEND,
};
-/* aa_ext is the read of the buffer containing the serialized profile. The
+/*
+ * aa_ext is the read of the buffer containing the serialized profile. The
* data is copied into a kernel buffer in apparmorfs and then handed off to
* the unpack routines.
*/
@@ -116,8 +118,10 @@ static inline int aa_is_X(struct aa_ext
static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name)
{
void *pos = e->pos;
- /* check for presence of a tagname, and if present name size
- * AA_NAME tag value is a u16 */
+ /*
+ * Check for presence of a tagname, and if present name size
+ * AA_NAME tag value is a u16.
+ */
if (aa_is_X(e, AA_NAME)) {
char *tag;
size_t size = aa_is_u16_chunk(e, &tag);
@@ -212,8 +216,9 @@ struct aa_dfa *aa_unpack_dfa(struct aa_e
if (size) {
dfa = aa_match_alloc();
if (dfa) {
- /* the dfa is aligned with in the blob to 8 bytes
- * from the beginning of the stream
+ /*
+ * The dfa is aligned with in the blob to 8 bytes
+ * from the beginning of the stream.
*/
size_t sz = blob - (char *) e->start;
size_t pad = ALIGN(sz, 8) - sz;
@@ -410,8 +415,10 @@ static inline void task_replace(struct t
if (cxt->profile != cxt->profile->parent) {
struct aa_profile *hat;
- /* The old profile was in a hat, check to see if the new
- * profile has an equivalent hat */
+ /*
+ * The old profile was in a hat, check to see if the new
+ * profile has an equivalent hat.
+ */
hat = __aa_find_profile(cxt->profile->name, &new_profile->sub);
if (!hat)
@@ -595,7 +602,8 @@ void free_aa_profile(struct aa_profile *
aa_match_free(profile->file_rules);
- /* use free_aa_profile instead of aa_put_profile to destroy the
+ /*
+ * Use free_aa_profile instead of aa_put_profile to destroy the
* null_profile, because the null_profile use the same reference
* counting as hats, ie. the count goes to the base profile.
*/

View File

@@ -0,0 +1,364 @@
---
security/apparmor/apparmor.h | 16 ++++++--
security/apparmor/apparmorfs.c | 2 -
security/apparmor/lsm.c | 25 ++++--------
security/apparmor/main.c | 70 +++++++++++------------------------
security/apparmor/module_interface.c | 6 +--
security/apparmor/procattr.c | 27 +++++--------
6 files changed, 57 insertions(+), 89 deletions(-)
--- linux-2.6.orig/security/apparmor/apparmor.h
+++ linux-2.6/security/apparmor/apparmor.h
@@ -74,6 +74,13 @@ extern int apparmor_path_max;
#define AA_WARN(gfp, fmt, args...) \
aa_audit_message(NULL, gfp, 0, fmt, ##args);
+#define AA_REJECT_MSG(p, gfp, fmt, args...) \
+ aa_audit_message(p, gfp, 0, \
+ "REJECTING " fmt \
+ " (%s(%d) profile %s active %s)", ##args, \
+ current->comm, current->pid, \
+ (p)->parent->name, (p)->name)
+
#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
/* struct aa_profile - basic confinement data
@@ -192,10 +199,11 @@ struct aa_audit {
#define HINT_PTRACE "ptrace"
#define LOG_HINT(p, gfp, hint, fmt, args...) \
- do {\
- aa_audit_message(p, gfp, 0, \
- "LOGPROF-HINT " hint " " fmt, ##args);\
- } while(0)
+ aa_audit_message(p, gfp, 0, \
+ "LOGPROF-HINT " hint " " fmt \
+ " (%s(%d) profile %s active %s)", ##args, \
+ current->comm, current->pid, \
+ (p)->parent->name, (p)->name)
/* Flags for the permission check functions */
#define AA_CHECK_LEAF 1 /* this is the leaf lookup component */
--- linux-2.6.orig/security/apparmor/apparmorfs.c
+++ linux-2.6/security/apparmor/apparmorfs.c
@@ -38,7 +38,7 @@ static char *aa_simple_write_to_buffer(c
profile = aa_get_profile(current);
if (profile) {
AA_WARN(GFP_KERNEL, "REJECTING access to profile %s (%s(%d) "
- "profile %s active %s)\n",
+ "profile %s active %s)",
msg, current->comm, current->pid,
profile->parent->name, profile->name);
aa_put_profile(profile);
--- linux-2.6.orig/security/apparmor/lsm.c
+++ linux-2.6/security/apparmor/lsm.c
@@ -622,9 +622,8 @@ static int apparmor_setprocattr(struct t
if (strcmp(command, "changehat") == 0) {
if (current != task) {
AA_WARN(GFP_KERNEL,
- "%s: Attempt by foreign task %s(%d) "
- "[user %d] to changehat of task %s(%d)\n",
- __FUNCTION__,
+ "Attempt by foreign task %s(%d) "
+ "[user %d] to changehat of task %s(%d)",
current->comm,
current->pid,
current->uid,
@@ -643,9 +642,8 @@ static int apparmor_setprocattr(struct t
if (!capable(CAP_SYS_ADMIN)) {
AA_WARN(GFP_KERNEL,
- "%s: Unprivileged attempt by task %s(%d) "
- "[user %d] to assign profile to task %s(%d)\n",
- __FUNCTION__,
+ "Unprivileged attempt by task %s(%d) "
+ "[user %d] to assign profile to task %s(%d)",
current->comm,
current->pid,
current->uid,
@@ -658,9 +656,8 @@ static int apparmor_setprocattr(struct t
if (profile) {
aa_put_profile(profile);
AA_WARN(GFP_KERNEL,
- "%s: Attempt by confined task %s(%d) "
- "[user %d] to assign profile to task %s(%d)\n",
- __FUNCTION__,
+ "Attempt by confined task %s(%d) "
+ "[user %d] to assign profile to task %s(%d)",
current->comm,
current->pid,
current->uid,
@@ -670,9 +667,8 @@ static int apparmor_setprocattr(struct t
}
error = aa_setprocattr_setprofile(task, args);
} else {
- AA_WARN(GFP_KERNEL, "%s: Unknown setprocattr command '%.*s' "
- "by task %s(%d) [user %d] for task %s(%d)\n",
- __FUNCTION__,
+ AA_ERROR("Unknown setprocattr command '%.*s' "
+ "by task %s(%d) [user %d] for task %s(%d)",
size < 16 ? (int)size : 16,
command,
current->comm,
@@ -759,9 +755,6 @@ static int __init apparmor_init(void)
AA_INFO(GFP_KERNEL, "AppArmor initialized%s\n",
apparmor_complain ? complainmsg : "");
- aa_audit_message(NULL, GFP_KERNEL, 0,
- "AppArmor initialized%s\n",
- apparmor_complain ? complainmsg : "");
return error;
@@ -816,8 +809,6 @@ static void __exit apparmor_exit(void)
"AppArmor\n");
AA_INFO(GFP_KERNEL, "AppArmor protection removed\n");
- aa_audit_message(NULL, GFP_KERNEL, 0,
- "AppArmor protection removed\n");
}
module_init(apparmor_init);
--- linux-2.6.orig/security/apparmor/main.c
+++ linux-2.6/security/apparmor/main.c
@@ -802,11 +802,9 @@ repeat:
unlock_profile(profile);
if (APPARMOR_COMPLAIN(child_cxt) &&
- profile == null_complain_profile) {
+ profile == null_complain_profile)
LOG_HINT(profile, GFP_KERNEL, HINT_FORK,
- "pid=%d child=%d\n",
- current->pid, child->pid);
- }
+ "child=%d", child->pid);
aa_put_profile(profile);
} else
aa_free_task_context(child_cxt);
@@ -828,26 +826,20 @@ aa_register_find(struct aa_profile *prof
} else if (mandatory && profile) {
if (complain) {
LOG_HINT(profile, GFP_KERNEL, HINT_MANDPROF,
- "image=%s pid=%d profile=%s active=%s\n",
- name,
- current->pid,
- profile->parent->name, profile->name);
-
+ "image '%s'", name);
profile = aa_dup_profile(null_complain_profile);
} else {
- AA_WARN(GFP_KERNEL, "REJECTING exec(2) of image '%s'. "
- "Profile mandatory and not found "
- "(%s(%d) profile %s active %s)\n",
- name,
- current->comm, current->pid,
- profile->parent->name, profile->name);
+ AA_REJECT_MSG(profile, GFP_KERNEL,
+ "exec(2) of image '%s'. "
+ "Profile mandatory and not found.",
+ name);
return ERR_PTR(-EPERM);
}
} else {
/* Only way we can get into this code is if task
* is unconfined.
*/
- AA_DEBUG("%s: No profile found for exec image %s\n",
+ AA_DEBUG("%s: No profile found for exec image '%s'\n",
__FUNCTION__,
name);
}
@@ -872,8 +864,7 @@ int aa_register(struct linux_binprm *bpr
filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0);
if (IS_ERR(filename)) {
- AA_WARN(GFP_KERNEL, "%s: Failed to get filename\n",
- __FUNCTION__);
+ AA_ERROR("%s: Failed to get filename", __FUNCTION__);
return -ENOENT;
}
@@ -915,10 +906,9 @@ repeat:
break;
default:
- AA_ERROR("%s: Rejecting exec(2) of image '%s'. "
+ AA_ERROR("Rejecting exec(2) of image '%s'. "
"Unknown exec qualifier %x "
"(%s (pid %d) profile %s active %s)\n",
- __FUNCTION__,
filename,
exec_mode & AA_EXEC_MODIFIERS,
current->comm, current->pid,
@@ -936,14 +926,10 @@ repeat:
new_profile = aa_dup_profile(null_complain_profile);
exec_mode |= AA_EXEC_UNSAFE;
} else {
- AA_WARN(GFP_KERNEL,
- "%s: Rejecting exec(2) of image '%s'. "
- "Unable to determine exec qualifier "
- "(%s (pid %d) profile %s active %s)\n",
- __FUNCTION__,
- filename,
- current->comm, current->pid,
- profile->parent->name, profile->name);
+ AA_REJECT_MSG(profile, GFP_KERNEL,
+ "exec(2) of image '%s'. "
+ "Unable to determine exec qualifier.",
+ filename);
new_profile = ERR_PTR(-EPERM);
}
} else {
@@ -963,13 +949,10 @@ repeat:
if (PTR_ERR(old_profile) == -ESTALE)
goto repeat;
if (PTR_ERR(old_profile) == -EPERM)
- AA_WARN(GFP_KERNEL,
- "Rejecting exec(2) of image '%s'. "
- "Unable to change profile due to ptrace. ",
- "(%s (pid %d) profile %s active %s)\n",
- filename,
- current->comm, current->pid,
- profile->parent->name, profile->name);
+ AA_REJECT_MSG(profile, GFP_KERNEL,
+ "exec(2) of image '%s'. "
+ "Unable to change profile due to ptrace.",
+ filename);
new_profile = old_profile;
goto cleanup;
}
@@ -993,11 +976,9 @@ repeat:
((unsigned long)bprm->security | bprm_flags);
}
- if (complain && new_profile == null_complain_profile) {
+ if (complain && new_profile == null_complain_profile)
LOG_HINT(new_profile, GFP_ATOMIC, HINT_CHGPROF,
- "pid=%d\n",
- current->pid);
- }
+ "");
cleanup:
aa_put_name_buffer(buffer);
@@ -1085,12 +1066,7 @@ static int do_change_hat(const char *hat
if (APPARMOR_COMPLAIN(cxt)) {
LOG_HINT(profile, GFP_ATOMIC, HINT_UNKNOWN_HAT,
- "%s pid=%d "
- "profile=%s active=%s\n",
- hat_name,
- current->pid,
- profile->parent->name,
- profile->name);
+ "%s", hat_name);
} else {
AA_DEBUG("%s: Unknown hatname '%s'. "
"Changing to NULL profile "
@@ -1135,8 +1111,8 @@ 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(GFP_KERNEL, "%s: %s, 0x%llx (pid %d)\n",
- __FUNCTION__, hat_name ? hat_name : "NULL",
+ AA_WARN(GFP_KERNEL, "changehat %s, 0x%llx (pid %d)",
+ hat_name ? hat_name : "NULL",
hat_magic, current->pid);
}
--- linux-2.6.orig/security/apparmor/module_interface.c
+++ linux-2.6/security/apparmor/module_interface.c
@@ -297,7 +297,7 @@ static struct aa_profile *aa_unpack_prof
return profile;
fail:
- AA_WARN(GFP_KERNEL, "Invalid profile %s\n",
+ AA_WARN(GFP_KERNEL, "Invalid profile %s",
profile && profile->name ? profile->name : "unknown");
if (profile)
@@ -338,14 +338,14 @@ static int aa_verify_header(struct aa_ex
{
/* get the interface version */
if (!aa_is_u32(e, &e->version, "version")) {
- AA_WARN(GFP_KERNEL, "Interface version missing\n");
+ AA_WARN(GFP_KERNEL, "Interface version missing");
return -EPROTONOSUPPORT;
}
/* check that the interface version is currently supported */
if (e->version != 3) {
AA_WARN(GFP_KERNEL,
- "Unsupported interface version (%d)\n", e->version);
+ "Unsupported interface version (%d)", e->version);
return -EPROTONOSUPPORT;
}
return 0;
--- linux-2.6.orig/security/apparmor/procattr.c
+++ linux-2.6/security/apparmor/procattr.c
@@ -61,17 +61,14 @@ int aa_setprocattr_changehat(char *args)
magic = simple_strtoull(args, &hat, 16);
if (hat == args || *hat != '^') {
- AA_WARN(GFP_KERNEL, "%s: Invalid input '%s'\n",
- __FUNCTION__, args);
+ AA_ERROR("change_hat: Invalid input '%s'", args);
return -EINVAL;
}
hat++; /* skip ^ */
if (!*hat)
hat = NULL;
if (!hat && !magic) {
- AA_WARN(GFP_KERNEL,
- "%s: Invalid input, NULL hat and NULL magic\n",
- __FUNCTION__);
+ AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic");
return -EINVAL;
}
@@ -95,9 +92,8 @@ repeat:
new_profile = aa_find_profile(args);
if (!new_profile) {
AA_WARN(GFP_KERNEL,
- "%s: Unable to switch task %s(%d) to profile"
- "'%s'. No such profile.\n",
- __FUNCTION__,
+ "Unable to switch task %s(%d) to profile"
+ "'%s'. No such profile.",
task->comm, task->pid,
args);
@@ -118,9 +114,8 @@ repeat:
if (new_profile) {
AA_WARN(GFP_KERNEL,
- "%s: Switching task %s(%d) "
- "profile %s active %s to new profile %s\n",
- __FUNCTION__,
+ "Switching task %s(%d) "
+ "profile %s active %s to new profile %s",
task->comm, task->pid,
old_profile ? old_profile->parent->name :
"unconfined",
@@ -129,17 +124,15 @@ repeat:
} else {
if (old_profile) {
AA_WARN(GFP_KERNEL,
- "%s: Unconfining task %s(%d) "
- "profile %s active %s\n",
- __FUNCTION__,
+ "Unconfining task %s(%d) "
+ "profile %s active %s",
task->comm, task->pid,
old_profile->parent->name,
old_profile->name);
} else {
AA_WARN(GFP_KERNEL,
- "%s: task %s(%d) "
- "is already unconfined\n",
- __FUNCTION__, task->comm, task->pid);
+ "task %s(%d) is already unconfined",
+ task->comm, task->pid);
}
}

View File

@@ -0,0 +1,45 @@
---
security/apparmor/lsm.c | 23 ++---------------------
1 file changed, 2 insertions(+), 21 deletions(-)
--- linux-2.6.orig/security/apparmor/lsm.c
+++ linux-2.6/security/apparmor/lsm.c
@@ -620,18 +620,8 @@ static int apparmor_setprocattr(struct t
return -EINVAL;
if (strcmp(command, "changehat") == 0) {
- if (current != task) {
- AA_WARN(GFP_KERNEL,
- "Attempt by foreign task %s(%d) "
- "[user %d] to changehat of task %s(%d)",
- current->comm,
- current->pid,
- current->uid,
- task->comm,
- task->pid);
-
+ if (current != task)
return -EACCES;
- }
error = aa_setprocattr_changehat(args);
} else if (strcmp(command, "setprofile")) {
struct aa_profile *profile;
@@ -640,17 +630,8 @@ static int apparmor_setprocattr(struct t
* may change the profile of another task.
*/
- if (!capable(CAP_SYS_ADMIN)) {
- AA_WARN(GFP_KERNEL,
- "Unprivileged attempt by task %s(%d) "
- "[user %d] to assign profile to task %s(%d)",
- current->comm,
- current->pid,
- current->uid,
- task->comm,
- task->pid);
+ if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- }
profile = aa_get_profile(current);
if (profile) {

View File

@@ -4,9 +4,19 @@
security/apparmor/main.c | 35 +++++++++++++++++++++++++++++++----
3 files changed, 48 insertions(+), 23 deletions(-)
Index: b/security/apparmor/apparmor.h
===================================================================
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@@ -238,6 +238,8 @@ extern struct aa_task_context *lock_task
@@ -189,6 +189,7 @@ struct aa_audit {
#define HINT_FORK "fork"
#define HINT_MANDPROF "missing_mandatory_profile"
#define HINT_CHGPROF "changing_profile"
+#define HINT_PTRACE "ptrace"
#define LOG_HINT(p, gfp, hint, fmt, args...) \
do {\
@@ -238,6 +239,8 @@ extern struct aa_task_context *lock_task
extern void aa_change_task_context(struct task_struct *task,
struct aa_task_context *new_cxt,
struct aa_profile *profile, u64 hat_magic);
@@ -15,9 +25,11 @@
/* list.c */
extern void aa_profilelist_release(void);
Index: b/security/apparmor/lsm.c
===================================================================
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -73,30 +73,26 @@ static int aa_reject_syscall(struct task
@@ -73,30 +73,31 @@ static int aa_reject_syscall(struct task
}
static int apparmor_ptrace(struct task_struct *parent,
@@ -59,10 +71,17 @@
+ child_cxt = aa_task_context(child);
+ child_profile = child_cxt ? child_cxt->profile : NULL;
+ error = aa_may_ptrace(cxt, child_profile);
+ if (cxt && PROFILE_COMPLAIN(cxt->profile)) {
+ LOG_HINT(cxt->profile, GFP_ATOMIC, HINT_PTRACE,
+ "pid=%d child=%d\n",
+ current->pid, child->pid);
+ }
+ rcu_read_unlock();
return error;
}
Index: b/security/apparmor/main.c
===================================================================
--- a/security/apparmor/main.c
+++ b/security/apparmor/main.c
@@ -13,6 +13,7 @@
@@ -73,15 +92,14 @@
#include "apparmor.h"
@@ -703,6 +704,15 @@ int aa_capability(struct aa_task_context
@@ -703,6 +704,14 @@ int aa_capability(struct aa_task_context
return error;
}
+/* must be used inside rcu_read_lock or task_lock */
+int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee)
+{
+ if (!cxt || cxt->profile == null_complain_profile ||
+ cxt->profile == tracee)
+ if (!cxt || cxt->profile == tracee)
+ return 0;
+ return aa_capability(cxt, CAP_SYS_PTRACE);
+}
@@ -89,7 +107,7 @@
/**
* aa_link - hard link check
* @profile: profile to check against
@@ -953,6 +963,14 @@ repeat:
@@ -953,6 +962,14 @@ repeat:
aa_put_profile(profile);
if (PTR_ERR(old_profile) == -ESTALE)
goto repeat;
@@ -104,7 +122,7 @@
new_profile = old_profile;
goto cleanup;
}
@@ -1041,9 +1059,8 @@ repeat:
@@ -1041,9 +1058,8 @@ repeat:
*
* Switch to a new hat. Returns %0 on success, error otherwise.
*/
@@ -116,7 +134,7 @@
{
struct aa_task_context *cxt = aa_task_context(current);
struct aa_profile *sub;
@@ -1054,6 +1071,10 @@ static inline int do_change_hat(const ch
@@ -1054,6 +1070,10 @@ static inline int do_change_hat(const ch
* no need to grab an additional reference count.
*/
sub = __aa_find_profile(hat_name, &cxt->profile->parent->sub);
@@ -127,7 +145,7 @@
if (sub) {
/* change hat */
aa_change_task_context(current, new_cxt, sub, hat_magic);
@@ -1232,6 +1253,13 @@ struct aa_profile *__aa_replace_profile(
@@ -1232,6 +1252,13 @@ struct aa_profile *__aa_replace_profile(
return ERR_PTR(-ESTALE);
}
@@ -141,7 +159,7 @@
if (cxt) {
old_profile = aa_dup_profile(cxt->profile);
aa_change_task_context(task, new_cxt, profile, cxt->hat_magic);
@@ -1240,7 +1268,6 @@ struct aa_profile *__aa_replace_profile(
@@ -1240,7 +1267,6 @@ struct aa_profile *__aa_replace_profile(
task_unlock(task);
unlock_both_profiles(profile, old_profile);

View File

@@ -0,0 +1,14 @@
---
security/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-2.6.orig/security/Makefile
+++ linux-2.6/security/Makefile
@@ -14,6 +14,6 @@ endif
obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
-obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
+obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o

View File

@@ -0,0 +1,93 @@
---
security/apparmor/apparmor.h | 2 +-
security/apparmor/apparmorfs.c | 2 +-
security/apparmor/inline.h | 2 +-
security/apparmor/list.c | 2 +-
security/apparmor/lsm.c | 2 +-
security/apparmor/main.c | 2 +-
security/apparmor/match.c | 2 +-
security/apparmor/module_interface.c | 2 +-
security/apparmor/procattr.c | 2 +-
9 files changed, 9 insertions(+), 9 deletions(-)
--- linux-2.6.orig/security/apparmor/apparmor.h
+++ linux-2.6/security/apparmor/apparmor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1998-2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/apparmorfs.c
+++ linux-2.6/security/apparmor/apparmorfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/inline.h
+++ linux-2.6/security/apparmor/inline.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/list.c
+++ linux-2.6/security/apparmor/list.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1998-2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/lsm.c
+++ linux-2.6/security/apparmor/lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/main.c
+++ linux-2.6/security/apparmor/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2005 Novell/SUSE
+ * Copyright (C) 2002-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/match.c
+++ linux-2.6/security/apparmor/match.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002-2005 Novell/SUSE
+ * Copyright (C) 2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/module_interface.c
+++ linux-2.6/security/apparmor/module_interface.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1998-2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
--- linux-2.6.orig/security/apparmor/procattr.c
+++ linux-2.6/security/apparmor/procattr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005 Novell/SUSE
+ * Copyright (C) 1998-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as

View File

@@ -0,0 +1,166 @@
---
security/apparmor/apparmorfs.c | 28 -------------
security/apparmor/lsm.c | 84 +++++++++++++++++++++++++++++++++++------
2 files changed, 73 insertions(+), 39 deletions(-)
--- linux-2.6.orig/security/apparmor/apparmorfs.c
+++ linux-2.6/security/apparmor/apparmorfs.c
@@ -170,22 +170,6 @@ static struct file_operations apparmorfs
.write = aa_profile_remove
};
-/* apparmor/control/ */
-static u64 aa_control_get(void *data)
-{
- return *(int *)data;
-}
-
-static void aa_control_set(void *data, u64 val)
-{
- if (val > 1)
- val = 1;
-
- *(int*)data = (int)val;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(apparmorfs_control_fops, aa_control_get,
- aa_control_set, "%lld\n");
static struct root_entry {
const char *name;
@@ -217,18 +201,6 @@ static struct root_entry {
{".remove", S_IFREG, 0640, &apparmorfs_profile_remove,
NULL},
- /* interface for setting binary config values */
- {"control", S_IFDIR, 0550},
- {"complain", S_IFREG, 0640, &apparmorfs_control_fops,
- &apparmor_complain},
- {"audit", S_IFREG, 0640, &apparmorfs_control_fops,
- &apparmor_audit},
- {"debug", S_IFREG, 0640, &apparmorfs_control_fops,
- &apparmor_debug},
- {"logsyscall", S_IFREG, 0640, &apparmorfs_control_fops,
- &apparmor_logsyscall},
- {NULL, S_IFDIR, 0},
-
/* root end */
{NULL, S_IFDIR, 0}
};
--- linux-2.6.orig/security/apparmor/lsm.c
+++ linux-2.6/security/apparmor/lsm.c
@@ -22,41 +22,103 @@
#include "apparmor.h"
#include "inline.h"
-/* Flag values, also controllable via apparmorfs/control.
- * We explicitly do not allow these to be modifiable when exported via
- * /sys/modules/parameters, as we want to do additional mediation and
- * don't want to add special path code. */
-
-/* Complain mode -- in complain mode access failures result in auditing only
+static int param_set_aabool(const char *val, struct kernel_param *kp);
+static int param_get_aabool(char *buffer, struct kernel_param *kp);
+#define param_check_aabool(name, p) __param_check(name, p, int)
+
+static int param_set_aapathint(const char *val, struct kernel_param *kp);
+static int param_get_aapathint(char *buffer, struct kernel_param *kp);
+#define param_check_aapathint(name, p) __param_check(name, p, int)
+
+/* Flag values, also controllable via /sys/module/apparmor/parameters
+ * We define special types as we want to do additional mediation.
+ *
+ * Complain mode -- in complain mode access failures result in auditing only
* and task is allowed access. audit events are processed by userspace to
* generate policy. Default is 'enforce' (0).
* Value is also togglable per profile and referenced when global value is
* enforce.
*/
int apparmor_complain = 0;
-module_param_named(complain, apparmor_complain, int, S_IRUSR);
+module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
/* Debug mode */
int apparmor_debug = 0;
-module_param_named(debug, apparmor_debug, int, S_IRUSR);
+module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
/* Audit mode */
int apparmor_audit = 0;
-module_param_named(audit, apparmor_audit, int, S_IRUSR);
+module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
/* Syscall logging mode */
int apparmor_logsyscall = 0;
-module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR);
+module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
/* Maximum pathname length before accesses will start getting rejected */
int apparmor_path_max = 2 * PATH_MAX;
-module_param_named(path_max, apparmor_path_max, int, S_IRUSR);
+module_param_named(path_max, apparmor_path_max, aapathint, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed");
+static int param_set_aabool(const char *val, struct kernel_param *kp)
+{
+ int boolval, ret;
+ struct kernel_param dummy = { .arg = &boolval };
+
+ if (aa_task_context(current))
+ return -EPERM;
+
+ ret = param_set_bool(val, &dummy);
+ if (ret == 0)
+ *(int *)kp->arg = boolval;
+ return ret;
+}
+
+static int param_get_aabool(char *buffer, struct kernel_param *kp)
+{
+ int val;
+ struct kernel_param dummy = { .arg = &val };
+
+ if (aa_task_context(current))
+ return -EPERM;
+
+ val = *(int *)kp->arg;
+ return param_get_bool(buffer, &dummy);
+}
+
+static int param_set_aapathint(const char *val, struct kernel_param *kp)
+{
+ int len, ret;
+ struct kernel_param dummy = { .arg = &len };
+
+ if (aa_task_context(current))
+ return -EPERM;
+
+ ret = param_set_int(val, &dummy);
+ if (ret)
+ return ret;
+
+ if (len <0 && len <= apparmor_path_max)
+ return -EINVAL;
+
+ *(int *)kp->arg = len;
+ return 0;
+}
+
+static int param_get_aapathint(char *buffer, struct kernel_param *kp)
+{
+ int val;
+ struct kernel_param dummy = { .arg = &val };
+
+ if (aa_task_context(current))
+ return -EPERM;
+
+ val = *(int *)kp->arg;
+ return param_get_int(buffer, &dummy);
+}
static int aa_reject_syscall(struct task_struct *task, gfp_t flags,
const char *name)

View File

@@ -36,6 +36,12 @@ file-handle-ops.diff
security-xattr-file.diff
apparmor-audit.diff
apparmor.diff
apparmor-2.diff
apparmor-ptrace.diff
builtin-commoncap-dep.diff
licence.diff
# apparmor-messages.diff
# apparmor-messages2.diff
apparmor-intree.diff
# module_params.diff
# complain-to-learn.diff