From: Jeff Mahoney Date: Mon, 9 Apr 2012 01:28:12 +0000 (-0400) Subject: Update to 3.4-rc2. X-Git-Url: http://git.alex.org.uk Update to 3.4-rc2. suse-commit: 976094f7fa2839ed96c98a8358eb6964f195cacf --- 2d356c57be7de44c843c5491994d2dee5bb3c917 diff --cc arch/x86/Makefile index 7e93ca8,41a7237..c38ca3b --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@@ -126,11 -126,10 +126,12 @@@ KBUILD_CFLAGS += -pip # Workaround for a gcc prelease that unfortunately was shipped in a suse release KBUILD_CFLAGS += -Wno-sign-compare # +ifneq ($(CONFIG_UNWIND_INFO),y) KBUILD_CFLAGS += -fno-asynchronous-unwind-tables +endif # prevent gcc from generating any FP code by mistake KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) + KBUILD_CFLAGS += $(call cc-option,-mno-avx,) KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) diff --cc security/apparmor/include/audit.h index 4ba78c2,3868b1e..c1ff09c --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h @@@ -103,7 -103,33 +103,37 @@@ enum aa_ops }; - /* define a short hand for apparmor_audit_data portion of common_audit_data */ + struct apparmor_audit_data { + int error; + int op; + int type; + void *profile; + const char *name; + const char *info; + union { + void *target; + struct { + long pos; + void *target; + } iface; + struct { + int rlim; + unsigned long max; + } rlim; + struct { + const char *target; + u32 request; + u32 denied; + uid_t ouid; + } fs; ++ struct { ++ int type, protocol; ++ struct sock *sk; ++ } net; + }; + }; + + /* define a short hand for apparmor_audit_data structure */ #define aad apparmor_audit_data void aa_audit_msg(int type, struct common_audit_data *sa, diff --cc security/apparmor/net.c index 1765901,0000000..8de679a mode 100644,000000..100644 --- a/security/apparmor/net.c +++ b/security/apparmor/net.c @@@ -1,170 -1,0 +1,183 @@@ +/* + * AppArmor security module + * + * This file contains AppArmor network mediation + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009-2010 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include "include/apparmor.h" +#include "include/audit.h" +#include "include/context.h" +#include "include/net.h" +#include "include/policy.h" + +#include "af_names.h" + +static const char *sock_type_names[] = { + "unknown(0)", + "stream", + "dgram", + "raw", + "rdm", + "seqpacket", + "dccp", + "unknown(7)", + "unknown(8)", + "unknown(9)", + "packet", +}; + +/* audit callback for net specific fields */ +static void audit_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *aad = sa->apparmor_audit_data; + + audit_log_format(ab, " family="); - if (address_family_names[sa->u.net.family]) { - audit_log_string(ab, address_family_names[sa->u.net.family]); ++ if (address_family_names[sa->u.net->family]) { ++ audit_log_string(ab, address_family_names[sa->u.net->family]); + } else { - audit_log_format(ab, " \"unknown(%d)\"", sa->u.net.family); ++ audit_log_format(ab, " \"unknown(%d)\"", sa->u.net->family); + } + + audit_log_format(ab, " sock_type="); - if (sock_type_names[sa->aad.net.type]) { - audit_log_string(ab, sock_type_names[sa->aad.net.type]); ++ if (sock_type_names[aad->net.type]) { ++ audit_log_string(ab, sock_type_names[aad->net.type]); + } else { - audit_log_format(ab, "\"unknown(%d)\"", sa->aad.net.type); ++ audit_log_format(ab, "\"unknown(%d)\"", aad->net.type); + } + - audit_log_format(ab, " protocol=%d", sa->aad.net.protocol); ++ audit_log_format(ab, " protocol=%d", aad->net.protocol); +} + +/** + * audit_net - audit network access + * @profile: profile being enforced (NOT NULL) + * @op: operation being checked + * @family: network family + * @type: network type + * @protocol: network protocol + * @sk: socket auditing is being applied to + * @error: error code for failure else 0 + * + * Returns: %0 or sa->error else other errorcode on failure + */ +static int audit_net(struct aa_profile *profile, int op, u16 family, int type, + int protocol, struct sock *sk, int error) +{ + int audit_type = AUDIT_APPARMOR_AUTO; + struct common_audit_data sa; ++ ++ struct apparmor_audit_data aad = { ++ .op = op, ++ .net = { ++ .type = type, ++ .protocol = protocol, ++ }, ++ .error = error ++ }; ++ ++ struct lsm_network_audit net = { ++ .family = family, ++ .sk = sk, ++ }; ++ ++ + if (sk) { + COMMON_AUDIT_DATA_INIT(&sa, NET); + } else { + COMMON_AUDIT_DATA_INIT(&sa, NONE); + } + /* todo fill in socket addr info */ + - sa.aad.op = op, - sa.u.net.family = family; - sa.u.net.sk = sk; - sa.aad.net.type = type; - sa.aad.net.protocol = protocol; - sa.aad.error = error; ++ sa.apparmor_audit_data = &aad; ++ sa.u.net = &net; + - if (likely(!sa.aad.error)) { - u16 audit_mask = profile->net.audit[sa.u.net.family]; ++ if (likely(!aad.error)) { ++ u16 audit_mask = profile->net.audit[net.family]; + if (likely((AUDIT_MODE(profile) != AUDIT_ALL) && - !(1 << sa.aad.net.type & audit_mask))) ++ !(1 << aad.net.type & audit_mask))) + return 0; + audit_type = AUDIT_APPARMOR_AUDIT; + } else { - u16 quiet_mask = profile->net.quiet[sa.u.net.family]; ++ u16 quiet_mask = profile->net.quiet[net.family]; + u16 kill_mask = 0; - u16 denied = (1 << sa.aad.net.type) & ~quiet_mask; ++ u16 denied = (1 << aad.net.type) & ~quiet_mask; + + if (denied & kill_mask) + audit_type = AUDIT_APPARMOR_KILL; + + if ((denied & quiet_mask) && + AUDIT_MODE(profile) != AUDIT_NOQUIET && + AUDIT_MODE(profile) != AUDIT_ALL) - return COMPLAIN_MODE(profile) ? 0 : sa.aad.error; ++ return COMPLAIN_MODE(profile) ? 0 : aad.error; + } + + return aa_audit(audit_type, profile, GFP_KERNEL, &sa, audit_cb); +} + +/** + * aa_net_perm - very course network access check + * @op: operation being checked + * @profile: profile being enforced (NOT NULL) + * @family: network family + * @type: network type + * @protocol: network protocol + * + * Returns: %0 else error if permission denied + */ +int aa_net_perm(int op, struct aa_profile *profile, u16 family, int type, + int protocol, struct sock *sk) +{ + u16 family_mask; + int error; + + if ((family < 0) || (family >= AF_MAX)) + return -EINVAL; + + if ((type < 0) || (type >= SOCK_MAX)) + return -EINVAL; + + /* unix domain and netlink sockets are handled by ipc */ + if (family == AF_UNIX || family == AF_NETLINK) + return 0; + + family_mask = profile->net.allow[family]; + + error = (family_mask & (1 << type)) ? 0 : -EACCES; + + return audit_net(profile, op, family, type, protocol, sk, error); +} + +/** + * aa_revalidate_sk - Revalidate access to a sock + * @op: operation being checked + * @sk: sock being revalidated (NOT NULL) + * + * Returns: %0 else error if permission denied + */ +int aa_revalidate_sk(int op, struct sock *sk) +{ + struct aa_profile *profile; + int error = 0; + + /* aa_revalidate_sk should not be called from interrupt context + * don't mediate these calls as they are not task related + */ + if (in_interrupt()) + return 0; + + profile = __aa_current_profile(); + if (!unconfined(profile)) + error = aa_net_perm(op, profile, sk->sk_family, sk->sk_type, + sk->sk_protocol, sk); + + return error; +}