From c4a2786ff72d1aee1aed5b0c3a5916e85555f455 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 28 Nov 2008 13:11:22 +0000 Subject: [PATCH] back port applicable patches from 2.6.27 branch --- .../2.6.26/AppArmor-checkpatch.diff | 506 ++++++++++++++++++ .../2.6.26/AppArmor-misc-cleanups.diff | 260 +++++++++ .../export-security_inode_permission-for-aufs | 26 + kernel-patches/2.6.26/fix-complain.diff | 32 ++ kernel-patches/2.6.26/fix-config.diff | 14 + .../2.6.26/fix-d_namespace_path-tmp-root.diff | 25 + .../2.6.26/fix-d_namespace_path.diff | 15 + kernel-patches/2.6.26/fix-get_cwd.diff | 25 + .../2.6.26/fix-ptrace-complain.diff | 15 + kernel-patches/2.6.26/fix-security-param.diff | 35 ++ kernel-patches/2.6.26/fork-tracking.diff | 56 ++ kernel-patches/2.6.26/mount-capability.diff | 55 ++ kernel-patches/2.6.26/series | 12 + 13 files changed, 1076 insertions(+) create mode 100644 kernel-patches/2.6.26/AppArmor-checkpatch.diff create mode 100644 kernel-patches/2.6.26/AppArmor-misc-cleanups.diff create mode 100644 kernel-patches/2.6.26/export-security_inode_permission-for-aufs create mode 100644 kernel-patches/2.6.26/fix-complain.diff create mode 100644 kernel-patches/2.6.26/fix-config.diff create mode 100644 kernel-patches/2.6.26/fix-d_namespace_path-tmp-root.diff create mode 100644 kernel-patches/2.6.26/fix-d_namespace_path.diff create mode 100644 kernel-patches/2.6.26/fix-get_cwd.diff create mode 100644 kernel-patches/2.6.26/fix-ptrace-complain.diff create mode 100644 kernel-patches/2.6.26/fix-security-param.diff create mode 100644 kernel-patches/2.6.26/fork-tracking.diff create mode 100644 kernel-patches/2.6.26/mount-capability.diff diff --git a/kernel-patches/2.6.26/AppArmor-checkpatch.diff b/kernel-patches/2.6.26/AppArmor-checkpatch.diff new file mode 100644 index 000000000..328ab359d --- /dev/null +++ b/kernel-patches/2.6.26/AppArmor-checkpatch.diff @@ -0,0 +1,506 @@ + + security/apparmor/apparmor.h | 5 +++ + security/apparmor/apparmorfs.c | 10 ++----- + security/apparmor/inline.h | 2 - + security/apparmor/list.c | 2 - + security/apparmor/lsm.c | 35 ++++++++++++++------------- + security/apparmor/main.c | 21 ++++++++-------- + security/apparmor/match.c | 8 ++---- + security/apparmor/match.h | 2 - + security/apparmor/module_interface.c | 44 +++++++++++++---------------------- + security/apparmor/procattr.c | 5 +-- + 10 files changed, 61 insertions(+), 73 deletions(-) + +--- a/security/apparmor/apparmor.h ++++ b/security/apparmor/apparmor.h +@@ -297,6 +297,9 @@ enum aa_lock_class { + aa_lock_task_release + }; + ++/* apparmor/profiles */ ++extern struct seq_operations apparmorfs_profiles_op; ++ + /* main.c */ + extern int alloc_default_namespace(void); + extern void free_default_namespace(void); +@@ -334,7 +337,7 @@ extern int aa_change_profile(const char + extern struct aa_profile *__aa_replace_profile(struct task_struct *task, + struct aa_profile *profile); + extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task, +- struct aa_profile *profile); ++ struct aa_profile *profile); + extern void unlock_task_and_profiles(struct task_struct *task, + struct aa_task_context *cxt, + struct aa_profile *profile); +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -13,7 +13,7 @@ + #include + #include + #include +-#include ++#include + + #include "apparmor.h" + #include "inline.h" +@@ -64,9 +64,6 @@ out: + return data; + } + +-/* apparmor/profiles */ +-extern struct seq_operations apparmorfs_profiles_op; +- + static int aa_profiles_open(struct inode *inode, struct file *file) + { + return seq_open(file, &apparmorfs_profiles_op); +@@ -235,8 +232,7 @@ int create_apparmorfs(void) + return 0; + + if (apparmor_dentry) { +- AA_ERROR("%s: AppArmor securityfs already exists\n", +- __FUNCTION__); ++ AA_ERROR("%s: AppArmor securityfs already exists\n", __func__); + return -EEXIST; + } + +@@ -244,7 +240,7 @@ int create_apparmorfs(void) + if (IS_ERR(apparmor_dentry)) { + error = PTR_ERR(apparmor_dentry); + apparmor_dentry = NULL; +- goto error; ++ goto error; + } + error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops); + if (error) +--- a/security/apparmor/inline.h ++++ b/security/apparmor/inline.h +@@ -213,7 +213,7 @@ static inline void lock_both_profiles(st + * gives us RCU reader safety. + */ + static inline void unlock_both_profiles(struct aa_profile *profile1, +- struct aa_profile *profile2) ++ struct aa_profile *profile2) + { + /* Unlock the two profiles. */ + if (!profile1 || profile1 == profile2) { +--- a/security/apparmor/list.c ++++ b/security/apparmor/list.c +@@ -15,7 +15,7 @@ + + /* list of profile namespaces and lock */ + LIST_HEAD(profile_ns_list); +-rwlock_t profile_ns_list_lock = RW_LOCK_UNLOCKED; ++DEFINE_RWLOCK(profile_ns_list_lock); + + /** + * __aa_find_namespace - look up a profile namespace on the namespace list +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -24,7 +24,7 @@ + #include "inline.h" + + /* Flag indicating whether initialization completed */ +-int apparmor_initialized = 0; ++int apparmor_initialized; + + /* point to the apparmor module */ + struct module *aa_module = NULL; +@@ -57,22 +57,22 @@ static int param_get_aauint(char *buffer + * Value is also togglable per profile and referenced when global value is + * enforce. + */ +-int apparmor_complain = 0; ++int apparmor_complain; + 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; ++int apparmor_debug; + 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; ++int apparmor_audit; + 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; ++int apparmor_logsyscall; + module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR); + MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode"); + +@@ -131,7 +131,6 @@ static int param_get_aauint(char *buffer + /* allow run time disabling of apparmor */ + static int param_set_aa_enabled(const char *val, struct kernel_param *kp) + { +- char *endp; + unsigned long l; + + if (!apparmor_initialized) { +@@ -148,8 +147,7 @@ static int param_set_aa_enabled(const ch + if (!val) + return -EINVAL; + +- l = simple_strtoul(val, &endp, 0); +- if (endp == val || l != 0) ++ if (strict_strtoul(val, 0, &l) || l != 0) + return -EINVAL; + + apparmor_enabled = 0; +@@ -240,7 +238,7 @@ static int apparmor_sysctl(struct ctl_ta + mask |= MAY_WRITE; + + error = -ENOMEM; +- buffer = (char*)__get_free_page(GFP_KERNEL); ++ buffer = (char *)__get_free_page(GFP_KERNEL); + if (!buffer) + goto out; + name = sysctl_pathname(table, buffer, PAGE_SIZE); +@@ -273,7 +271,7 @@ static int apparmor_bprm_secureexec(stru + + if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) { + AA_DEBUG("%s: secureexec required for %s\n", +- __FUNCTION__, bprm->filename); ++ __func__, bprm->filename); + ret = 1; + } + +@@ -543,7 +541,7 @@ static int apparmor_inode_removexattr(st + static int aa_file_permission(const char *op, struct file *file, int mask) + { + struct aa_profile *profile; +- struct aa_profile *file_profile = (struct aa_profile*)file->f_security; ++ struct aa_profile *file_profile = file->f_security; + int error = 0; + + if (!file_profile) +@@ -580,7 +578,7 @@ static int apparmor_file_permission(stru + aa_mask_permissions(mask)); + } + +-static inline int apparmor_file_lock (struct file *file, unsigned int cmd) ++static inline int apparmor_file_lock(struct file *file, unsigned int cmd) + { + int mask = AA_MAY_LOCK; + if (cmd == F_WRLCK) +@@ -601,7 +599,7 @@ static int apparmor_file_alloc_security( + + static void apparmor_file_free_security(struct file *file) + { +- struct aa_profile *file_profile = (struct aa_profile*)file->f_security; ++ struct aa_profile *file_profile = file->f_security; + + aa_put_profile(file_profile); + } +@@ -1020,17 +1018,20 @@ static int __init apparmor_init(void) + return 0; + } + +- if ((error = create_apparmorfs())) { ++ error = create_apparmorfs(); ++ if (error) { + AA_ERROR("Unable to activate AppArmor filesystem\n"); + goto createfs_out; + } + +- if ((error = alloc_default_namespace())){ ++ error = alloc_default_namespace(); ++ if (error) { + AA_ERROR("Unable to allocate default profile namespace\n"); + goto alloc_out; + } + +- if ((error = register_security(&apparmor_ops))) { ++ error = register_security(&apparmor_ops); ++ if (error) { + AA_ERROR("Unable to register AppArmor\n"); + goto register_security_out; + } +@@ -1049,7 +1050,7 @@ register_security_out: + free_default_namespace(); + + alloc_out: +- destroy_apparmorfs(); ++ destroy_apparmorfs(); + + createfs_out: + return error; +--- a/security/apparmor/main.c ++++ b/security/apparmor/main.c +@@ -416,7 +416,7 @@ static int aa_link_denied(struct aa_prof + * + * If the link has 'x', an exact match of all the execute flags + * must match. +- */ ++ */ + denied_mask |= ~l_mode & link_mask; + + t_mode = aa_match(profile->file_rules, target, NULL); +@@ -445,8 +445,10 @@ static int aa_link_denied(struct aa_prof + (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE)) + denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE); + if ((l_mode & AA_OTHER_EXEC) && +- (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) +- denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE); ++ (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) { ++ denied_mask = ++ AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE); ++ } + } + + return denied_mask; +@@ -866,7 +868,7 @@ int aa_revalidate_sk(struct sock *sk, ch + /* this is some debugging code to flush out the network hooks that + that are called in interrupt context */ + if (in_interrupt()) { +- printk("AppArmor Debug: Hook being called from interrupt context\n"); ++ printk(KERN_WARNING "AppArmor Debug: Hook being called from interrupt context\n"); + dump_stack(); + return 0; + } +@@ -1019,7 +1021,7 @@ repeat: + } + + static struct aa_profile * +-aa_register_find(struct aa_profile *profile, const char* ns_name, ++aa_register_find(struct aa_profile *profile, const char *ns_name, + const char *name, int mandatory, int complain, + struct aa_audit *sa) + { +@@ -1053,7 +1055,7 @@ aa_register_find(struct aa_profile *prof + + if (new_profile) { + AA_DEBUG("%s: setting profile %s\n", +- __FUNCTION__, new_profile->name); ++ __func__, new_profile->name); + } else if (mandatory && profile) { + sa->info = "mandatory profile missing"; + sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */ +@@ -1072,8 +1074,7 @@ aa_register_find(struct aa_profile *prof + * is unconfined, pix, nix. + */ + AA_DEBUG("%s: No profile found for exec image '%s'\n", +- __FUNCTION__, +- name); ++ __func__, name); + } + if (ns_ref) + aa_put_namespace(ns); +@@ -1158,7 +1159,7 @@ int aa_register(struct linux_binprm *bpr + int exec_mode, complain = 0, shift; + struct aa_audit sa; + +- AA_DEBUG("%s\n", __FUNCTION__); ++ AA_DEBUG("%s\n", __func__); + + profile = aa_get_profile(current); + +@@ -1266,7 +1267,7 @@ repeat: + unsigned long bprm_flags; + + bprm_flags = AA_SECURE_EXEC_NEEDED; +- bprm->security = (void*) ++ bprm->security = (void *) + ((unsigned long)bprm->security | bprm_flags); + } + +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -82,7 +82,7 @@ int unpack_dfa(struct aa_dfa *dfa, void + if (!table) + goto fail; + +- switch(table->td_id) { ++ switch (table->td_id) { + case YYTD_ID_ACCEPT: + case YYTD_ID_ACCEPT2: + case YYTD_ID_BASE: +@@ -115,10 +115,8 @@ int unpack_dfa(struct aa_dfa *dfa, void + + fail: + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { +- if (dfa->tables[i]) { +- kfree(dfa->tables[i]); +- dfa->tables[i] = NULL; +- } ++ kfree(dfa->tables[i]); ++ dfa->tables[i] = NULL; + } + return error; + } +--- a/security/apparmor/match.h ++++ b/security/apparmor/match.h +@@ -61,7 +61,7 @@ struct table_header { + #define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data)) + #define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data)) + #define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data)) +-#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 -1]->td_data)) ++#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 - 1]->td_data)) + + struct aa_dfa { + struct table_header *tables[YYTD_ID_NXT]; +--- a/security/apparmor/module_interface.c ++++ b/security/apparmor/module_interface.c +@@ -219,7 +219,7 @@ static size_t aa_is_blob(struct aa_ext * + size = le32_to_cpu(get_unaligned((u32 *)e->pos)); + e->pos += sizeof(u32); + if (aa_inbounds(e, (size_t) size)) { +- * blob = e->pos; ++ *blob = e->pos; + e->pos += size; + return size; + } +@@ -237,8 +237,8 @@ static int aa_is_dynstring(struct aa_ext + *string = NULL; + if (aa_is_nameX(e, AA_STRING, name) && + (size = aa_is_u16_chunk(e, &src_str))) { +- char *str; +- if (!(str = kmalloc(size, GFP_KERNEL))) ++ char *str = kmalloc(size, GFP_KERNEL); ++ if (!str) + goto fail; + memcpy(str, src_str, size); + *string = str; +@@ -495,9 +495,8 @@ static int aa_verify_header(struct aa_ex + } + + /* read the namespace if present */ +- if (!aa_is_dynstring(e, &e->ns_name, "namespace")) { ++ if (!aa_is_dynstring(e, &e->ns_name, "namespace")) + e->ns_name = NULL; +- } + + return 0; + } +@@ -592,11 +591,8 @@ static inline void task_replace(struct t + { + struct aa_task_context *cxt = aa_task_context(task); + +- AA_DEBUG("%s: replacing profile for task %d " +- "profile=%s (%p)\n", +- __FUNCTION__, +- cxt->task->pid, +- cxt->profile->name, cxt->profile); ++ AA_DEBUG("%s: replacing profile for task %d profile=%s (%p)\n", ++ __func__, cxt->task->pid, cxt->profile->name, cxt->profile); + + aa_change_task_context(task, new_cxt, new_profile, cxt->cookie, + cxt->previous_profile); +@@ -797,9 +793,7 @@ noent: + */ + void free_aa_namespace_kref(struct kref *kref) + { +- struct aa_namespace *ns=container_of(kref, struct aa_namespace, count); +- +- free_aa_namespace(ns); ++ free_aa_namespace(container_of(kref, struct aa_namespace, count)); + } + + /** +@@ -812,7 +806,7 @@ struct aa_namespace *alloc_aa_namespace( + struct aa_namespace *ns; + + ns = kzalloc(sizeof(*ns), GFP_KERNEL); +- AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); ++ AA_DEBUG("%s(%p)\n", __func__, ns); + if (ns) { + ns->name = name; + INIT_LIST_HEAD(&ns->list); +@@ -854,7 +848,7 @@ struct aa_namespace *alloc_aa_namespace( + */ + void free_aa_namespace(struct aa_namespace *ns) + { +- AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); ++ AA_DEBUG("%s(%p)\n", __func__, ns); + + if (!ns) + return; +@@ -863,15 +857,12 @@ void free_aa_namespace(struct aa_namespa + if (!list_empty(&ns->profiles)) { + AA_ERROR("%s: internal error, " + "namespace '%s' still contains profiles\n", +- __FUNCTION__, +- ns->name); ++ __func__, ns->name); + BUG(); + } + if (!list_empty(&ns->list)) { +- AA_ERROR("%s: internal error, " +- "namespace '%s' still on list\n", +- __FUNCTION__, +- ns->name); ++ AA_ERROR("%s: internal error, namespace '%s' still on list\n", ++ __func__, ns->name); + BUG(); + } + /* null_complain_profile doesn't contribute to ns ref counting */ +@@ -887,7 +878,7 @@ void free_aa_namespace(struct aa_namespa + */ + void free_aa_profile_kref(struct kref *kref) + { +- struct aa_profile *p=container_of(kref, struct aa_profile, count); ++ struct aa_profile *p = container_of(kref, struct aa_profile, count); + + free_aa_profile(p); + } +@@ -901,7 +892,7 @@ struct aa_profile *alloc_aa_profile(void + struct aa_profile *profile; + + profile = kzalloc(sizeof(*profile), GFP_KERNEL); +- AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); ++ AA_DEBUG("%s(%p)\n", __func__, profile); + if (profile) { + INIT_LIST_HEAD(&profile->list); + kref_init(&profile->count); +@@ -923,7 +914,7 @@ struct aa_profile *alloc_aa_profile(void + */ + void free_aa_profile(struct aa_profile *profile) + { +- AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); ++ AA_DEBUG("%s(%p)\n", __func__, profile); + + if (!profile) + return; +@@ -932,8 +923,7 @@ void free_aa_profile(struct aa_profile * + if (!list_empty(&profile->list)) { + AA_ERROR("%s: internal error, " + "profile '%s' still on global list\n", +- __FUNCTION__, +- profile->name); ++ __func__, profile->name); + BUG(); + } + aa_put_namespace(profile->ns); +@@ -941,7 +931,7 @@ void free_aa_profile(struct aa_profile * + aa_match_free(profile->file_rules); + + if (profile->name) { +- AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name); ++ AA_DEBUG("%s: %s\n", __func__, profile->name); + kfree(profile->name); + } + +--- a/security/apparmor/procattr.c ++++ b/security/apparmor/procattr.c +@@ -88,7 +88,7 @@ int aa_setprocattr_changehat(char *args) + } + + AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n", +- __FUNCTION__, cookie, hat ? hat : NULL); ++ __func__, cookie, hat ? hat : NULL); + + return aa_change_hat(hat, cookie); + } +@@ -121,8 +121,7 @@ int aa_setprocattr_setprofile(struct tas + sa.gfp_mask = GFP_KERNEL; + sa.task = task->pid; + +- AA_DEBUG("%s: current %d\n", +- __FUNCTION__, current->pid); ++ AA_DEBUG("%s: current %d\n", __func__, current->pid); + + name = args; + if (args[0] != '/') { diff --git a/kernel-patches/2.6.26/AppArmor-misc-cleanups.diff b/kernel-patches/2.6.26/AppArmor-misc-cleanups.diff new file mode 100644 index 000000000..f08c59c6f --- /dev/null +++ b/kernel-patches/2.6.26/AppArmor-misc-cleanups.diff @@ -0,0 +1,260 @@ + security/apparmor/Kconfig | 1 + + security/apparmor/apparmor.h | 7 +++---- + security/apparmor/inline.h | 4 ++-- + security/apparmor/list.c | 2 ++ + security/apparmor/lsm.c | 22 ++++++---------------- + security/apparmor/main.c | 5 +++-- + security/apparmor/match.c | 5 +++-- + security/apparmor/module_interface.c | 13 ++++++------- + 8 files changed, 26 insertions(+), 33 deletions(-) + +--- a/security/apparmor/Kconfig ++++ b/security/apparmor/Kconfig +@@ -3,6 +3,7 @@ config SECURITY_APPARMOR + depends on SECURITY + depends on SECURITY_NETWORK + select AUDIT ++ default n + help + This enables the AppArmor security module. + Required userspace tools (if they are not included in your +--- a/security/apparmor/apparmor.h ++++ b/security/apparmor/apparmor.h +@@ -214,9 +214,9 @@ struct aa_profile { + char **exec_table; + struct aa_dfa *file_rules; + struct { +- int hat; +- int complain; +- int audit; ++ u32 hat; ++ u32 complain; ++ u32 audit; + } flags; + int isstale; + +@@ -310,7 +310,6 @@ void aa_audit_status(struct aa_profile * + int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa); + extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *); +-extern int aa_audit(struct aa_profile *profile, struct aa_audit *); + + extern int aa_attr(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct iattr *iattr); +--- a/security/apparmor/inline.h ++++ b/security/apparmor/inline.h +@@ -21,7 +21,7 @@ static inline int mediated_filesystem(st + + static inline struct aa_task_context *aa_task_context(struct task_struct *task) + { +- return (struct aa_task_context *) rcu_dereference(task->security); ++ return rcu_dereference(task->security); + } + + static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns) +@@ -91,7 +91,7 @@ static inline struct aa_profile *aa_get_ + static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns, + const char *name) + { +- struct aa_profile *profile = NULL; ++ struct aa_profile *profile; + + read_lock(&ns->lock); + profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles)); +--- a/security/apparmor/list.c ++++ b/security/apparmor/list.c +@@ -112,6 +112,7 @@ static struct aa_profile *next_profile(s + } + + static void *p_start(struct seq_file *f, loff_t *pos) ++ __acquires(profile_ns_list_lock) + { + struct aa_namespace *ns; + loff_t l = *pos; +@@ -144,6 +145,7 @@ static void *p_next(struct seq_file *f, + } + + static void p_stop(struct seq_file *f, void *p) ++ __releases(profile_ns_list_lock) + { + struct aa_profile *profile = (struct aa_profile *) p; + +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -10,7 +10,7 @@ + */ + + #include +-#include ++#include + #include + #include + #include +@@ -59,27 +59,21 @@ static int param_get_aauint(char *buffer + */ + int apparmor_complain; + 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; + 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; + 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; + 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 */ + unsigned int apparmor_path_max = 2 * PATH_MAX; + module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR); +-MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed"); + + /* Boot time disable flag */ + #ifdef CONFIG_SECURITY_APPARMOR_DISABLE +@@ -88,10 +82,9 @@ MODULE_PARM_DESC(apparmor_path_max, "Max + #define AA_ENABLED_PERMS 0400 + #endif + static int param_set_aa_enabled(const char *val, struct kernel_param *kp); +-unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; ++static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; + module_param_call(enabled, param_set_aa_enabled, param_get_aauint, + &apparmor_enabled, AA_ENABLED_PERMS); +-MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot"); + + static int __init apparmor_enabled_setup(char *str) + { +@@ -578,7 +571,7 @@ static int apparmor_file_permission(stru + aa_mask_permissions(mask)); + } + +-static inline int apparmor_file_lock(struct file *file, unsigned int cmd) ++static int apparmor_file_lock(struct file *file, unsigned int cmd) + { + int mask = AA_MAY_LOCK; + if (cmd == F_WRLCK) +@@ -604,8 +597,8 @@ static void apparmor_file_free_security( + aa_put_profile(file_profile); + } + +-static inline int aa_mmap(struct file *file, const char *operation, +- unsigned long prot, unsigned long flags) ++static int aa_mmap(struct file *file, const char *operation, ++ unsigned long prot, unsigned long flags) + { + struct dentry *dentry; + int mask = 0; +@@ -936,7 +929,7 @@ int apparmor_unregister_subsecurity(cons + return error; + } + +-struct security_operations apparmor_ops = { ++static struct security_operations apparmor_ops = { + .name = "apparmor", + .ptrace = apparmor_ptrace, + .capget = cap_capget, +@@ -1083,6 +1076,3 @@ void apparmor_disable(void) + info_message("AppArmor protection removed", NULL); + } + +-MODULE_DESCRIPTION("AppArmor process confinement"); +-MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); +-MODULE_LICENSE("GPL"); +--- a/security/apparmor/main.c ++++ b/security/apparmor/main.c +@@ -299,7 +299,7 @@ int aa_audit_reject(struct aa_profile *p + * @profile: profile to check against + * @sa: audit event + */ +-int aa_audit(struct aa_profile *profile, struct aa_audit *sa) ++static int aa_audit(struct aa_profile *profile, struct aa_audit *sa) + { + int type = AUDIT_APPARMOR_DENIED; + struct audit_context *audit_cxt; +@@ -520,7 +520,8 @@ static char *new_compound_name(const cha + sprintf(name, "%s//%s", n1, n2); + return name; + } +-static inline void aa_put_name_buffer(char *buffer) ++ ++static void aa_put_name_buffer(char *buffer) + { + kfree(buffer); + } +--- a/security/apparmor/match.c ++++ b/security/apparmor/match.c +@@ -226,8 +226,9 @@ void aa_match_free(struct aa_dfa *dfa) + * but that would require traversing the string twice and be slightly + * slower. + */ +-unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start, +- const char *str, int len) ++static unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, ++ unsigned int start, ++ const char *str, int len) + { + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); +--- a/security/apparmor/module_interface.c ++++ b/security/apparmor/module_interface.c +@@ -61,7 +61,7 @@ struct aa_ext { + char *ns_name; + }; + +-static inline int aa_inbounds(struct aa_ext *e, size_t size) ++static int aa_inbounds(struct aa_ext *e, size_t size) + { + return (size <= e->end - e->pos); + } +@@ -94,7 +94,7 @@ fail: + return 0; + } + +-static inline int aa_is_X(struct aa_ext *e, enum aa_code code) ++static int aa_is_X(struct aa_ext *e, enum aa_code code) + { + if (!aa_inbounds(e, 1)) + return 0; +@@ -369,7 +369,7 @@ fail: + static struct aa_profile *aa_unpack_profile(struct aa_ext *e, + struct aa_audit *sa) + { +- struct aa_profile *profile = NULL; ++ struct aa_profile *profile; + size_t size = 0; + int i, error = -EPROTO; + +@@ -465,8 +465,7 @@ fail: + sa->info = "failed to unpack profile"; + aa_audit_status(NULL, sa); + +- if (profile) +- free_aa_profile(profile); ++ free_aa_profile(profile); + + return ERR_PTR(error); + } +@@ -508,7 +507,7 @@ static int aa_verify_header(struct aa_ex + */ + ssize_t aa_add_profile(void *data, size_t size) + { +- struct aa_profile *profile = NULL; ++ struct aa_profile *profile; + struct aa_namespace *ns = NULL; + struct aa_ext e = { + .start = data, +@@ -585,7 +584,7 @@ ssize_t aa_add_profile(void *data, size_ + * @new_cxt: new aa_task_context to do replacement with + * @new_profile: new profile + */ +-static inline void task_replace(struct task_struct *task, ++static void task_replace(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *new_profile) + { diff --git a/kernel-patches/2.6.26/export-security_inode_permission-for-aufs b/kernel-patches/2.6.26/export-security_inode_permission-for-aufs new file mode 100644 index 000000000..f628c9ec5 --- /dev/null +++ b/kernel-patches/2.6.26/export-security_inode_permission-for-aufs @@ -0,0 +1,26 @@ +From: Jeff Mahoney +Subject: [PATCH] LSM: Export security_inode_permission for aufs +Patch-mainline: Never +References: 356902 + + In order for aufs to work with AppArmor, it needs to be able to call + security_inode_permission itself. + + This patch is a _workaround_ since the author will need to find a + mainline-compatible solution moving forward. + +Signed-off-by: Jeff Mahoney +--- + security/security.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/security/security.c ++++ b/security/security.c +@@ -415,6 +415,7 @@ int security_inode_mknod(struct inode *d + return 0; + return security_ops->inode_mknod(dir, dentry, mnt, mode, dev); + } ++EXPORT_SYMBOL_GPL(security_inode_permission); + + int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *new_dir, diff --git a/kernel-patches/2.6.26/fix-complain.diff b/kernel-patches/2.6.26/fix-complain.diff new file mode 100644 index 000000000..a71803ee8 --- /dev/null +++ b/kernel-patches/2.6.26/fix-complain.diff @@ -0,0 +1,32 @@ +From: John Johansen +Subject: fix enforcement of deny rules in complain mode +Patch-mainline: no +References: bnc#426159 + +Fix enforcement of deny rules so that they are not enforced in complain +mode. This is necessary so that application behavior is not changed by +the presence of the deny rule. + +Signed-off-by: John Johansen + +--- + security/apparmor/main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/security/apparmor/main.c ++++ b/security/apparmor/main.c +@@ -325,11 +325,12 @@ static int aa_audit_file(struct aa_profi + } else { + int mask = AUDIT_QUIET_MASK(sa->audit_mask); + +- if (!(sa->denied_mask & ~mask)) ++ if (!(sa->denied_mask & ~mask) && !PROFILE_COMPLAIN(profile)) + return sa->error_code; + + /* mask off perms whose denial is being silenced */ +- sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; ++ if (!PROFILE_COMPLAIN(profile)) ++ sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; + } + + return aa_audit(profile, sa); diff --git a/kernel-patches/2.6.26/fix-config.diff b/kernel-patches/2.6.26/fix-config.diff new file mode 100644 index 000000000..f8f5450a7 --- /dev/null +++ b/kernel-patches/2.6.26/fix-config.diff @@ -0,0 +1,14 @@ +--- + security/apparmor/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/security/apparmor/Kconfig ++++ b/security/apparmor/Kconfig +@@ -1,6 +1,7 @@ + config SECURITY_APPARMOR + bool "AppArmor support" + depends on SECURITY ++ depends on SECURITY_NETWORK + select AUDIT + help + This enables the AppArmor security module. diff --git a/kernel-patches/2.6.26/fix-d_namespace_path-tmp-root.diff b/kernel-patches/2.6.26/fix-d_namespace_path-tmp-root.diff new file mode 100644 index 000000000..98ee6814c --- /dev/null +++ b/kernel-patches/2.6.26/fix-d_namespace_path-tmp-root.diff @@ -0,0 +1,25 @@ +--- + fs/namespace.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2355,7 +2355,7 @@ void __put_mnt_ns(struct mnt_namespace * + char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) + { +- struct path root, ns_root = { }; ++ struct path root, tmp, ns_root = { }; + struct path path = { .mnt = vfsmnt, .dentry = dentry }; + char *res; + +@@ -2369,7 +2369,8 @@ char *d_namespace_path(struct dentry *de + if (ns_root.mnt) + ns_root.dentry = dget(ns_root.mnt->mnt_root); + spin_unlock(&vfsmount_lock); +- res = __d_path(&path, &ns_root, buf, buflen, ++ tmp = ns_root; ++ res = __d_path(&path, &tmp, buf, buflen, + D_PATH_FAIL_DELETED | D_PATH_DISCONNECT); + path_put(&root); + path_put(&ns_root); diff --git a/kernel-patches/2.6.26/fix-d_namespace_path.diff b/kernel-patches/2.6.26/fix-d_namespace_path.diff new file mode 100644 index 000000000..4c8899838 --- /dev/null +++ b/kernel-patches/2.6.26/fix-d_namespace_path.diff @@ -0,0 +1,15 @@ +--- + fs/namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -2365,7 +2365,7 @@ char *d_namespace_path(struct dentry *de + path_get(¤t->fs->root); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); +- if (root.mnt) ++ if (root.mnt && root.mnt->mnt_ns) + ns_root.mnt = mntget(root.mnt->mnt_ns->root); + if (ns_root.mnt) + ns_root.dentry = dget(ns_root.mnt->mnt_root); diff --git a/kernel-patches/2.6.26/fix-get_cwd.diff b/kernel-patches/2.6.26/fix-get_cwd.diff new file mode 100644 index 000000000..e908b2bf6 --- /dev/null +++ b/kernel-patches/2.6.26/fix-get_cwd.diff @@ -0,0 +1,25 @@ +--- + fs/dcache.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1983,7 +1983,7 @@ Elong: + asmlinkage long sys_getcwd(char __user *buf, unsigned long size) + { + int error, len; +- struct path pwd, root; ++ struct path pwd, root, tmp; + char *page = (char *) __get_free_page(GFP_USER), *cwd; + + if (!page) +@@ -1996,7 +1996,8 @@ asmlinkage long sys_getcwd(char __user * + path_get(&root); + read_unlock(¤t->fs->lock); + +- cwd = __d_path(&pwd, &root, page, PAGE_SIZE, 0); ++ tmp = root; ++ cwd = __d_path(&pwd, &root, tmp, PAGE_SIZE, 0); + error = PTR_ERR(cwd); + if (IS_ERR(cwd)) + goto out; diff --git a/kernel-patches/2.6.26/fix-ptrace-complain.diff b/kernel-patches/2.6.26/fix-ptrace-complain.diff new file mode 100644 index 000000000..c44accf88 --- /dev/null +++ b/kernel-patches/2.6.26/fix-ptrace-complain.diff @@ -0,0 +1,15 @@ +--- + security/apparmor/lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -205,7 +205,7 @@ static int apparmor_ptrace(struct task_s + + error = aa_may_ptrace(cxt, child_cxt ? + child_cxt->profile : NULL); +- if (PROFILE_COMPLAIN(cxt->profile)) { ++ if (error && PROFILE_COMPLAIN(cxt->profile)) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "ptrace"; diff --git a/kernel-patches/2.6.26/fix-security-param.diff b/kernel-patches/2.6.26/fix-security-param.diff new file mode 100644 index 000000000..742463fda --- /dev/null +++ b/kernel-patches/2.6.26/fix-security-param.diff @@ -0,0 +1,35 @@ +From: John Johansen +Subject: fix recognition of security= boot parameter +Patch-mainline: no +References: bnc#442668 + +Fix AppArmor to respect the kernel boot parameter security=, so that if a +different lsm is choosen apparmor does not try to register its lsm hooks. + +Signed-off-by: John Johansen + +--- + security/apparmor/lsm.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -964,6 +964,7 @@ int apparmor_unregister_subsecurity(cons + } + + struct security_operations apparmor_ops = { ++ .name = "apparmor", + .ptrace = apparmor_ptrace, + .capget = cap_capget, + .capset_check = cap_capset_check, +@@ -1042,8 +1043,8 @@ static int __init apparmor_init(void) + { + int error; + +- if (!apparmor_enabled) { +- info_message("AppArmor disabled by boottime parameter", ""); ++ if (!apparmor_enabled || !security_module_enable(&apparmor_ops)) { ++ info_message("AppArmor disabled by boot time parameter", ""); + return 0; + } + diff --git a/kernel-patches/2.6.26/fork-tracking.diff b/kernel-patches/2.6.26/fork-tracking.diff new file mode 100644 index 000000000..1b0ab094b --- /dev/null +++ b/kernel-patches/2.6.26/fork-tracking.diff @@ -0,0 +1,56 @@ +From: John Johansen +Subject: fix log messages to enable tools profile learning +Patch-mainline: no +References: bnc#447564 + +The allocation of the child pid is done after the LSM clone hook, which +breaks the AppArmor tools fork tracking, for profiles learning. Output +the parent pid with each log message to enable the tools to handle fork +tracking. + +Signed-off-by: John Johansen + +--- + security/apparmor/main.c | 10 +++++----- + security/apparmor/module_interface.c | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/security/apparmor/main.c ++++ b/security/apparmor/main.c +@@ -229,9 +229,13 @@ static int aa_audit_base(struct aa_profi + audit_log_format(ab, " protocol=%d", sa->protocol); + } + +- audit_log_format(ab, " pid=%d", current->pid); ++ audit_log_format(ab, " pid=%d", current->pid); + + if (profile) { ++ if (!sa->parent) ++ audit_log_format(ab, " parent=%d", ++ current->real_parent->pid); ++ + audit_log_format(ab, " profile="); + audit_log_untrustedstring(ab, profile->name); + +@@ -1007,10 +1011,6 @@ repeat: + + unlock_profile(profile); + +- if (APPARMOR_COMPLAIN(child_cxt) && +- profile == profile->ns->null_complain_profile) { +- aa_audit_hint(profile, &sa); +- } + aa_put_profile(profile); + } else + aa_free_task_context(child_cxt); +--- a/security/apparmor/module_interface.c ++++ b/security/apparmor/module_interface.c +@@ -126,7 +126,7 @@ static int aa_is_nameX(struct aa_ext *e, + * AA_NAME tag value is a u16. + */ + if (aa_is_X(e, AA_NAME)) { +- char *tag; ++ char *tag = NULL; + size_t size = aa_is_u16_chunk(e, &tag); + /* if a name is specified it must match. otherwise skip tag */ + if (name && (!size || strcmp(name, tag))) diff --git a/kernel-patches/2.6.26/mount-capability.diff b/kernel-patches/2.6.26/mount-capability.diff new file mode 100644 index 000000000..5a81a93ca --- /dev/null +++ b/kernel-patches/2.6.26/mount-capability.diff @@ -0,0 +1,55 @@ +--- + security/apparmor/lsm.c | 28 ---------------------------- + 1 file changed, 28 deletions(-) + +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -157,20 +157,6 @@ static int param_set_aa_enabled(const ch + return 0; + } + +-static int aa_reject_syscall(struct task_struct *task, gfp_t flags, +- const char *name) +-{ +- struct aa_profile *profile = aa_get_profile(task); +- int error = 0; +- +- if (profile) { +- error = aa_audit_syscallreject(profile, flags, name); +- aa_put_profile(profile); +- } +- +- return error; +-} +- + static int apparmor_ptrace(struct task_struct *parent, + struct task_struct *child) + { +@@ -294,17 +280,6 @@ static int apparmor_bprm_secureexec(stru + return ret; + } + +-static int apparmor_sb_mount(char *dev_name, struct path *path, char *type, +- unsigned long flags, void *data) +-{ +- return aa_reject_syscall(current, GFP_KERNEL, "mount"); +-} +- +-static int apparmor_umount(struct vfsmount *mnt, int flags) +-{ +- return aa_reject_syscall(current, GFP_KERNEL, "umount"); +-} +- + static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) + { +@@ -977,9 +952,6 @@ struct security_operations apparmor_ops + .bprm_set_security = apparmor_bprm_set_security, + .bprm_secureexec = apparmor_bprm_secureexec, + +- .sb_mount = apparmor_sb_mount, +- .sb_umount = apparmor_umount, +- + .inode_mkdir = apparmor_inode_mkdir, + .inode_rmdir = apparmor_inode_rmdir, + .inode_create = apparmor_inode_create, diff --git a/kernel-patches/2.6.26/series b/kernel-patches/2.6.26/series index d9cb21693..44618c3fe 100644 --- a/kernel-patches/2.6.26/series +++ b/kernel-patches/2.6.26/series @@ -48,3 +48,15 @@ apparmor-network.diff apparmor-rlimits.diff apparmor-2.6.25.diff apparmor-stack_secondary.diff +fix-ptrace-complain.diff +export-security_inode_permission-for-aufs +fix-security-param.diff +fix-complain.diff +fix-d_namespace_path.diff +fix-d_namespace_path-tmp-root.diff +fix-get_cwd.diff +fork-tracking.diff +mount-capability.diff +fix-config.diff +AppArmor-checkpatch.diff +AppArmor-misc-cleanups.diff