From ede19ea0c47fb23f3fc779833d1e57cf76f3371e Mon Sep 17 00:00:00 2001 From: Yannick GICQUEL Date: Mon, 19 Oct 2015 15:57:07 +0200 Subject: kernel: smack security backport from kernel 4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Here is the backport of all patches relating to smack support on kernel side. For more details, see file: meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README Please note that patches are applied only if "smack" is in the ditro features. Here are the 2 lines to add in the local.conf OVERRIDES .= ":smack" DISTRO_FEATURES_append = " smack" Change-Id: I147a3532aec531f977d6ec34c576261835711f1e Signed-off-by: Yannick GICQUEL Signed-off-by: José Bollo --- ...0001-Smack-Local-IPv6-port-based-controls.patch | 509 +++++++ ...02-Smack-Improve-access-check-performance.patch | 1583 ++++++++++++++++++++ ...003-Smack-Add-smkfstransmute-mount-option.patch | 101 ++ ...ossible-NULL-pointer-dereference-at-smk_n.patch | 29 + ...he-bug-smackcipso-can-t-set-CIPSO-correct.patch | 36 + ...d-Hook-to-test-if-the-particular-xattr-is.patch | 170 +++ ...attr-Constify-name-member-of-struct-xattr.patch | 239 +++ ...smack-fix-memleak-in-smk_write_rules_list.patch | 89 ++ ...ack-add-a-hash-table-to-quicken-smk_find_.patch | 166 ++ .../smack/0010-Smack-network-label-match-fix.patch | 110 ++ ...011-Smack-IPv6-casting-error-fix-for-3.11.patch | 105 ++ ...-multiple-rules-per-write-to-load2-up-to-.patch | 252 ++++ .../0013-Smack-Implement-lock-security-mode.patch | 189 +++ .../0014-Smack-Ptrace-access-check-mode.patch | 34 + ...llow-either-entry-be-missing-on-access-ac.patch | 107 ++ ...nt-the-and-labels-from-being-used-in-SMAC.patch | 104 ++ ...mack-Make-the-syslog-control-configurable.patch | 252 ++++ .../smack/0018-Smack-change-rule-cap-check.patch | 33 + ...0019-Smack-Rationalize-mount-restrictions.patch | 185 +++ .../0020-Smack-File-receive-audit-correction.patch | 39 + ...WARN_ONCE-instead-of-calling-audit_log_st.patch | 36 + .../0022-Smack-Cgroup-filesystem-access.patch | 82 + ...022-smack-fix-key-permission-verification.patch | 55 + ...-Minor-improvement-of-smack_sb_kern_mount.patch | 37 + ...he-subject-object-order-in-smack_ptrace_t.patch | 118 ++ ...ck-unify-all-ptrace-accesses-in-the-smack.patch | 185 +++ .../0026-Smack-adds-smackfs-ptrace-interface.patch | 233 +++ .../smack/0027-bugfix-patch-for-SMACK.patch | 43 + ...-Fix-handling-value-NULL-in-post-setxattr.patch | 64 + ...rrectly-remove-SMACK64TRANSMUTE-attribute.patch | 64 + ...030-Smack-bidirectional-UDS-connect-check.patch | 204 +++ ...-Smack-Verify-read-access-on-file-open-v3.patch | 62 + ...0032-Smack-Label-cgroup-files-for-systemd.patch | 80 + .../0033-Warning-in-scanf-string-typing.patch | 32 + ...-fix-behavior-of-smack_inode_listsecurity.patch | 45 + ...e-zero-length-security-labels-without-pan.patch | 62 + ...e-unneeded-NULL-termination-from-securtit.patch | 54 + ...Fix-setting-label-on-successful-file-open.patch | 32 + .../smack/0038-Smack-Bring-up-access-mode.patch | 805 ++++++++++ ...-in-comments-describing-function-paramete.patch | 63 + ...ix-a-bidirectional-UDS-connect-check-typo.patch | 32 + ...operate-on-smack_known-struct-where-it-st.patch | 1461 ++++++++++++++++++ ...ck-Lock-mode-for-the-floor-and-hat-labels.patch | 52 + ...ack-replace-kzalloc-with-kmem_cache-for-i.patch | 79 + ...ack-fix-out-of-bounds-access-in-smk_parse.patch | 95 ++ ...llaneous-small-fixes-in-function-comments.patch | 62 + ...ogic-in-smack_inode_init_security-functio.patch | 43 + ...duce-a-special-case-for-tmpfs-in-smack_d_.patch | 56 + ...ix-a-bidirectional-UDS-connect-check-typo.patch | 40 + .../smack/0049-Smack-Rework-file-hooks.patch | 172 +++ .../0050-Smack-secmark-support-for-netfilter.patch | 448 ++++++ ...issing-logging-in-bidirectional-UDS-conne.patch | 31 + ...ossible-use-after-frees-in-task_security-.patch | 253 ++++ .../0053-Smack-Repair-netfilter-dependency.patch | 39 + .../smack/0054-Smack-secmark-connections.patch | 50 + .../linux/linux-renesas/smack/README | 153 ++ .../recipes-kernel/linux/linux-renesas_3.10.bb | 69 + meta-rcar-gen2/recipes-kernel/linux/linux.inc | 16 + 58 files changed, 9839 insertions(+) create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0001-Smack-Local-IPv6-port-based-controls.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0002-Smack-Improve-access-check-performance.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0003-Smack-Add-smkfstransmute-mount-option.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0007-xattr-Constify-name-member-of-struct-xattr.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0008-security-smack-fix-memleak-in-smk_write_rules_list.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0010-Smack-network-label-match-fix.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0011-Smack-IPv6-casting-error-fix-for-3.11.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0013-Smack-Implement-lock-security-mode.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0014-Smack-Ptrace-access-check-mode.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0017-Smack-Make-the-syslog-control-configurable.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0018-Smack-change-rule-cap-check.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0019-Smack-Rationalize-mount-restrictions.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0020-Smack-File-receive-audit-correction.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-Smack-Cgroup-filesystem-access.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-smack-fix-key-permission-verification.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0023-Minor-improvement-of-smack_sb_kern_mount.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0026-Smack-adds-smackfs-ptrace-interface.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0027-bugfix-patch-for-SMACK.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0031-Smack-Verify-read-access-on-file-open-v3.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0032-Smack-Label-cgroup-files-for-systemd.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0033-Warning-in-scanf-string-typing.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0035-Smack-handle-zero-length-security-labels-without-pan.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0037-Smack-Fix-setting-label-on-successful-file-open.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0039-Small-fixes-in-comments-describing-function-paramete.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0040-Fix-a-bidirectional-UDS-connect-check-typo.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0045-smack-miscellaneous-small-fixes-in-function-comments.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0046-smack-fix-logic-in-smack_inode_init_security-functio.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0049-Smack-Rework-file-hooks.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0052-smack-fix-possible-use-after-frees-in-task_security-.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0053-Smack-Repair-netfilter-dependency.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0054-Smack-secmark-connections.patch create mode 100644 meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README (limited to 'meta-rcar-gen2/recipes-kernel/linux') diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0001-Smack-Local-IPv6-port-based-controls.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0001-Smack-Local-IPv6-port-based-controls.patch new file mode 100644 index 0000000..d41501b --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0001-Smack-Local-IPv6-port-based-controls.patch @@ -0,0 +1,509 @@ +From 2a16c72fa63c1de2e5c591f0afe5b575cac3b237 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Wed, 22 May 2013 18:42:56 -0700 +Subject: [PATCH 01/54] Smack: Local IPv6 port based controls + +Smack does not provide access controls on IPv6 communications. +This patch introduces a mechanism for maintaining Smack lables +for local IPv6 communications. It is based on labeling local ports. +The behavior should be compatible with any future "real" IPv6 +support as it provides no interfaces for users to manipulate +the labeling. Remote IPv6 connections use the ambient label +the same way that unlabeled IPv4 packets are treated. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 11 ++ + security/smack/smack_lsm.c | 348 +++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 319 insertions(+), 40 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 8ad3095..bb28e09 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -94,6 +94,17 @@ struct smk_netlbladdr { + }; + + /* ++ * An entry in the table identifying ports. ++ */ ++struct smk_port_label { ++ struct list_head list; ++ struct sock *smk_sock; /* socket initialized on */ ++ unsigned short smk_port; /* the port number */ ++ char *smk_in; /* incoming label */ ++ char *smk_out; /* outgoing label */ ++}; ++ ++/* + * This is the repository for labels seen so that it is + * not necessary to keep allocating tiny chuncks of memory + * and so that they can be shared. +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d52c780..609e89d 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -27,10 +27,13 @@ + #include + #include + #include ++#include + #include + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -45,6 +48,12 @@ + #define TRANS_TRUE "TRUE" + #define TRANS_TRUE_SIZE 4 + ++#define SMK_CONNECTING 0 ++#define SMK_RECEIVING 1 ++#define SMK_SENDING 2 ++ ++LIST_HEAD(smk_ipv6_port_list); ++ + /** + * smk_fetch - Fetch the smack label from a file. + * @ip: a pointer to the inode +@@ -1878,6 +1887,155 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + } + + /** ++ * smk_ipv6_port_label - Smack port access table management ++ * @sock: socket ++ * @address: address ++ * ++ * Create or update the port list entry ++ */ ++static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) ++{ ++ struct sock *sk = sock->sk; ++ struct sockaddr_in6 *addr6; ++ struct socket_smack *ssp = sock->sk->sk_security; ++ struct smk_port_label *spp; ++ unsigned short port = 0; ++ ++ if (address == NULL) { ++ /* ++ * This operation is changing the Smack information ++ * on the bound socket. Take the changes to the port ++ * as well. ++ */ ++ list_for_each_entry(spp, &smk_ipv6_port_list, list) { ++ if (sk != spp->smk_sock) ++ continue; ++ spp->smk_in = ssp->smk_in; ++ spp->smk_out = ssp->smk_out; ++ return; ++ } ++ /* ++ * A NULL address is only used for updating existing ++ * bound entries. If there isn't one, it's OK. ++ */ ++ return; ++ } ++ ++ addr6 = (struct sockaddr_in6 *)address; ++ port = ntohs(addr6->sin6_port); ++ /* ++ * This is a special case that is safely ignored. ++ */ ++ if (port == 0) ++ return; ++ ++ /* ++ * Look for an existing port list entry. ++ * This is an indication that a port is getting reused. ++ */ ++ list_for_each_entry(spp, &smk_ipv6_port_list, list) { ++ if (spp->smk_port != port) ++ continue; ++ spp->smk_port = port; ++ spp->smk_sock = sk; ++ spp->smk_in = ssp->smk_in; ++ spp->smk_out = ssp->smk_out; ++ return; ++ } ++ ++ /* ++ * A new port entry is required. ++ */ ++ spp = kzalloc(sizeof(*spp), GFP_KERNEL); ++ if (spp == NULL) ++ return; ++ ++ spp->smk_port = port; ++ spp->smk_sock = sk; ++ spp->smk_in = ssp->smk_in; ++ spp->smk_out = ssp->smk_out; ++ ++ list_add(&spp->list, &smk_ipv6_port_list); ++ return; ++} ++ ++/** ++ * smk_ipv6_port_check - check Smack port access ++ * @sock: socket ++ * @address: address ++ * ++ * Create or update the port list entry ++ */ ++static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, ++ int act) ++{ ++ __be16 *bep; ++ __be32 *be32p; ++ struct sockaddr_in6 *addr6; ++ struct smk_port_label *spp; ++ struct socket_smack *ssp = sk->sk_security; ++ unsigned short port = 0; ++ char *subject; ++ char *object; ++ struct smk_audit_info ad; ++#ifdef CONFIG_AUDIT ++ struct lsm_network_audit net; ++#endif ++ ++ if (act == SMK_RECEIVING) { ++ subject = smack_net_ambient; ++ object = ssp->smk_in; ++ } else { ++ subject = ssp->smk_out; ++ object = smack_net_ambient; ++ } ++ ++ /* ++ * Get the IP address and port from the address. ++ */ ++ addr6 = (struct sockaddr_in6 *)address; ++ port = ntohs(addr6->sin6_port); ++ bep = (__be16 *)(&addr6->sin6_addr); ++ be32p = (__be32 *)(&addr6->sin6_addr); ++ ++ /* ++ * It's remote, so port lookup does no good. ++ */ ++ if (be32p[0] || be32p[1] || be32p[2] || bep[6] || ntohs(bep[7]) != 1) ++ goto auditout; ++ ++ /* ++ * It's local so the send check has to have passed. ++ */ ++ if (act == SMK_RECEIVING) { ++ subject = smack_known_web.smk_known; ++ goto auditout; ++ } ++ ++ list_for_each_entry(spp, &smk_ipv6_port_list, list) { ++ if (spp->smk_port != port) ++ continue; ++ object = spp->smk_in; ++ if (act == SMK_CONNECTING) ++ ssp->smk_packet = spp->smk_out; ++ break; ++ } ++ ++auditout: ++ ++#ifdef CONFIG_AUDIT ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ ad.a.u.net->family = sk->sk_family; ++ ad.a.u.net->dport = port; ++ if (act == SMK_RECEIVING) ++ ad.a.u.net->v6info.saddr = addr6->sin6_addr; ++ else ++ ad.a.u.net->v6info.daddr = addr6->sin6_addr; ++#endif ++ return smk_access(subject, object, MAY_WRITE, &ad); ++} ++ ++/** + * smack_inode_setsecurity - set smack xattrs + * @inode: the object + * @name: attribute name +@@ -1926,7 +2084,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + ssp->smk_in = sp; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { + ssp->smk_out = sp; +- if (sock->sk->sk_family != PF_UNIX) { ++ if (sock->sk->sk_family == PF_INET) { + rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); + if (rc != 0) + printk(KERN_WARNING +@@ -1936,6 +2094,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + } else + return -EOPNOTSUPP; + ++ if (sock->sk->sk_family == PF_INET6) ++ smk_ipv6_port_label(sock, NULL); ++ + return 0; + } + +@@ -1963,6 +2124,25 @@ static int smack_socket_post_create(struct socket *sock, int family, + } + + /** ++ * smack_socket_bind - record port binding information. ++ * @sock: the socket ++ * @address: the port address ++ * @addrlen: size of the address ++ * ++ * Records the label bound to a port. ++ * ++ * Returns 0 ++ */ ++static int smack_socket_bind(struct socket *sock, struct sockaddr *address, ++ int addrlen) ++{ ++ if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) ++ smk_ipv6_port_label(sock, address); ++ ++ return 0; ++} ++ ++/** + * smack_socket_connect - connect access check + * @sock: the socket + * @sap: the other end +@@ -1975,12 +2155,24 @@ static int smack_socket_post_create(struct socket *sock, int family, + static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, + int addrlen) + { +- if (sock->sk == NULL || sock->sk->sk_family != PF_INET) ++ int rc = 0; ++ ++ if (sock->sk == NULL) + return 0; +- if (addrlen < sizeof(struct sockaddr_in)) +- return -EINVAL; + +- return smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); ++ switch (sock->sk->sk_family) { ++ case PF_INET: ++ if (addrlen < sizeof(struct sockaddr_in)) ++ return -EINVAL; ++ rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap); ++ break; ++ case PF_INET6: ++ if (addrlen < sizeof(struct sockaddr_in6)) ++ return -EINVAL; ++ rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING); ++ break; ++ } ++ return rc; + } + + /** +@@ -2792,22 +2984,32 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + * @msg: the message + * @size: the size of the message + * +- * Return 0 if the current subject can write to the destination +- * host. This is only a question if the destination is a single +- * label host. ++ * Return 0 if the current subject can write to the destination host. ++ * For IPv4 this is only a question if the destination is a single label host. ++ * For IPv6 this is a check against the label of the port. + */ + static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + int size) + { + struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; ++ struct sockaddr *sap = (struct sockaddr *) msg->msg_name; ++ int rc = 0; + + /* + * Perfectly reasonable for this to be NULL + */ +- if (sip == NULL || sip->sin_family != AF_INET) ++ if (sip == NULL) + return 0; + +- return smack_netlabel_send(sock->sk, sip); ++ switch (sip->sin_family) { ++ case AF_INET: ++ rc = smack_netlabel_send(sock->sk, sip); ++ break; ++ case AF_INET6: ++ rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); ++ break; ++ } ++ return rc; + } + + /** +@@ -2878,6 +3080,54 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, + return smack_net_ambient; + } + ++static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap) ++{ ++ struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap; ++ u8 nexthdr; ++ int offset; ++ int proto = -EINVAL; ++ struct ipv6hdr _ipv6h; ++ struct ipv6hdr *ip6; ++ __be16 frag_off; ++ struct tcphdr _tcph, *th; ++ struct udphdr _udph, *uh; ++ struct dccp_hdr _dccph, *dh; ++ ++ sip->sin6_port = 0; ++ ++ offset = skb_network_offset(skb); ++ ip6 = skb_header_pointer(skb, offset, sizeof(_ipv6h), &_ipv6h); ++ if (ip6 == NULL) ++ return -EINVAL; ++ sip->sin6_addr = ip6->saddr; ++ ++ nexthdr = ip6->nexthdr; ++ offset += sizeof(_ipv6h); ++ offset = ipv6_skip_exthdr(skb, offset, &nexthdr, &frag_off); ++ if (offset < 0) ++ return -EINVAL; ++ ++ proto = nexthdr; ++ switch (proto) { ++ case IPPROTO_TCP: ++ th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); ++ if (th != NULL) ++ sip->sin6_port = th->source; ++ break; ++ case IPPROTO_UDP: ++ uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); ++ if (uh != NULL) ++ sip->sin6_port = uh->source; ++ break; ++ case IPPROTO_DCCP: ++ dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph); ++ if (dh != NULL) ++ sip->sin6_port = dh->dccph_sport; ++ break; ++ } ++ return proto; ++} ++ + /** + * smack_socket_sock_rcv_skb - Smack packet delivery access check + * @sk: socket +@@ -2889,43 +3139,52 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = sk->sk_security; ++ struct sockaddr sadd; + char *csp; +- int rc; ++ int rc = 0; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; + #endif +- if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) +- return 0; +- +- /* +- * Translate what netlabel gave us. +- */ +- netlbl_secattr_init(&secattr); ++ switch (sk->sk_family) { ++ case PF_INET: ++ /* ++ * Translate what netlabel gave us. ++ */ ++ netlbl_secattr_init(&secattr); + +- rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); +- if (rc == 0) +- csp = smack_from_secattr(&secattr, ssp); +- else +- csp = smack_net_ambient; ++ rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); ++ if (rc == 0) ++ csp = smack_from_secattr(&secattr, ssp); ++ else ++ csp = smack_net_ambient; + +- netlbl_secattr_destroy(&secattr); ++ netlbl_secattr_destroy(&secattr); + + #ifdef CONFIG_AUDIT +- smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); +- ad.a.u.net->family = sk->sk_family; +- ad.a.u.net->netif = skb->skb_iif; +- ipv4_skb_to_auditdata(skb, &ad.a, NULL); ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ ad.a.u.net->family = sk->sk_family; ++ ad.a.u.net->netif = skb->skb_iif; ++ ipv4_skb_to_auditdata(skb, &ad.a, NULL); + #endif +- /* +- * Receiving a packet requires that the other end +- * be able to write here. Read access is not required. +- * This is the simplist possible security model +- * for networking. +- */ +- rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); +- if (rc != 0) +- netlbl_skbuff_err(skb, rc, 0); ++ /* ++ * Receiving a packet requires that the other end ++ * be able to write here. Read access is not required. ++ * This is the simplist possible security model ++ * for networking. ++ */ ++ rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); ++ if (rc != 0) ++ netlbl_skbuff_err(skb, rc, 0); ++ break; ++ case PF_INET6: ++ rc = smk_skb_to_addr_ipv6(skb, &sadd); ++ if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) ++ rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); ++ else ++ rc = 0; ++ break; ++ } + return rc; + } + +@@ -3063,9 +3322,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct lsm_network_audit net; + #endif + +- /* handle mapped IPv4 packets arriving via IPv6 sockets */ +- if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) +- family = PF_INET; ++ if (family == PF_INET6) { ++ /* ++ * Handle mapped IPv4 packets arriving ++ * via IPv6 sockets. Don't set up netlabel ++ * processing on IPv6. ++ */ ++ if (skb->protocol == htons(ETH_P_IP)) ++ family = PF_INET; ++ else ++ return 0; ++ } + + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); +@@ -3498,6 +3765,7 @@ struct security_operations smack_ops = { + .unix_may_send = smack_unix_may_send, + + .socket_post_create = smack_socket_post_create, ++ .socket_bind = smack_socket_bind, + .socket_connect = smack_socket_connect, + .socket_sendmsg = smack_socket_sendmsg, + .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0002-Smack-Improve-access-check-performance.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0002-Smack-Improve-access-check-performance.patch new file mode 100644 index 0000000..30b1c82 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0002-Smack-Improve-access-check-performance.patch @@ -0,0 +1,1583 @@ +From deb377a5301bde51f693879af02821db2016107e Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Wed, 22 May 2013 18:43:03 -0700 +Subject: [PATCH 02/54] Smack: Improve access check performance + +Each Smack label that the kernel has seen is added to a +list of labels. The list of access rules for a given subject +label hangs off of the label list entry for the label. +This patch changes the structures that contain subject +labels to point at the label list entry rather that the +label itself. Doing so removes a label list lookup in +smk_access() that was accounting for the largest single +chunk of Smack overhead. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 108 +++++++------- + security/smack/smack_access.c | 41 +++--- + security/smack/smack_lsm.c | 331 +++++++++++++++++++++++------------------- + security/smack/smackfs.c | 51 +++---- + 4 files changed, 282 insertions(+), 249 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index bb28e09..159f25b 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -29,6 +29,38 @@ + #define SMK_LONGLABEL 256 + + /* ++ * This is the repository for labels seen so that it is ++ * not necessary to keep allocating tiny chuncks of memory ++ * and so that they can be shared. ++ * ++ * Labels are never modified in place. Anytime a label ++ * is imported (e.g. xattrset on a file) the list is checked ++ * for it and it is added if it doesn't exist. The address ++ * is passed out in either case. Entries are added, but ++ * never deleted. ++ * ++ * Since labels are hanging around anyway it doesn't ++ * hurt to maintain a secid for those awkward situations ++ * where kernel components that ought to use LSM independent ++ * interfaces don't. The secid should go away when all of ++ * these components have been repaired. ++ * ++ * The cipso value associated with the label gets stored here, too. ++ * ++ * Keep the access rules for this subject label here so that ++ * the entire set of rules does not need to be examined every ++ * time. ++ */ ++struct smack_known { ++ struct list_head list; ++ char *smk_known; ++ u32 smk_secid; ++ struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ ++ struct list_head smk_rules; /* access rules */ ++ struct mutex smk_rules_lock; /* lock for rules */ ++}; ++ ++/* + * Maximum number of bytes for the levels in a CIPSO IP option. + * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is + * bigger than can be used, and 24 is the next lower multiple +@@ -46,25 +78,25 @@ struct superblock_smack { + }; + + struct socket_smack { +- char *smk_out; /* outbound label */ +- char *smk_in; /* inbound label */ +- char *smk_packet; /* TCP peer label */ ++ struct smack_known *smk_out; /* outbound label */ ++ char *smk_in; /* inbound label */ ++ char *smk_packet; /* TCP peer label */ + }; + + /* + * Inode smack data + */ + struct inode_smack { +- char *smk_inode; /* label of the fso */ +- char *smk_task; /* label of the task */ +- char *smk_mmap; /* label of the mmap domain */ +- struct mutex smk_lock; /* initialization lock */ +- int smk_flags; /* smack inode flags */ ++ char *smk_inode; /* label of the fso */ ++ struct smack_known *smk_task; /* label of the task */ ++ struct smack_known *smk_mmap; /* label of the mmap domain */ ++ struct mutex smk_lock; /* initialization lock */ ++ int smk_flags; /* smack inode flags */ + }; + + struct task_smack { +- char *smk_task; /* label for access control */ +- char *smk_forked; /* label when forked */ ++ struct smack_known *smk_task; /* label for access control */ ++ struct smack_known *smk_forked; /* label when forked */ + struct list_head smk_rules; /* per task access rules */ + struct mutex smk_rules_lock; /* lock for the rules */ + }; +@@ -78,7 +110,7 @@ struct task_smack { + */ + struct smack_rule { + struct list_head list; +- char *smk_subject; ++ struct smack_known *smk_subject; + char *smk_object; + int smk_access; + }; +@@ -101,39 +133,7 @@ struct smk_port_label { + struct sock *smk_sock; /* socket initialized on */ + unsigned short smk_port; /* the port number */ + char *smk_in; /* incoming label */ +- char *smk_out; /* outgoing label */ +-}; +- +-/* +- * This is the repository for labels seen so that it is +- * not necessary to keep allocating tiny chuncks of memory +- * and so that they can be shared. +- * +- * Labels are never modified in place. Anytime a label +- * is imported (e.g. xattrset on a file) the list is checked +- * for it and it is added if it doesn't exist. The address +- * is passed out in either case. Entries are added, but +- * never deleted. +- * +- * Since labels are hanging around anyway it doesn't +- * hurt to maintain a secid for those awkward situations +- * where kernel components that ought to use LSM independent +- * interfaces don't. The secid should go away when all of +- * these components have been repaired. +- * +- * The cipso value associated with the label gets stored here, too. +- * +- * Keep the access rules for this subject label here so that +- * the entire set of rules does not need to be examined every +- * time. +- */ +-struct smack_known { +- struct list_head list; +- char *smk_known; +- u32 smk_secid; +- struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ +- struct list_head smk_rules; /* access rules */ +- struct mutex smk_rules_lock; /* lock for rules */ ++ struct smack_known *smk_out; /* outgoing label */ + }; + + /* +@@ -214,9 +214,9 @@ struct inode_smack *new_inode_smack(char *); + * These functions are in smack_access.c + */ + int smk_access_entry(char *, char *, struct list_head *); +-int smk_access(char *, char *, int, struct smk_audit_info *); ++int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); + int smk_curacc(char *, u32, struct smk_audit_info *); +-char *smack_from_secid(const u32); ++struct smack_known *smack_from_secid(const u32); + char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); + char *smk_import(const char *, int); +@@ -229,7 +229,7 @@ u32 smack_to_secid(const char *); + */ + extern int smack_cipso_direct; + extern int smack_cipso_mapped; +-extern char *smack_net_ambient; ++extern struct smack_known *smack_net_ambient; + extern char *smack_onlycap; + extern const char *smack_cipso_option; + +@@ -265,17 +265,17 @@ static inline char *smk_of_inode(const struct inode *isp) + } + + /* +- * Present a pointer to the smack label in an task blob. ++ * Present a pointer to the smack label entry in an task blob. + */ +-static inline char *smk_of_task(const struct task_smack *tsp) ++static inline struct smack_known *smk_of_task(const struct task_smack *tsp) + { + return tsp->smk_task; + } + + /* +- * Present a pointer to the forked smack label in an task blob. ++ * Present a pointer to the forked smack label entry in an task blob. + */ +-static inline char *smk_of_forked(const struct task_smack *tsp) ++static inline struct smack_known *smk_of_forked(const struct task_smack *tsp) + { + return tsp->smk_forked; + } +@@ -283,7 +283,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp) + /* + * Present a pointer to the smack label in the current task blob. + */ +-static inline char *smk_of_current(void) ++static inline struct smack_known *smk_of_current(void) + { + return smk_of_task(current_security()); + } +@@ -294,9 +294,11 @@ static inline char *smk_of_current(void) + */ + static inline int smack_privileged(int cap) + { ++ struct smack_known *skp = smk_of_current(); ++ + if (!capable(cap)) + return 0; +- if (smack_onlycap == NULL || smack_onlycap == smk_of_current()) ++ if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) + return 1; + return 0; + } +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 2e397a8..53f2327 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -93,7 +93,7 @@ int smk_access_entry(char *subject_label, char *object_label, + + list_for_each_entry_rcu(srp, rule_list, list) { + if (srp->smk_object == object_label && +- srp->smk_subject == subject_label) { ++ srp->smk_subject->smk_known == subject_label) { + may = srp->smk_access; + break; + } +@@ -104,7 +104,7 @@ int smk_access_entry(char *subject_label, char *object_label, + + /** + * smk_access - determine if a subject has a specific access to an object +- * @subject_label: a pointer to the subject's Smack label ++ * @subject_known: a pointer to the subject's Smack label entry + * @object_label: a pointer to the object's Smack label + * @request: the access requested, in "MAY" format + * @a : a pointer to the audit data +@@ -115,10 +115,9 @@ int smk_access_entry(char *subject_label, char *object_label, + * + * Smack labels are shared on smack_list + */ +-int smk_access(char *subject_label, char *object_label, int request, +- struct smk_audit_info *a) ++int smk_access(struct smack_known *subject_known, char *object_label, ++ int request, struct smk_audit_info *a) + { +- struct smack_known *skp; + int may = MAY_NOT; + int rc = 0; + +@@ -127,7 +126,7 @@ int smk_access(char *subject_label, char *object_label, int request, + * + * A star subject can't access any object. + */ +- if (subject_label == smack_known_star.smk_known) { ++ if (subject_known == &smack_known_star) { + rc = -EACCES; + goto out_audit; + } +@@ -137,7 +136,7 @@ int smk_access(char *subject_label, char *object_label, int request, + * An internet subject can access any object. + */ + if (object_label == smack_known_web.smk_known || +- subject_label == smack_known_web.smk_known) ++ subject_known == &smack_known_web) + goto out_audit; + /* + * A star object can be accessed by any subject. +@@ -148,7 +147,7 @@ int smk_access(char *subject_label, char *object_label, int request, + * An object can be accessed in any way by a subject + * with the same label. + */ +- if (subject_label == object_label) ++ if (subject_known->smk_known == object_label) + goto out_audit; + /* + * A hat subject can read any object. +@@ -157,7 +156,7 @@ int smk_access(char *subject_label, char *object_label, int request, + if ((request & MAY_ANYREAD) == request) { + if (object_label == smack_known_floor.smk_known) + goto out_audit; +- if (subject_label == smack_known_hat.smk_known) ++ if (subject_known == &smack_known_hat) + goto out_audit; + } + /* +@@ -167,9 +166,9 @@ int smk_access(char *subject_label, char *object_label, int request, + * good. A negative response from smk_access_entry() + * indicates there is no entry for this pair. + */ +- skp = smk_find_entry(subject_label); + rcu_read_lock(); +- may = smk_access_entry(subject_label, object_label, &skp->smk_rules); ++ may = smk_access_entry(subject_known->smk_known, object_label, ++ &subject_known->smk_rules); + rcu_read_unlock(); + + if (may > 0 && (request & may) == request) +@@ -179,7 +178,8 @@ int smk_access(char *subject_label, char *object_label, int request, + out_audit: + #ifdef CONFIG_AUDIT + if (a) +- smack_log(subject_label, object_label, request, rc, a); ++ smack_log(subject_known->smk_known, object_label, request, ++ rc, a); + #endif + return rc; + } +@@ -198,20 +198,21 @@ out_audit: + int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) + { + struct task_smack *tsp = current_security(); +- char *sp = smk_of_task(tsp); ++ struct smack_known *skp = smk_of_task(tsp); + int may; + int rc; + + /* + * Check the global rule list + */ +- rc = smk_access(sp, obj_label, mode, NULL); ++ rc = smk_access(skp, obj_label, mode, NULL); + if (rc == 0) { + /* + * If there is an entry in the task's rule list + * it can further restrict access. + */ +- may = smk_access_entry(sp, obj_label, &tsp->smk_rules); ++ may = smk_access_entry(skp->smk_known, obj_label, ++ &tsp->smk_rules); + if (may < 0) + goto out_audit; + if ((mode & may) == mode) +@@ -228,7 +229,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) + out_audit: + #ifdef CONFIG_AUDIT + if (a) +- smack_log(sp, obj_label, mode, rc, a); ++ smack_log(skp->smk_known, obj_label, mode, rc, a); + #endif + return rc; + } +@@ -513,10 +514,10 @@ char *smk_import(const char *string, int len) + * smack_from_secid - find the Smack label associated with a secid + * @secid: an integer that might be associated with a Smack label + * +- * Returns a pointer to the appropriate Smack label if there is one, ++ * Returns a pointer to the appropriate Smack label entry if there is one, + * otherwise a pointer to the invalid Smack label. + */ +-char *smack_from_secid(const u32 secid) ++struct smack_known *smack_from_secid(const u32 secid) + { + struct smack_known *skp; + +@@ -524,7 +525,7 @@ char *smack_from_secid(const u32 secid) + list_for_each_entry_rcu(skp, &smack_known_list, list) { + if (skp->smk_secid == secid) { + rcu_read_unlock(); +- return skp->smk_known; ++ return skp; + } + } + +@@ -533,7 +534,7 @@ char *smack_from_secid(const u32 secid) + * of a secid that is not on the list. + */ + rcu_read_unlock(); +- return smack_known_invalid.smk_known; ++ return &smack_known_invalid; + } + + /** +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 609e89d..3669d9f 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -62,11 +62,12 @@ LIST_HEAD(smk_ipv6_port_list); + * Returns a pointer to the master list entry for the Smack label + * or NULL if there was no label to fetch. + */ +-static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) ++static struct smack_known *smk_fetch(const char *name, struct inode *ip, ++ struct dentry *dp) + { + int rc; + char *buffer; +- char *result = NULL; ++ struct smack_known *skp = NULL; + + if (ip->i_op->getxattr == NULL) + return NULL; +@@ -77,11 +78,11 @@ static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp) + + rc = ip->i_op->getxattr(dp, name, buffer, SMK_LONGLABEL); + if (rc > 0) +- result = smk_import(buffer, rc); ++ skp = smk_import_entry(buffer, rc); + + kfree(buffer); + +- return result; ++ return skp; + } + + /** +@@ -111,7 +112,8 @@ struct inode_smack *new_inode_smack(char *smack) + * + * Returns the new blob or NULL if there's no memory available + */ +-static struct task_smack *new_task_smack(char *task, char *forked, gfp_t gfp) ++static struct task_smack *new_task_smack(struct smack_known *task, ++ struct smack_known *forked, gfp_t gfp) + { + struct task_smack *tsp; + +@@ -173,17 +175,17 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + { + int rc; + struct smk_audit_info ad; +- char *tsp; ++ struct smack_known *skp; + + rc = cap_ptrace_access_check(ctp, mode); + if (rc != 0) + return rc; + +- tsp = smk_of_task(task_security(ctp)); ++ skp = smk_of_task(task_security(ctp)); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ctp); + +- rc = smk_curacc(tsp, MAY_READWRITE, &ad); ++ rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); + return rc; + } + +@@ -199,17 +201,17 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + { + int rc; + struct smk_audit_info ad; +- char *tsp; ++ struct smack_known *skp; + + rc = cap_ptrace_traceme(ptp); + if (rc != 0) + return rc; + +- tsp = smk_of_task(task_security(ptp)); ++ skp = smk_of_task(task_security(ptp)); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ptp); + +- rc = smk_curacc(tsp, MAY_READWRITE, &ad); ++ rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); + return rc; + } + +@@ -224,12 +226,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + static int smack_syslog(int typefrom_file) + { + int rc = 0; +- char *sp = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); + + if (smack_privileged(CAP_MAC_OVERRIDE)) + return 0; + +- if (sp != smack_known_floor.smk_known) ++ if (skp != &smack_known_floor) + rc = -EACCES; + + return rc; +@@ -533,7 +535,9 @@ static int smack_bprm_secureexec(struct linux_binprm *bprm) + */ + static int smack_inode_alloc_security(struct inode *inode) + { +- inode->i_security = new_inode_smack(smk_of_current()); ++ struct smack_known *skp = smk_of_current(); ++ ++ inode->i_security = new_inode_smack(skp->smk_known); + if (inode->i_security == NULL) + return -ENOMEM; + return 0; +@@ -566,9 +570,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, char **name, + void **value, size_t *len) + { +- struct smack_known *skp; + struct inode_smack *issp = inode->i_security; +- char *csp = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); + char *isp = smk_of_inode(inode); + char *dsp = smk_of_inode(dir); + int may; +@@ -580,9 +583,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + } + + if (value) { +- skp = smk_find_entry(csp); + rcu_read_lock(); +- may = smk_access_entry(csp, dsp, &skp->smk_rules); ++ may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules); + rcu_read_unlock(); + + /* +@@ -871,29 +873,31 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, + static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) + { +- char *nsp; ++ struct smack_known *skp; + struct inode_smack *isp = dentry->d_inode->i_security; + ++ if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { ++ isp->smk_flags |= SMK_INODE_TRANSMUTE; ++ return; ++ } ++ ++ skp = smk_import_entry(value, size); + if (strcmp(name, XATTR_NAME_SMACK) == 0) { +- nsp = smk_import(value, size); +- if (nsp != NULL) +- isp->smk_inode = nsp; ++ if (skp != NULL) ++ isp->smk_inode = skp->smk_known; + else + isp->smk_inode = smack_known_invalid.smk_known; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { +- nsp = smk_import(value, size); +- if (nsp != NULL) +- isp->smk_task = nsp; ++ if (skp != NULL) ++ isp->smk_task = skp; + else +- isp->smk_task = smack_known_invalid.smk_known; ++ isp->smk_task = &smack_known_invalid; + } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { +- nsp = smk_import(value, size); +- if (nsp != NULL) +- isp->smk_mmap = nsp; ++ if (skp != NULL) ++ isp->smk_mmap = skp; + else +- isp->smk_mmap = smack_known_invalid.smk_known; +- } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) +- isp->smk_flags |= SMK_INODE_TRANSMUTE; ++ isp->smk_mmap = &smack_known_invalid; ++ } + + return; + } +@@ -999,7 +1003,7 @@ static int smack_inode_getsecurity(const struct inode *inode, + if (strcmp(name, XATTR_SMACK_IPIN) == 0) + isp = ssp->smk_in; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) +- isp = ssp->smk_out; ++ isp = ssp->smk_out->smk_known; + else + return -EOPNOTSUPP; + +@@ -1079,7 +1083,9 @@ static int smack_file_permission(struct file *file, int mask) + */ + static int smack_file_alloc_security(struct file *file) + { +- file->f_security = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); ++ ++ file->f_security = skp->smk_known; + return 0; + } + +@@ -1190,10 +1196,9 @@ static int smack_mmap_file(struct file *file, + unsigned long flags) + { + struct smack_known *skp; ++ struct smack_known *mkp; + struct smack_rule *srp; + struct task_smack *tsp; +- char *sp; +- char *msmack; + char *osmack; + struct inode_smack *isp; + int may; +@@ -1207,11 +1212,10 @@ static int smack_mmap_file(struct file *file, + isp = file_inode(file)->i_security; + if (isp->smk_mmap == NULL) + return 0; +- msmack = isp->smk_mmap; ++ mkp = isp->smk_mmap; + + tsp = current_security(); +- sp = smk_of_current(); +- skp = smk_find_entry(sp); ++ skp = smk_of_current(); + rc = 0; + + rcu_read_lock(); +@@ -1225,13 +1229,13 @@ static int smack_mmap_file(struct file *file, + /* + * Matching labels always allows access. + */ +- if (msmack == osmack) ++ if (mkp->smk_known == osmack) + continue; + /* + * If there is a matching local rule take + * that into account as well. + */ +- may = smk_access_entry(srp->smk_subject, osmack, ++ may = smk_access_entry(srp->smk_subject->smk_known, osmack, + &tsp->smk_rules); + if (may == -ENOENT) + may = srp->smk_access; +@@ -1249,8 +1253,8 @@ static int smack_mmap_file(struct file *file, + * If there isn't one a SMACK64MMAP subject + * can't have as much access as current. + */ +- skp = smk_find_entry(msmack); +- mmay = smk_access_entry(msmack, osmack, &skp->smk_rules); ++ mmay = smk_access_entry(mkp->smk_known, osmack, ++ &mkp->smk_rules); + if (mmay == -ENOENT) { + rc = -EACCES; + break; +@@ -1259,7 +1263,8 @@ static int smack_mmap_file(struct file *file, + * If there is a local entry it modifies the + * potential access, too. + */ +- tmay = smk_access_entry(msmack, osmack, &tsp->smk_rules); ++ tmay = smk_access_entry(mkp->smk_known, osmack, ++ &tsp->smk_rules); + if (tmay != -ENOENT) + mmay &= tmay; + +@@ -1288,7 +1293,9 @@ static int smack_mmap_file(struct file *file, + */ + static int smack_file_set_fowner(struct file *file) + { +- file->f_security = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); ++ ++ file->f_security = skp->smk_known; + return 0; + } + +@@ -1306,9 +1313,10 @@ static int smack_file_set_fowner(struct file *file) + static int smack_file_send_sigiotask(struct task_struct *tsk, + struct fown_struct *fown, int signum) + { ++ struct smack_known *skp; ++ struct smack_known *tkp = smk_of_task(tsk->cred->security); + struct file *file; + int rc; +- char *tsp = smk_of_task(tsk->cred->security); + struct smk_audit_info ad; + + /* +@@ -1317,13 +1325,14 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, + file = container_of(fown, struct file, f_owner); + + /* we don't log here as rc can be overriden */ +- rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); ++ skp = smk_find_entry(file->f_security); ++ rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL); + if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) + rc = 0; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, tsk); +- smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); ++ smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad); + return rc; + } + +@@ -1478,12 +1487,12 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old) + static int smack_kernel_act_as(struct cred *new, u32 secid) + { + struct task_smack *new_tsp = new->security; +- char *smack = smack_from_secid(secid); ++ struct smack_known *skp = smack_from_secid(secid); + +- if (smack == NULL) ++ if (skp == NULL) + return -EINVAL; + +- new_tsp->smk_task = smack; ++ new_tsp->smk_task = skp; + return 0; + } + +@@ -1501,8 +1510,8 @@ static int smack_kernel_create_files_as(struct cred *new, + struct inode_smack *isp = inode->i_security; + struct task_smack *tsp = new->security; + +- tsp->smk_forked = isp->smk_inode; +- tsp->smk_task = isp->smk_inode; ++ tsp->smk_forked = smk_find_entry(isp->smk_inode); ++ tsp->smk_task = tsp->smk_forked; + return 0; + } + +@@ -1518,10 +1527,11 @@ static int smk_curacc_on_task(struct task_struct *p, int access, + const char *caller) + { + struct smk_audit_info ad; ++ struct smack_known *skp = smk_of_task(task_security(p)); + + smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); +- return smk_curacc(smk_of_task(task_security(p)), access, &ad); ++ return smk_curacc(skp->smk_known, access, &ad); + } + + /** +@@ -1567,7 +1577,9 @@ static int smack_task_getsid(struct task_struct *p) + */ + static void smack_task_getsecid(struct task_struct *p, u32 *secid) + { +- *secid = smack_to_secid(smk_of_task(task_security(p))); ++ struct smack_known *skp = smk_of_task(task_security(p)); ++ ++ *secid = skp->smk_secid; + } + + /** +@@ -1671,6 +1683,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + int sig, u32 secid) + { + struct smk_audit_info ad; ++ struct smack_known *skp; ++ struct smack_known *tkp = smk_of_task(task_security(p)); + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); +@@ -1679,15 +1693,14 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + * can write the receiver. + */ + if (secid == 0) +- return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE, +- &ad); ++ return smk_curacc(tkp->smk_known, MAY_WRITE, &ad); + /* + * If the secid isn't 0 we're dealing with some USB IO + * specific behavior. This is not clean. For one thing + * we can't take privilege into account. + */ +- return smk_access(smack_from_secid(secid), +- smk_of_task(task_security(p)), MAY_WRITE, &ad); ++ skp = smack_from_secid(secid); ++ return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad); + } + + /** +@@ -1719,7 +1732,9 @@ static int smack_task_wait(struct task_struct *p) + static void smack_task_to_inode(struct task_struct *p, struct inode *inode) + { + struct inode_smack *isp = inode->i_security; +- isp->smk_inode = smk_of_task(task_security(p)); ++ struct smack_known *skp = smk_of_task(task_security(p)); ++ ++ isp->smk_inode = skp->smk_known; + } + + /* +@@ -1738,15 +1753,15 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) + */ + static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) + { +- char *csp = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); + struct socket_smack *ssp; + + ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); + if (ssp == NULL) + return -ENOMEM; + +- ssp->smk_in = csp; +- ssp->smk_out = csp; ++ ssp->smk_in = skp->smk_known; ++ ssp->smk_out = skp; + ssp->smk_packet = NULL; + + sk->sk_security = ssp; +@@ -1833,7 +1848,7 @@ static int smack_netlabel(struct sock *sk, int labeled) + labeled == SMACK_UNLABELED_SOCKET) + netlbl_sock_delattr(sk); + else { +- skp = smk_find_entry(ssp->smk_out); ++ skp = ssp->smk_out; + rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); + } + +@@ -1856,6 +1871,7 @@ static int smack_netlabel(struct sock *sk, int labeled) + */ + static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + { ++ struct smack_known *skp; + int rc; + int sk_lbl; + char *hostsp; +@@ -1874,7 +1890,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; + #endif + sk_lbl = SMACK_UNLABELED_SOCKET; +- rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); ++ skp = ssp->smk_out; ++ rc = smk_access(skp, hostsp, MAY_WRITE, &ad); + } else { + sk_lbl = SMACK_CIPSO_SOCKET; + rc = 0; +@@ -1974,8 +1991,8 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, + struct sockaddr_in6 *addr6; + struct smk_port_label *spp; + struct socket_smack *ssp = sk->sk_security; ++ struct smack_known *skp; + unsigned short port = 0; +- char *subject; + char *object; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT +@@ -1983,11 +2000,11 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, + #endif + + if (act == SMK_RECEIVING) { +- subject = smack_net_ambient; ++ skp = smack_net_ambient; + object = ssp->smk_in; + } else { +- subject = ssp->smk_out; +- object = smack_net_ambient; ++ skp = ssp->smk_out; ++ object = smack_net_ambient->smk_known; + } + + /* +@@ -2008,7 +2025,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, + * It's local so the send check has to have passed. + */ + if (act == SMK_RECEIVING) { +- subject = smack_known_web.smk_known; ++ skp = &smack_known_web; + goto auditout; + } + +@@ -2017,7 +2034,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, + continue; + object = spp->smk_in; + if (act == SMK_CONNECTING) +- ssp->smk_packet = spp->smk_out; ++ ssp->smk_packet = spp->smk_out->smk_known; + break; + } + +@@ -2032,7 +2049,7 @@ auditout: + else + ad.a.u.net->v6info.daddr = addr6->sin6_addr; + #endif +- return smk_access(subject, object, MAY_WRITE, &ad); ++ return smk_access(skp, object, MAY_WRITE, &ad); + } + + /** +@@ -2050,7 +2067,7 @@ auditout: + static int smack_inode_setsecurity(struct inode *inode, const char *name, + const void *value, size_t size, int flags) + { +- char *sp; ++ struct smack_known *skp; + struct inode_smack *nsp = inode->i_security; + struct socket_smack *ssp; + struct socket *sock; +@@ -2059,12 +2076,12 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + if (value == NULL || size > SMK_LONGLABEL || size == 0) + return -EACCES; + +- sp = smk_import(value, size); +- if (sp == NULL) ++ skp = smk_import_entry(value, size); ++ if (skp == NULL) + return -EINVAL; + + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { +- nsp->smk_inode = sp; ++ nsp->smk_inode = skp->smk_known; + nsp->smk_flags |= SMK_INODE_INSTANT; + return 0; + } +@@ -2081,9 +2098,9 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- ssp->smk_in = sp; ++ ssp->smk_in = skp->smk_known; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { +- ssp->smk_out = sp; ++ ssp->smk_out = skp; + if (sock->sk->sk_family == PF_INET) { + rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); + if (rc != 0) +@@ -2203,7 +2220,9 @@ static int smack_flags_to_may(int flags) + */ + static int smack_msg_msg_alloc_security(struct msg_msg *msg) + { +- msg->security = smk_of_current(); ++ struct smack_known *skp = smk_of_current(); ++ ++ msg->security = skp->smk_known; + return 0; + } + +@@ -2238,8 +2257,9 @@ static char *smack_of_shm(struct shmid_kernel *shp) + static int smack_shm_alloc_security(struct shmid_kernel *shp) + { + struct kern_ipc_perm *isp = &shp->shm_perm; ++ struct smack_known *skp = smk_of_current(); + +- isp->security = smk_of_current(); ++ isp->security = skp->smk_known; + return 0; + } + +@@ -2361,8 +2381,9 @@ static char *smack_of_sem(struct sem_array *sma) + static int smack_sem_alloc_security(struct sem_array *sma) + { + struct kern_ipc_perm *isp = &sma->sem_perm; ++ struct smack_known *skp = smk_of_current(); + +- isp->security = smk_of_current(); ++ isp->security = skp->smk_known; + return 0; + } + +@@ -2479,8 +2500,9 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, + static int smack_msg_queue_alloc_security(struct msg_queue *msq) + { + struct kern_ipc_perm *kisp = &msq->q_perm; ++ struct smack_known *skp = smk_of_current(); + +- kisp->security = smk_of_current(); ++ kisp->security = skp->smk_known; + return 0; + } + +@@ -2652,8 +2674,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + struct super_block *sbp; + struct superblock_smack *sbsp; + struct inode_smack *isp; +- char *csp = smk_of_current(); +- char *fetched; ++ struct smack_known *skp; ++ struct smack_known *ckp = smk_of_current(); + char *final; + char trattr[TRANS_TRUE_SIZE]; + int transflag = 0; +@@ -2720,7 +2742,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * Programs that change smack have to treat the + * pty with respect. + */ +- final = csp; ++ final = ckp->smk_known; + break; + case SOCKFS_MAGIC: + /* +@@ -2775,9 +2797,9 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * Get the dentry for xattr. + */ + dp = dget(opt_dentry); +- fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp); +- if (fetched != NULL) +- final = fetched; ++ skp = smk_fetch(XATTR_NAME_SMACK, inode, dp); ++ if (skp != NULL) ++ final = skp->smk_known; + + /* + * Transmuting directory +@@ -2817,7 +2839,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + } + + if (final == NULL) +- isp->smk_inode = csp; ++ isp->smk_inode = ckp->smk_known; + else + isp->smk_inode = final; + +@@ -2840,13 +2862,14 @@ unlockandout: + */ + static int smack_getprocattr(struct task_struct *p, char *name, char **value) + { ++ struct smack_known *skp = smk_of_task(task_security(p)); + char *cp; + int slen; + + if (strcmp(name, "current") != 0) + return -EINVAL; + +- cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL); ++ cp = kstrdup(skp->smk_known, GFP_KERNEL); + if (cp == NULL) + return -ENOMEM; + +@@ -2872,7 +2895,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, + { + struct task_smack *tsp; + struct cred *new; +- char *newsmack; ++ struct smack_known *skp; + + /* + * Changing another process' Smack value is too dangerous +@@ -2890,14 +2913,14 @@ static int smack_setprocattr(struct task_struct *p, char *name, + if (strcmp(name, "current") != 0) + return -EINVAL; + +- newsmack = smk_import(value, size); +- if (newsmack == NULL) ++ skp = smk_import_entry(value, size); ++ if (skp == NULL) + return -EINVAL; + + /* + * No process is ever allowed the web ("@") label. + */ +- if (newsmack == smack_known_web.smk_known) ++ if (skp == &smack_known_web) + return -EPERM; + + new = prepare_creds(); +@@ -2905,7 +2928,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, + return -ENOMEM; + + tsp = new->security; +- tsp->smk_task = newsmack; ++ tsp->smk_task = skp; + + commit_creds(new); + return size; +@@ -2923,6 +2946,7 @@ static int smack_setprocattr(struct task_struct *p, char *name, + static int smack_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) + { ++ struct smack_known *skp; + struct socket_smack *ssp = sock->sk_security; + struct socket_smack *osp = other->sk_security; + struct socket_smack *nsp = newsk->sk_security; +@@ -2936,15 +2960,17 @@ static int smack_unix_stream_connect(struct sock *sock, + smk_ad_setfield_u_net_sk(&ad, other); + #endif + +- if (!smack_privileged(CAP_MAC_OVERRIDE)) +- rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); ++ if (!smack_privileged(CAP_MAC_OVERRIDE)) { ++ skp = ssp->smk_out; ++ rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad); ++ } + + /* + * Cross reference the peer labels for SO_PEERSEC. + */ + if (rc == 0) { +- nsp->smk_packet = ssp->smk_out; +- ssp->smk_packet = osp->smk_out; ++ nsp->smk_packet = ssp->smk_out->smk_known; ++ ssp->smk_packet = osp->smk_out->smk_known; + } + + return rc; +@@ -2962,8 +2988,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + { + struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *osp = other->sk->sk_security; ++ struct smack_known *skp; + struct smk_audit_info ad; +- int rc = 0; + + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; +@@ -2972,10 +2998,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + smk_ad_setfield_u_net_sk(&ad, other->sk); + #endif + +- if (!smack_privileged(CAP_MAC_OVERRIDE)) +- rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); ++ if (smack_privileged(CAP_MAC_OVERRIDE)) ++ return 0; + +- return rc; ++ skp = ssp->smk_out; ++ return smk_access(skp, osp->smk_in, MAY_WRITE, &ad); + } + + /** +@@ -3017,13 +3044,12 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + * @sap: netlabel secattr + * @ssp: socket security information + * +- * Returns a pointer to a Smack label found on the label list. ++ * Returns a pointer to a Smack label entry found on the label list. + */ +-static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, +- struct socket_smack *ssp) ++static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, ++ struct socket_smack *ssp) + { +- struct smack_known *kp; +- char *sp; ++ struct smack_known *skp; + int found = 0; + + if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { +@@ -3038,11 +3064,11 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, + * ambient value. + */ + rcu_read_lock(); +- list_for_each_entry(kp, &smack_known_list, list) { +- if (sap->attr.mls.lvl != kp->smk_netlabel.attr.mls.lvl) ++ list_for_each_entry(skp, &smack_known_list, list) { ++ if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl) + continue; + if (memcmp(sap->attr.mls.cat, +- kp->smk_netlabel.attr.mls.cat, ++ skp->smk_netlabel.attr.mls.cat, + SMK_CIPSOLEN) != 0) + continue; + found = 1; +@@ -3051,17 +3077,17 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, + rcu_read_unlock(); + + if (found) +- return kp->smk_known; ++ return skp; + + if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) +- return smack_known_web.smk_known; +- return smack_known_star.smk_known; ++ return &smack_known_web; ++ return &smack_known_star; + } + if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { + /* + * Looks like a fallback, which gives us a secid. + */ +- sp = smack_from_secid(sap->attr.secid); ++ skp = smack_from_secid(sap->attr.secid); + /* + * This has got to be a bug because it is + * impossible to specify a fallback without +@@ -3069,8 +3095,8 @@ static char *smack_from_secattr(struct netlbl_lsm_secattr *sap, + * it has a secid, and the only way to get a + * secid is from a fallback. + */ +- BUG_ON(sp == NULL); +- return sp; ++ BUG_ON(skp == NULL); ++ return skp; + } + /* + * Without guidance regarding the smack value +@@ -3139,8 +3165,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = sk->sk_security; ++ struct smack_known *skp; + struct sockaddr sadd; +- char *csp; + int rc = 0; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT +@@ -3155,9 +3181,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + + rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); + if (rc == 0) +- csp = smack_from_secattr(&secattr, ssp); ++ skp = smack_from_secattr(&secattr, ssp); + else +- csp = smack_net_ambient; ++ skp = smack_net_ambient; + + netlbl_secattr_destroy(&secattr); + +@@ -3173,7 +3199,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + * This is the simplist possible security model + * for networking. + */ +- rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; +@@ -3238,7 +3264,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + { + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = NULL; +- char *sp; ++ struct smack_known *skp; + int family = PF_UNSPEC; + u32 s = 0; /* 0 is the invalid secid */ + int rc; +@@ -3254,7 +3280,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + + if (family == PF_UNIX) { + ssp = sock->sk->sk_security; +- s = smack_to_secid(ssp->smk_out); ++ s = ssp->smk_out->smk_secid; + } else if (family == PF_INET || family == PF_INET6) { + /* + * Translate what netlabel gave us. +@@ -3264,8 +3290,8 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); + if (rc == 0) { +- sp = smack_from_secattr(&secattr, ssp); +- s = smack_to_secid(sp); ++ skp = smack_from_secattr(&secattr, ssp); ++ s = skp->smk_secid; + } + netlbl_secattr_destroy(&secattr); + } +@@ -3286,13 +3312,15 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + static void smack_sock_graft(struct sock *sk, struct socket *parent) + { + struct socket_smack *ssp; ++ struct smack_known *skp = smk_of_current(); + + if (sk == NULL || + (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) + return; + + ssp = sk->sk_security; +- ssp->smk_in = ssp->smk_out = smk_of_current(); ++ ssp->smk_in = skp->smk_known; ++ ssp->smk_out = skp; + /* cssp->smk_packet is already set in smack_inet_csk_clone() */ + } + +@@ -3314,7 +3342,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct netlbl_lsm_secattr secattr; + struct sockaddr_in addr; + struct iphdr *hdr; +- char *sp; + char *hsp; + int rc; + struct smk_audit_info ad; +@@ -3337,9 +3364,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); + if (rc == 0) +- sp = smack_from_secattr(&secattr, ssp); ++ skp = smack_from_secattr(&secattr, ssp); + else +- sp = smack_known_huh.smk_known; ++ skp = &smack_known_huh; + netlbl_secattr_destroy(&secattr); + + #ifdef CONFIG_AUDIT +@@ -3352,7 +3379,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * Receiving a packet requires that the other end be able to write + * here. Read access is not required. + */ +- rc = smk_access(sp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); + if (rc != 0) + return rc; + +@@ -3360,7 +3387,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * Save the peer's label in the request_sock so we can later setup + * smk_packet in the child socket so that SO_PEERCRED can report it. + */ +- req->peer_secid = smack_to_secid(sp); ++ req->peer_secid = skp->smk_secid; + + /* + * We need to decide if we want to label the incoming connection here +@@ -3373,10 +3400,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + hsp = smack_host_label(&addr); + rcu_read_unlock(); + +- if (hsp == NULL) { +- skp = smk_find_entry(sp); ++ if (hsp == NULL) + rc = netlbl_req_setattr(req, &skp->smk_netlabel); +- } else ++ else + netlbl_req_delattr(req); + + return rc; +@@ -3393,10 +3419,12 @@ static void smack_inet_csk_clone(struct sock *sk, + const struct request_sock *req) + { + struct socket_smack *ssp = sk->sk_security; ++ struct smack_known *skp; + +- if (req->peer_secid != 0) +- ssp->smk_packet = smack_from_secid(req->peer_secid); +- else ++ if (req->peer_secid != 0) { ++ skp = smack_from_secid(req->peer_secid); ++ ssp->smk_packet = skp->smk_known; ++ } else + ssp->smk_packet = NULL; + } + +@@ -3422,7 +3450,9 @@ static void smack_inet_csk_clone(struct sock *sk, + static int smack_key_alloc(struct key *key, const struct cred *cred, + unsigned long flags) + { +- key->security = smk_of_task(cred->security); ++ struct smack_known *skp = smk_of_task(cred->security); ++ ++ key->security = skp->smk_known; + return 0; + } + +@@ -3451,7 +3481,7 @@ static int smack_key_permission(key_ref_t key_ref, + { + struct key *keyp; + struct smk_audit_info ad; +- char *tsp = smk_of_task(cred->security); ++ struct smack_known *tkp = smk_of_task(cred->security); + + keyp = key_ref_to_ptr(key_ref); + if (keyp == NULL) +@@ -3465,15 +3495,14 @@ static int smack_key_permission(key_ref_t key_ref, + /* + * This should not occur + */ +- if (tsp == NULL) ++ if (tkp == NULL) + return -EACCES; + #ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); + ad.a.u.key_struct.key = keyp->serial; + ad.a.u.key_struct.key_desc = keyp->description; + #endif +- return smk_access(tsp, keyp->security, +- MAY_READWRITE, &ad); ++ return smk_access(tkp, keyp->security, MAY_READWRITE, &ad); + } + #endif /* CONFIG_KEYS */ + +@@ -3555,7 +3584,7 @@ static int smack_audit_rule_known(struct audit_krule *krule) + static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, + struct audit_context *actx) + { +- char *smack; ++ struct smack_known *skp; + char *rule = vrule; + + if (!rule) { +@@ -3567,7 +3596,7 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, + if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER) + return 0; + +- smack = smack_from_secid(secid); ++ skp = smack_from_secid(secid); + + /* + * No need to do string comparisons. If a match occurs, +@@ -3575,9 +3604,9 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, + * label. + */ + if (op == Audit_equal) +- return (rule == smack); ++ return (rule == skp->smk_known); + if (op == Audit_not_equal) +- return (rule != smack); ++ return (rule != skp->smk_known); + + return 0; + } +@@ -3605,11 +3634,11 @@ static void smack_audit_rule_free(void *vrule) + */ + static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + { +- char *sp = smack_from_secid(secid); ++ struct smack_known *skp = smack_from_secid(secid); + + if (secdata) +- *secdata = sp; +- *seclen = strlen(sp); ++ *secdata = skp->smk_known; ++ *seclen = strlen(skp->smk_known); + return 0; + } + +@@ -3845,8 +3874,8 @@ static __init int smack_init(void) + if (!security_module_enable(&smack_ops)) + return 0; + +- tsp = new_task_smack(smack_known_floor.smk_known, +- smack_known_floor.smk_known, GFP_KERNEL); ++ tsp = new_task_smack(&smack_known_floor, &smack_known_floor, ++ GFP_KERNEL); + if (tsp == NULL) + return -ENOMEM; + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 53a08b8..3c79cba 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -66,7 +66,7 @@ static DEFINE_MUTEX(smk_netlbladdr_lock); + * If it isn't somehow marked, use this. + * It can be reset via smackfs/ambient + */ +-char *smack_net_ambient; ++struct smack_known *smack_net_ambient; + + /* + * This is the level in a CIPSO header that indicates a +@@ -112,7 +112,7 @@ struct smack_master_list { + LIST_HEAD(smack_rule_list); + + struct smack_parsed_rule { +- char *smk_subject; ++ struct smack_known *smk_subject; + char *smk_object; + int smk_access1; + int smk_access2; +@@ -163,9 +163,11 @@ static inline void smack_catset_bit(unsigned int cat, char *catsetp) + */ + static void smk_netlabel_audit_set(struct netlbl_audit *nap) + { ++ struct smack_known *skp = smk_of_current(); ++ + nap->loginuid = audit_get_loginuid(current); + nap->sessionid = audit_get_sessionid(current); +- nap->secid = smack_to_secid(smk_of_current()); ++ nap->secid = skp->smk_secid; + } + + /* +@@ -306,7 +308,7 @@ static int smk_fill_rule(const char *subject, const char *object, + struct smack_known *skp; + + if (import) { +- rule->smk_subject = smk_import(subject, len); ++ rule->smk_subject = smk_import_entry(subject, len); + if (rule->smk_subject == NULL) + return -1; + +@@ -321,7 +323,7 @@ static int smk_fill_rule(const char *subject, const char *object, + kfree(cp); + if (skp == NULL) + return -1; +- rule->smk_subject = skp->smk_known; ++ rule->smk_subject = skp; + + cp = smk_parse_smack(object, len); + if (cp == NULL) +@@ -445,7 +447,6 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + struct list_head *rule_list, + struct mutex *rule_lock, int format) + { +- struct smack_known *skp; + struct smack_parsed_rule *rule; + char *data; + int datalen; +@@ -505,12 +506,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + goto out_free_rule; + } + +- + if (rule_list == NULL) { + load = 1; +- skp = smk_find_entry(rule->smk_subject); +- rule_list = &skp->smk_rules; +- rule_lock = &skp->smk_rules_lock; ++ rule_list = &rule->smk_subject->smk_rules; ++ rule_lock = &rule->smk_subject->smk_rules_lock; + } + + rc = smk_set_access(rule, rule_list, rule_lock, load); +@@ -579,13 +578,14 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) + * because you should expect to be able to write + * anything you read back. + */ +- if (strlen(srp->smk_subject) >= max || strlen(srp->smk_object) >= max) ++ if (strlen(srp->smk_subject->smk_known) >= max || ++ strlen(srp->smk_object) >= max) + return; + + if (srp->smk_access == 0) + return; + +- seq_printf(s, "%s %s", srp->smk_subject, srp->smk_object); ++ seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object); + + seq_putc(s, ' '); + +@@ -738,9 +738,9 @@ static void smk_unlbl_ambient(char *oldambient) + __func__, __LINE__, rc); + } + if (smack_net_ambient == NULL) +- smack_net_ambient = smack_known_floor.smk_known; ++ smack_net_ambient = &smack_known_floor; + +- rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, ++ rc = netlbl_cfg_unlbl_map_add(smack_net_ambient->smk_known, PF_INET, + NULL, NULL, &nai); + if (rc != 0) + printk(KERN_WARNING "%s:%d add rc = %d\n", +@@ -1535,11 +1535,12 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, + */ + mutex_lock(&smack_ambient_lock); + +- asize = strlen(smack_net_ambient) + 1; ++ asize = strlen(smack_net_ambient->smk_known) + 1; + + if (cn >= asize) + rc = simple_read_from_buffer(buf, cn, ppos, +- smack_net_ambient, asize); ++ smack_net_ambient->smk_known, ++ asize); + else + rc = -EINVAL; + +@@ -1560,8 +1561,8 @@ static ssize_t smk_read_ambient(struct file *filp, char __user *buf, + static ssize_t smk_write_ambient(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { ++ struct smack_known *skp; + char *oldambient; +- char *smack = NULL; + char *data; + int rc = count; + +@@ -1577,16 +1578,16 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf, + goto out; + } + +- smack = smk_import(data, count); +- if (smack == NULL) { ++ skp = smk_import_entry(data, count); ++ if (skp == NULL) { + rc = -EINVAL; + goto out; + } + + mutex_lock(&smack_ambient_lock); + +- oldambient = smack_net_ambient; +- smack_net_ambient = smack; ++ oldambient = smack_net_ambient->smk_known; ++ smack_net_ambient = skp; + smk_unlbl_ambient(oldambient); + + mutex_unlock(&smack_ambient_lock); +@@ -1645,7 +1646,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { + char *data; +- char *sp = smk_of_task(current->cred->security); ++ struct smack_known *skp = smk_of_task(current->cred->security); + int rc = count; + + if (!smack_privileged(CAP_MAC_ADMIN)) +@@ -1656,7 +1657,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, + * explicitly for clarity. The smk_access() implementation + * would use smk_access(smack_onlycap, MAY_WRITE) + */ +- if (smack_onlycap != NULL && smack_onlycap != sp) ++ if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) + return -EPERM; + + data = kzalloc(count, GFP_KERNEL); +@@ -1866,8 +1867,8 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, + if (res) + return -EINVAL; + +- res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access1, +- NULL); ++ res = smk_access(rule.smk_subject, rule.smk_object, ++ rule.smk_access1, NULL); + data[0] = res == 0 ? '1' : '0'; + data[1] = '\0'; + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0003-Smack-Add-smkfstransmute-mount-option.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0003-Smack-Add-smkfstransmute-mount-option.patch new file mode 100644 index 0000000..5f9a218 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0003-Smack-Add-smkfstransmute-mount-option.patch @@ -0,0 +1,101 @@ +From 4e05ff0ecdea0eca7bee89f38553b14cd12c15ec Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Wed, 22 May 2013 18:43:07 -0700 +Subject: [PATCH 03/54] Smack: Add smkfstransmute mount option + +Suppliment the smkfsroot mount option with another, smkfstransmute, +that does the same thing but also marks the root inode as +transmutting. This allows a freshly created filesystem to +be mounted with a transmutting heirarchy. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 1 + + security/smack/smack_lsm.c | 25 ++++++++++++++++++++----- + 2 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 159f25b..339614c 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -143,6 +143,7 @@ struct smk_port_label { + #define SMK_FSFLOOR "smackfsfloor=" + #define SMK_FSHAT "smackfshat=" + #define SMK_FSROOT "smackfsroot=" ++#define SMK_FSTRANS "smackfstransmute=" + + #define SMACK_CIPSO_OPTION "-CIPSO" + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 3669d9f..6a08330 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -261,8 +261,9 @@ static int smack_sb_alloc_security(struct super_block *sb) + sbsp->smk_default = smack_known_floor.smk_known; + sbsp->smk_floor = smack_known_floor.smk_known; + sbsp->smk_hat = smack_known_hat.smk_known; +- sbsp->smk_initialized = 0; +- ++ /* ++ * smk_initialized will be zero from kzalloc. ++ */ + sb->s_security = sbsp; + + return 0; +@@ -306,6 +307,8 @@ static int smack_sb_copy_data(char *orig, char *smackopts) + dp = smackopts; + else if (strstr(cp, SMK_FSROOT) == cp) + dp = smackopts; ++ else if (strstr(cp, SMK_FSTRANS) == cp) ++ dp = smackopts; + else + dp = otheropts; + +@@ -341,8 +344,9 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + char *op; + char *commap; + char *nsp; ++ int transmute = 0; + +- if (sp->smk_initialized != 0) ++ if (sp->smk_initialized) + return 0; + + sp->smk_initialized = 1; +@@ -373,6 +377,13 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + nsp = smk_import(op, 0); + if (nsp != NULL) + sp->smk_root = nsp; ++ } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { ++ op += strlen(SMK_FSTRANS); ++ nsp = smk_import(op, 0); ++ if (nsp != NULL) { ++ sp->smk_root = nsp; ++ transmute = 1; ++ } + } + } + +@@ -380,11 +391,15 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + * Initialize the root inode. + */ + isp = inode->i_security; +- if (isp == NULL) ++ if (inode->i_security == NULL) { + inode->i_security = new_inode_smack(sp->smk_root); +- else ++ isp = inode->i_security; ++ } else + isp->smk_inode = sp->smk_root; + ++ if (transmute) ++ isp->smk_flags |= SMK_INODE_TRANSMUTE; ++ + return 0; + } + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch new file mode 100644 index 0000000..a0430ec --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch @@ -0,0 +1,29 @@ +From a7982ea90c9233c737923a9361229bbfc63caa2e Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 27 May 2013 20:11:27 +0900 +Subject: [PATCH 04/54] Smack: Fix possible NULL pointer dereference at + smk_netlbl_mls() + +netlbl_secattr_catmap_alloc(GFP_ATOMIC) can return NULL. + +Signed-off-by: Tetsuo Handa +--- + security/smack/smack_access.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 53f2327..6a0377f 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -403,6 +403,8 @@ int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, + sap->flags |= NETLBL_SECATTR_MLS_CAT; + sap->attr.mls.lvl = level; + sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); ++ if (!sap->attr.mls.cat) ++ return -ENOMEM; + sap->attr.mls.cat->startbit = 0; + + for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch new file mode 100644 index 0000000..d50aa45 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch @@ -0,0 +1,36 @@ +From 99c1ba83e749446ef633197f2f78642171baa30d Mon Sep 17 00:00:00 2001 +From: "Passion,Zhao" +Date: Mon, 3 Jun 2013 11:42:24 +0800 +Subject: [PATCH 05/54] Smack: Fix the bug smackcipso can't set CIPSO correctly + +Bug report: https://tizendev.org/bugs/browse/TDIS-3891 + +The reason is userspace libsmack only use "smackfs/cipso2" long-label interface, +but the code's logical is still for orginal fixed length label. Now update +smack_cipso_apply() to support flexible label (<=256 including tailing '\0') + +There is also a bug in kernel/security/smack/smackfs.c: +When smk_set_cipso() parsing the CIPSO setting from userspace, the offset of +CIPSO level should be "strlen(label)+1" instead of "strlen(label)" + +Signed-off-by: Passion,Zhao +--- + security/smack/smackfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 3c79cba..ab16703 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -881,7 +881,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, + if (format == SMK_FIXED24_FMT) + rule += SMK_LABELLEN; + else +- rule += strlen(skp->smk_known); ++ rule += strlen(skp->smk_known) + 1; + + ret = sscanf(rule, "%d", &maplevel); + if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch new file mode 100644 index 0000000..2539ff6 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch @@ -0,0 +1,170 @@ +From 2a47b333efc3a2cb768eaba9d35e1467b3bc6211 Mon Sep 17 00:00:00 2001 +From: David Quigley +Date: Wed, 22 May 2013 12:50:35 -0400 +Subject: [PATCH 06/54] Security: Add Hook to test if the particular xattr is + part of a MAC model. + +The interface to request security labels from user space is the xattr +interface. When requesting the security label from an NFS server it is +important to make sure the requested xattr actually is a MAC label. This allows +us to make sure that we get the desired semantics from the attribute instead of +something else such as capabilities or a time based LSM. + +Acked-by: Eric Paris +Acked-by: James Morris +Signed-off-by: Matthew N. Dodd +Signed-off-by: Miguel Rodel Felipe +Signed-off-by: Phua Eu Gene +Signed-off-by: Khin Mi Mi Aung +Signed-off-by: Trond Myklebust +--- + include/linux/security.h | 14 ++++++++++++++ + security/capability.c | 6 ++++++ + security/security.c | 6 ++++++ + security/selinux/hooks.c | 6 ++++++ + security/smack/smack_lsm.c | 11 +++++++++++ + 5 files changed, 43 insertions(+) + +diff --git a/include/linux/security.h b/include/linux/security.h +index 4686491..1d8fe3c 100644 +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -1313,6 +1313,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) + * @pages contains the number of pages. + * Return 0 if permission is granted. + * ++ * @ismaclabel: ++ * Check if the extended attribute specified by @name ++ * represents a MAC label. Returns 1 if name is a MAC ++ * attribute otherwise returns 0. ++ * @name full extended attribute name to check against ++ * LSM as a MAC label. ++ * + * @secid_to_secctx: + * Convert secid to security context. If secdata is NULL the length of + * the result will be returned in seclen, but no secdata will be returned. +@@ -1590,6 +1597,7 @@ struct security_operations { + + int (*getprocattr) (struct task_struct *p, char *name, char **value); + int (*setprocattr) (struct task_struct *p, char *name, void *value, size_t size); ++ int (*ismaclabel) (const char *name); + int (*secid_to_secctx) (u32 secid, char **secdata, u32 *seclen); + int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); + void (*release_secctx) (char *secdata, u32 seclen); +@@ -1840,6 +1848,7 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode); + int security_getprocattr(struct task_struct *p, char *name, char **value); + int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size); + int security_netlink_send(struct sock *sk, struct sk_buff *skb); ++int security_ismaclabel(const char *name); + int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); + int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); + void security_release_secctx(char *secdata, u32 seclen); +@@ -2520,6 +2529,11 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) + return cap_netlink_send(sk, skb); + } + ++static inline int security_ismaclabel(const char *name) ++{ ++ return 0; ++} ++ + static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + { + return -EOPNOTSUPP; +diff --git a/security/capability.c b/security/capability.c +index 1728d4e..26e0d3d 100644 +--- a/security/capability.c ++++ b/security/capability.c +@@ -816,6 +816,11 @@ static int cap_setprocattr(struct task_struct *p, char *name, void *value, + return -EINVAL; + } + ++static int cap_ismaclabel(const char *name) ++{ ++ return 0; ++} ++ + static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + { + return -EOPNOTSUPP; +@@ -1034,6 +1039,7 @@ void __init security_fixup_ops(struct security_operations *ops) + set_to_cap_if_null(ops, d_instantiate); + set_to_cap_if_null(ops, getprocattr); + set_to_cap_if_null(ops, setprocattr); ++ set_to_cap_if_null(ops, ismaclabel); + set_to_cap_if_null(ops, secid_to_secctx); + set_to_cap_if_null(ops, secctx_to_secid); + set_to_cap_if_null(ops, release_secctx); +diff --git a/security/security.c b/security/security.c +index a3dce87..bf919ce 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -1047,6 +1047,12 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb) + return security_ops->netlink_send(sk, skb); + } + ++int security_ismaclabel(const char *name) ++{ ++ return security_ops->ismaclabel(name); ++} ++EXPORT_SYMBOL(security_ismaclabel); ++ + int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + { + return security_ops->secid_to_secctx(secid, secdata, seclen); +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index a7096e1..d2f4381 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -5526,6 +5526,11 @@ abort_change: + return error; + } + ++static int selinux_ismaclabel(const char *name) ++{ ++ return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0); ++} ++ + static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + { + return security_sid_to_context(secid, secdata, seclen); +@@ -5763,6 +5768,7 @@ static struct security_operations selinux_ops = { + .getprocattr = selinux_getprocattr, + .setprocattr = selinux_setprocattr, + ++ .ismaclabel = selinux_ismaclabel, + .secid_to_secctx = selinux_secid_to_secctx, + .secctx_to_secid = selinux_secctx_to_secid, + .release_secctx = selinux_release_secctx, +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 6a08330..3f7682a 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3640,6 +3640,16 @@ static void smack_audit_rule_free(void *vrule) + #endif /* CONFIG_AUDIT */ + + /** ++ * smack_ismaclabel - check if xattr @name references a smack MAC label ++ * @name: Full xattr name to check. ++ */ ++static int smack_ismaclabel(const char *name) ++{ ++ return (strcmp(name, XATTR_SMACK_SUFFIX) == 0); ++} ++ ++ ++/** + * smack_secid_to_secctx - return the smack label for a secid + * @secid: incoming integer + * @secdata: destination +@@ -3836,6 +3846,7 @@ struct security_operations smack_ops = { + .audit_rule_free = smack_audit_rule_free, + #endif /* CONFIG_AUDIT */ + ++ .ismaclabel = smack_ismaclabel, + .secid_to_secctx = smack_secid_to_secctx, + .secctx_to_secid = smack_secctx_to_secid, + .release_secctx = smack_release_secctx, +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0007-xattr-Constify-name-member-of-struct-xattr.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0007-xattr-Constify-name-member-of-struct-xattr.patch new file mode 100644 index 0000000..01e1e95 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0007-xattr-Constify-name-member-of-struct-xattr.patch @@ -0,0 +1,239 @@ +From fe82cc13962e6dbf81dec4093e7dc947b296a988 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Thu, 25 Jul 2013 05:44:02 +0900 +Subject: [PATCH 07/54] xattr: Constify ->name member of "struct xattr". + +Since everybody sets kstrdup()ed constant string to "struct xattr"->name but +nobody modifies "struct xattr"->name , we can omit kstrdup() and its failure +checking by constifying ->name member of "struct xattr". + +Signed-off-by: Tetsuo Handa +Reviewed-by: Joel Becker [ocfs2] +Acked-by: Serge E. Hallyn +Acked-by: Casey Schaufler +Acked-by: Mimi Zohar +Reviewed-by: Paul Moore +Tested-by: Paul Moore +Acked-by: Eric Paris +Signed-off-by: James Morris +--- + fs/ocfs2/xattr.h | 2 +- + include/linux/security.h | 8 ++++---- + include/linux/xattr.h | 2 +- + include/uapi/linux/reiserfs_xattr.h | 2 +- + security/capability.c | 2 +- + security/integrity/evm/evm_main.c | 2 +- + security/security.c | 8 +++----- + security/selinux/hooks.c | 17 ++++++----------- + security/smack/smack_lsm.c | 9 +++------ + 9 files changed, 21 insertions(+), 31 deletions(-) + +diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h +index e5c7f15..19f134e 100644 +--- a/fs/ocfs2/xattr.h ++++ b/fs/ocfs2/xattr.h +@@ -32,7 +32,7 @@ enum ocfs2_xattr_type { + + struct ocfs2_security_xattr_info { + int enable; +- char *name; ++ const char *name; + void *value; + size_t value_len; + }; +diff --git a/include/linux/security.h b/include/linux/security.h +index 1d8fe3c..0f246d4 100644 +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -1472,7 +1472,7 @@ struct security_operations { + int (*inode_alloc_security) (struct inode *inode); + void (*inode_free_security) (struct inode *inode); + int (*inode_init_security) (struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, const char **name, + void **value, size_t *len); + int (*inode_create) (struct inode *dir, + struct dentry *dentry, umode_t mode); +@@ -1744,7 +1744,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, + const struct qstr *qstr, + initxattrs initxattrs, void *fs_data); + int security_old_inode_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, const char **name, + void **value, size_t *len); + int security_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode); + int security_inode_link(struct dentry *old_dentry, struct inode *dir, +@@ -2056,8 +2056,8 @@ static inline int security_inode_init_security(struct inode *inode, + static inline int security_old_inode_init_security(struct inode *inode, + struct inode *dir, + const struct qstr *qstr, +- char **name, void **value, +- size_t *len) ++ const char **name, ++ void **value, size_t *len) + { + return -EOPNOTSUPP; + } +diff --git a/include/linux/xattr.h b/include/linux/xattr.h +index fdbafc6..91b0a68 100644 +--- a/include/linux/xattr.h ++++ b/include/linux/xattr.h +@@ -31,7 +31,7 @@ struct xattr_handler { + }; + + struct xattr { +- char *name; ++ const char *name; + void *value; + size_t value_len; + }; +diff --git a/include/uapi/linux/reiserfs_xattr.h b/include/uapi/linux/reiserfs_xattr.h +index d8ce17c..38fdd64 100644 +--- a/include/uapi/linux/reiserfs_xattr.h ++++ b/include/uapi/linux/reiserfs_xattr.h +@@ -16,7 +16,7 @@ struct reiserfs_xattr_header { + }; + + struct reiserfs_security_handle { +- char *name; ++ const char *name; + void *value; + size_t length; + }; +diff --git a/security/capability.c b/security/capability.c +index 26e0d3d..432e8af 100644 +--- a/security/capability.c ++++ b/security/capability.c +@@ -119,7 +119,7 @@ static void cap_inode_free_security(struct inode *inode) + } + + static int cap_inode_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, const char **name, + void **value, size_t *len) + { + return -EOPNOTSUPP; +diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c +index cdbde17..2787080 100644 +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -405,7 +405,7 @@ int evm_inode_init_security(struct inode *inode, + + evm_xattr->value = xattr_data; + evm_xattr->value_len = sizeof(*xattr_data); +- evm_xattr->name = kstrdup(XATTR_EVM_SUFFIX, GFP_NOFS); ++ evm_xattr->name = XATTR_EVM_SUFFIX; + return 0; + out: + kfree(xattr_data); +diff --git a/security/security.c b/security/security.c +index bf919ce..7813fd8 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -335,10 +335,10 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, + if (unlikely(IS_PRIVATE(inode))) + return 0; + +- memset(new_xattrs, 0, sizeof new_xattrs); + if (!initxattrs) + return security_ops->inode_init_security(inode, dir, qstr, + NULL, NULL, NULL); ++ memset(new_xattrs, 0, sizeof(new_xattrs)); + lsm_xattr = new_xattrs; + ret = security_ops->inode_init_security(inode, dir, qstr, + &lsm_xattr->name, +@@ -353,16 +353,14 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, + goto out; + ret = initxattrs(inode, new_xattrs, fs_data); + out: +- for (xattr = new_xattrs; xattr->name != NULL; xattr++) { +- kfree(xattr->name); ++ for (xattr = new_xattrs; xattr->value != NULL; xattr++) + kfree(xattr->value); +- } + return (ret == -EOPNOTSUPP) ? 0 : ret; + } + EXPORT_SYMBOL(security_inode_init_security); + + int security_old_inode_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, const char **name, + void **value, size_t *len) + { + if (unlikely(IS_PRIVATE(inode))) +diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c +index d2f4381..0c47e2c 100644 +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -2533,7 +2533,8 @@ static void selinux_inode_free_security(struct inode *inode) + } + + static int selinux_inode_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, ++ const char **name, + void **value, size_t *len) + { + const struct task_security_struct *tsec = current_security(); +@@ -2541,7 +2542,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, + struct superblock_security_struct *sbsec; + u32 sid, newsid, clen; + int rc; +- char *namep = NULL, *context; ++ char *context; + + dsec = dir->i_security; + sbsec = dir->i_sb->s_security; +@@ -2577,19 +2578,13 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, + if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP)) + return -EOPNOTSUPP; + +- if (name) { +- namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_NOFS); +- if (!namep) +- return -ENOMEM; +- *name = namep; +- } ++ if (name) ++ *name = XATTR_SELINUX_SUFFIX; + + if (value && len) { + rc = security_sid_to_context_force(newsid, &context, &clen); +- if (rc) { +- kfree(namep); ++ if (rc) + return rc; +- } + *value = context; + *len = clen; + } +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 3f7682a..a113a77 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -582,7 +582,7 @@ static void smack_inode_free_security(struct inode *inode) + * Returns 0 if it all works out, -ENOMEM if there's no memory + */ + static int smack_inode_init_security(struct inode *inode, struct inode *dir, +- const struct qstr *qstr, char **name, ++ const struct qstr *qstr, const char **name, + void **value, size_t *len) + { + struct inode_smack *issp = inode->i_security; +@@ -591,11 +591,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + char *dsp = smk_of_inode(dir); + int may; + +- if (name) { +- *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_NOFS); +- if (*name == NULL) +- return -ENOMEM; +- } ++ if (name) ++ *name = XATTR_SMACK_SUFFIX; + + if (value) { + rcu_read_lock(); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0008-security-smack-fix-memleak-in-smk_write_rules_list.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0008-security-smack-fix-memleak-in-smk_write_rules_list.patch new file mode 100644 index 0000000..85e2c6f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0008-security-smack-fix-memleak-in-smk_write_rules_list.patch @@ -0,0 +1,89 @@ +From ebd488438bac4d71d95ed21281fce2b429804662 Mon Sep 17 00:00:00 2001 +From: Tomasz Stanislawski +Date: Thu, 6 Jun 2013 09:30:50 +0200 +Subject: [PATCH 08/54] security: smack: fix memleak in smk_write_rules_list() + +The smack_parsed_rule structure is allocated. If a rule is successfully +installed then the last reference to the object is lost. This patch fixes this +leak. Moreover smack_parsed_rule is allocated on stack because it no longer +needed ofter smk_write_rules_list() is finished. + +Signed-off-by: Tomasz Stanislawski +--- + security/smack/smackfs.c | 33 +++++++++++---------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index ab16703..269b270 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -447,7 +447,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + struct list_head *rule_list, + struct mutex *rule_lock, int format) + { +- struct smack_parsed_rule *rule; ++ struct smack_parsed_rule rule; + char *data; + int datalen; + int rc = -EINVAL; +@@ -479,47 +479,36 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + goto out; + } + +- rule = kzalloc(sizeof(*rule), GFP_KERNEL); +- if (rule == NULL) { +- rc = -ENOMEM; +- goto out; +- } +- + if (format == SMK_LONG_FMT) { + /* + * Be sure the data string is terminated. + */ + data[count] = '\0'; +- if (smk_parse_long_rule(data, rule, 1, 0)) +- goto out_free_rule; ++ if (smk_parse_long_rule(data, &rule, 1, 0)) ++ goto out; + } else if (format == SMK_CHANGE_FMT) { + data[count] = '\0'; +- if (smk_parse_long_rule(data, rule, 1, 1)) +- goto out_free_rule; ++ if (smk_parse_long_rule(data, &rule, 1, 1)) ++ goto out; + } else { + /* + * More on the minor hack for backward compatibility + */ + if (count == (SMK_OLOADLEN)) + data[SMK_OLOADLEN] = '-'; +- if (smk_parse_rule(data, rule, 1)) +- goto out_free_rule; ++ if (smk_parse_rule(data, &rule, 1)) ++ goto out; + } + + if (rule_list == NULL) { + load = 1; +- rule_list = &rule->smk_subject->smk_rules; +- rule_lock = &rule->smk_subject->smk_rules_lock; ++ rule_list = &rule.smk_subject->smk_rules; ++ rule_lock = &rule.smk_subject->smk_rules_lock; + } + +- rc = smk_set_access(rule, rule_list, rule_lock, load); +- if (rc == 0) { ++ rc = smk_set_access(&rule, rule_list, rule_lock, load); ++ if (rc == 0) + rc = count; +- goto out; +- } +- +-out_free_rule: +- kfree(rule); + out: + kfree(data); + return rc; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch new file mode 100644 index 0000000..f0ec92a --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch @@ -0,0 +1,166 @@ +From 505330bc05798436b7be090167ff0dfcffea973b Mon Sep 17 00:00:00 2001 +From: Tomasz Stanislawski +Date: Tue, 11 Jun 2013 14:55:13 +0200 +Subject: [PATCH 09/54] security: smack: add a hash table to quicken + smk_find_entry() + +Accepted for the smack-next tree after changing the number of +slots from 128 to 16. + +This patch adds a hash table to quicken searching of a smack label by its name. + +Basically, the patch improves performance of SMACK initialization. Parsing of +rules involves translation from a string to a smack_known (aka label) entity +which is done in smk_find_entry(). + +The current implementation of the function iterates over a global list of +smack_known resulting in O(N) complexity for smk_find_entry(). The total +complexity of SMACK initialization becomes O(rules * labels). Therefore it +scales quadratically with a complexity of a system. + +Applying the patch reduced the complexity of smk_find_entry() to O(1) as long +as number of label is in hundreds. If the number of labels is increased please +update SMACK_HASH_SLOTS constant defined in security/smack/smack.h. Introducing +the configuration of this constant with Kconfig or cmdline might be a good +idea. + +The size of the hash table was adjusted experimentally. The rule set used by +TIZEN contains circa 17K rules for 500 labels. The table above contains +results of SMACK initialization using 'time smackctl apply' bash command. +The 'Ref' is a kernel without this patch applied. The consecutive values +refers to value of SMACK_HASH_SLOTS. Every measurement was repeated three +times to reduce noise. + + | Ref | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 +-------------------------------------------------------------------------------------------- +Run1 | 1.156 | 1.096 | 0.883 | 0.764 | 0.692 | 0.667 | 0.649 | 0.633 | 0.634 | 0.629 | 0.620 +Run2 | 1.156 | 1.111 | 0.885 | 0.764 | 0.694 | 0.661 | 0.649 | 0.651 | 0.634 | 0.638 | 0.623 +Run3 | 1.160 | 1.107 | 0.886 | 0.764 | 0.694 | 0.671 | 0.661 | 0.638 | 0.631 | 0.624 | 0.638 +AVG | 1.157 | 1.105 | 0.885 | 0.764 | 0.693 | 0.666 | 0.653 | 0.641 | 0.633 | 0.630 | 0.627 + +Surprisingly, a single hlist is slightly faster than a double-linked list. +The speed-up saturates near 64 slots. Therefore I chose value 128 to provide +some margin if more labels were used. +It looks that IO becomes a new bottleneck. + +Signed-off-by: Tomasz Stanislawski +--- + security/smack/smack.h | 5 +++++ + security/smack/smack_access.c | 29 ++++++++++++++++++++++++++--- + security/smack/smack_lsm.c | 12 ++++++------ + 3 files changed, 37 insertions(+), 9 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 339614c..e80597a 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -53,6 +53,7 @@ + */ + struct smack_known { + struct list_head list; ++ struct hlist_node smk_hashed; + char *smk_known; + u32 smk_secid; + struct netlbl_lsm_secattr smk_netlabel; /* on wire labels */ +@@ -222,6 +223,7 @@ char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); + char *smk_import(const char *, int); + struct smack_known *smk_import_entry(const char *, int); ++void smk_insert_entry(struct smack_known *skp); + struct smack_known *smk_find_entry(const char *); + u32 smack_to_secid(const char *); + +@@ -247,6 +249,9 @@ extern struct list_head smk_netlbladdr_list; + + extern struct security_operations smack_ops; + ++#define SMACK_HASH_SLOTS 16 ++extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; ++ + /* + * Is the directory transmuting? + */ +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 6a0377f..b3b59b1 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -325,6 +325,25 @@ void smack_log(char *subject_label, char *object_label, int request, + + DEFINE_MUTEX(smack_known_lock); + ++struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; ++ ++/** ++ * smk_insert_entry - insert a smack label into a hash map, ++ * ++ * this function must be called under smack_known_lock ++ */ ++void smk_insert_entry(struct smack_known *skp) ++{ ++ unsigned int hash; ++ struct hlist_head *head; ++ ++ hash = full_name_hash(skp->smk_known, strlen(skp->smk_known)); ++ head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; ++ ++ hlist_add_head_rcu(&skp->smk_hashed, head); ++ list_add_rcu(&skp->list, &smack_known_list); ++} ++ + /** + * smk_find_entry - find a label on the list, return the list entry + * @string: a text string that might be a Smack label +@@ -334,12 +353,16 @@ DEFINE_MUTEX(smack_known_lock); + */ + struct smack_known *smk_find_entry(const char *string) + { ++ unsigned int hash; ++ struct hlist_head *head; + struct smack_known *skp; + +- list_for_each_entry_rcu(skp, &smack_known_list, list) { ++ hash = full_name_hash(string, strlen(string)); ++ head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; ++ ++ hlist_for_each_entry_rcu(skp, head, smk_hashed) + if (strcmp(skp->smk_known, string) == 0) + return skp; +- } + + return NULL; + } +@@ -475,7 +498,7 @@ struct smack_known *smk_import_entry(const char *string, int len) + * Make sure that the entry is actually + * filled before putting it on the list. + */ +- list_add_rcu(&skp->list, &smack_known_list); ++ smk_insert_entry(skp); + goto unlockout; + } + /* +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index a113a77..f70a0fa 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3876,12 +3876,12 @@ static __init void init_smack_known_list(void) + /* + * Create the known labels list + */ +- list_add(&smack_known_huh.list, &smack_known_list); +- list_add(&smack_known_hat.list, &smack_known_list); +- list_add(&smack_known_star.list, &smack_known_list); +- list_add(&smack_known_floor.list, &smack_known_list); +- list_add(&smack_known_invalid.list, &smack_known_list); +- list_add(&smack_known_web.list, &smack_known_list); ++ smk_insert_entry(&smack_known_huh); ++ smk_insert_entry(&smack_known_hat); ++ smk_insert_entry(&smack_known_star); ++ smk_insert_entry(&smack_known_floor); ++ smk_insert_entry(&smack_known_invalid); ++ smk_insert_entry(&smack_known_web); + } + + /** +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0010-Smack-network-label-match-fix.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0010-Smack-network-label-match-fix.patch new file mode 100644 index 0000000..bfb9ad0 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0010-Smack-network-label-match-fix.patch @@ -0,0 +1,110 @@ +From 5ef1f5e8b97be9a415ad0828202d5ea03af377c7 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Fri, 28 Jun 2013 13:47:07 -0700 +Subject: [PATCH 10/54] Smack: network label match fix + +The Smack code that matches incoming CIPSO tags with Smack labels +reaches through the NetLabel interfaces and compares the network +data with the CIPSO header associated with a Smack label. This was +done in a ill advised attempt to optimize performance. It works +so long as the categories fit in a single capset, but this isn't +always the case. + +This patch changes the Smack code to use the appropriate NetLabel +interfaces to compare the incoming CIPSO header with the CIPSO +header associated with a label. It will always match the CIPSO +headers correctly. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 8 ++++++-- + security/smack/smack_lsm.c | 30 ++++++++++++++++++++++++------ + security/smack/smackfs.c | 2 +- + 3 files changed, 31 insertions(+), 9 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index e80597a..076b8e8 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -168,9 +168,13 @@ struct smk_port_label { + #define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */ + #define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ + #define SMACK_CIPSO_MAPPED_DEFAULT 251 /* Also arbitrary */ +-#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */ + #define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ +-#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ ++/* ++ * CIPSO 2.2 standard is 239, but Smack wants to use the ++ * categories in a structured way that limits the value to ++ * the bits in 23 bytes, hence the unusual number. ++ */ ++#define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ + + /* + * Flag for transmute access +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index f70a0fa..19de5e2 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3063,6 +3063,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + { + struct smack_known *skp; + int found = 0; ++ int acat; ++ int kcat; + + if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { + /* +@@ -3079,12 +3081,28 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + list_for_each_entry(skp, &smack_known_list, list) { + if (sap->attr.mls.lvl != skp->smk_netlabel.attr.mls.lvl) + continue; +- if (memcmp(sap->attr.mls.cat, +- skp->smk_netlabel.attr.mls.cat, +- SMK_CIPSOLEN) != 0) +- continue; +- found = 1; +- break; ++ /* ++ * Compare the catsets. Use the netlbl APIs. ++ */ ++ if ((sap->flags & NETLBL_SECATTR_MLS_CAT) == 0) { ++ if ((skp->smk_netlabel.flags & ++ NETLBL_SECATTR_MLS_CAT) == 0) ++ found = 1; ++ break; ++ } ++ for (acat = -1, kcat = -1; acat == kcat; ) { ++ acat = netlbl_secattr_catmap_walk( ++ sap->attr.mls.cat, acat + 1); ++ kcat = netlbl_secattr_catmap_walk( ++ skp->smk_netlabel.attr.mls.cat, ++ kcat + 1); ++ if (acat < 0 || kcat < 0) ++ break; ++ } ++ if (acat == kcat) { ++ found = 1; ++ break; ++ } + } + rcu_read_unlock(); + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 269b270..a07e93f 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -890,7 +890,7 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf, + for (i = 0; i < catlen; i++) { + rule += SMK_DIGITLEN; + ret = sscanf(rule, "%u", &cat); +- if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) ++ if (ret != 1 || cat > SMACK_CIPSO_MAXCATNUM) + goto out; + + smack_catset_bit(cat, mapcatset); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0011-Smack-IPv6-casting-error-fix-for-3.11.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0011-Smack-IPv6-casting-error-fix-for-3.11.patch new file mode 100644 index 0000000..617715b --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0011-Smack-IPv6-casting-error-fix-for-3.11.patch @@ -0,0 +1,105 @@ +From e1a1ad9641f7721edb0f52f0280cfc699ba4690c Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 5 Aug 2013 13:21:22 -0700 +Subject: [PATCH 11/54] Smack: IPv6 casting error fix for 3.11 + +The original implementation of the Smack IPv6 port based +local controls works most of the time using a sockaddr as +a temporary variable, but not always as it overflows in +some circumstances. The correct data is a sockaddr_in6. +A struct sockaddr isn't as large as a struct sockaddr_in6. +There would need to be casting one way or the other. This +patch gets it the right way. + +Signed-off-by: Casey Schaufler +Signed-off-by: James Morris +--- + security/smack/smack_lsm.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 19de5e2..8825375 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1995,12 +1995,11 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) + * + * Create or update the port list entry + */ +-static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, ++static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + int act) + { + __be16 *bep; + __be32 *be32p; +- struct sockaddr_in6 *addr6; + struct smk_port_label *spp; + struct socket_smack *ssp = sk->sk_security; + struct smack_known *skp; +@@ -2022,10 +2021,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, + /* + * Get the IP address and port from the address. + */ +- addr6 = (struct sockaddr_in6 *)address; +- port = ntohs(addr6->sin6_port); +- bep = (__be16 *)(&addr6->sin6_addr); +- be32p = (__be32 *)(&addr6->sin6_addr); ++ port = ntohs(address->sin6_port); ++ bep = (__be16 *)(&address->sin6_addr); ++ be32p = (__be32 *)(&address->sin6_addr); + + /* + * It's remote, so port lookup does no good. +@@ -2057,9 +2055,9 @@ auditout: + ad.a.u.net->family = sk->sk_family; + ad.a.u.net->dport = port; + if (act == SMK_RECEIVING) +- ad.a.u.net->v6info.saddr = addr6->sin6_addr; ++ ad.a.u.net->v6info.saddr = address->sin6_addr; + else +- ad.a.u.net->v6info.daddr = addr6->sin6_addr; ++ ad.a.u.net->v6info.daddr = address->sin6_addr; + #endif + return smk_access(skp, object, MAY_WRITE, &ad); + } +@@ -2198,7 +2196,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, + case PF_INET6: + if (addrlen < sizeof(struct sockaddr_in6)) + return -EINVAL; +- rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING); ++ rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, ++ SMK_CONNECTING); + break; + } + return rc; +@@ -3031,7 +3030,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + int size) + { + struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; +- struct sockaddr *sap = (struct sockaddr *) msg->msg_name; ++ struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; + int rc = 0; + + /* +@@ -3136,9 +3135,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + return smack_net_ambient; + } + +-static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap) ++static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) + { +- struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap; + u8 nexthdr; + int offset; + int proto = -EINVAL; +@@ -3196,7 +3194,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = sk->sk_security; + struct smack_known *skp; +- struct sockaddr sadd; ++ struct sockaddr_in6 sadd; + int rc = 0; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch new file mode 100644 index 0000000..b11e14e --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch @@ -0,0 +1,252 @@ +From af18e4fa19be1e914781acd5a9e3ad4ee62b4fac Mon Sep 17 00:00:00 2001 +From: Rafal Krypa +Date: Fri, 9 Aug 2013 11:47:07 +0200 +Subject: [PATCH 12/54] Smack: parse multiple rules per write to load2, up to + PAGE_SIZE-1 bytes + +Smack interface for loading rules has always parsed only single rule from +data written to it. This requires user program to call one write() per +each rule it wants to load. +This change makes it possible to write multiple rules, separated by new +line character. Smack will load at most PAGE_SIZE-1 characters and properly +return number of processed bytes. In case when user buffer is larger, it +will be additionally truncated. All characters after last \n will not get +parsed to avoid partial rule near input buffer boundary. + +Signed-off-by: Rafal Krypa +--- + security/smack/smackfs.c | 167 +++++++++++++++++++++++------------------------ + 1 file changed, 82 insertions(+), 85 deletions(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index a07e93f..80f4b4a 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -368,56 +368,43 @@ static int smk_parse_rule(const char *data, struct smack_parsed_rule *rule, + * @data: string to be parsed, null terminated + * @rule: Will be filled with Smack parsed rule + * @import: if non-zero, import labels +- * @change: if non-zero, data is from /smack/change-rule ++ * @tokens: numer of substrings expected in data + * +- * Returns 0 on success, -1 on failure ++ * Returns number of processed bytes on success, -1 on failure. + */ +-static int smk_parse_long_rule(const char *data, struct smack_parsed_rule *rule, +- int import, int change) ++static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, ++ int import, int tokens) + { +- char *subject; +- char *object; +- char *access1; +- char *access2; +- int datalen; +- int rc = -1; ++ ssize_t cnt = 0; ++ char *tok[4]; ++ int i; + +- /* This is inefficient */ +- datalen = strlen(data); ++ /* ++ * Parsing the rule in-place, filling all white-spaces with '\0' ++ */ ++ for (i = 0; i < tokens; ++i) { ++ while (isspace(data[cnt])) ++ data[cnt++] = '\0'; + +- /* Our first element can be 64 + \0 with no spaces */ +- subject = kzalloc(datalen + 1, GFP_KERNEL); +- if (subject == NULL) +- return -1; +- object = kzalloc(datalen, GFP_KERNEL); +- if (object == NULL) +- goto free_out_s; +- access1 = kzalloc(datalen, GFP_KERNEL); +- if (access1 == NULL) +- goto free_out_o; +- access2 = kzalloc(datalen, GFP_KERNEL); +- if (access2 == NULL) +- goto free_out_a; +- +- if (change) { +- if (sscanf(data, "%s %s %s %s", +- subject, object, access1, access2) == 4) +- rc = smk_fill_rule(subject, object, access1, access2, +- rule, import, 0); +- } else { +- if (sscanf(data, "%s %s %s", subject, object, access1) == 3) +- rc = smk_fill_rule(subject, object, access1, NULL, +- rule, import, 0); ++ if (data[cnt] == '\0') ++ /* Unexpected end of data */ ++ return -1; ++ ++ tok[i] = data + cnt; ++ ++ while (data[cnt] && !isspace(data[cnt])) ++ ++cnt; + } ++ while (isspace(data[cnt])) ++ data[cnt++] = '\0'; + +- kfree(access2); +-free_out_a: +- kfree(access1); +-free_out_o: +- kfree(object); +-free_out_s: +- kfree(subject); +- return rc; ++ while (i < 4) ++ tok[i++] = NULL; ++ ++ if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) ++ return -1; ++ ++ return cnt; + } + + #define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ +@@ -449,9 +436,10 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + { + struct smack_parsed_rule rule; + char *data; +- int datalen; +- int rc = -EINVAL; +- int load = 0; ++ int rc; ++ int trunc = 0; ++ int tokens; ++ ssize_t cnt = 0; + + /* + * No partial writes. +@@ -466,11 +454,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + */ + if (count != SMK_OLOADLEN && count != SMK_LOADLEN) + return -EINVAL; +- datalen = SMK_LOADLEN; +- } else +- datalen = count + 1; ++ } else { ++ if (count >= PAGE_SIZE) { ++ count = PAGE_SIZE - 1; ++ trunc = 1; ++ } ++ } + +- data = kzalloc(datalen, GFP_KERNEL); ++ data = kmalloc(count + 1, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + +@@ -479,36 +470,49 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + goto out; + } + +- if (format == SMK_LONG_FMT) { +- /* +- * Be sure the data string is terminated. +- */ +- data[count] = '\0'; +- if (smk_parse_long_rule(data, &rule, 1, 0)) +- goto out; +- } else if (format == SMK_CHANGE_FMT) { +- data[count] = '\0'; +- if (smk_parse_long_rule(data, &rule, 1, 1)) +- goto out; +- } else { +- /* +- * More on the minor hack for backward compatibility +- */ +- if (count == (SMK_OLOADLEN)) +- data[SMK_OLOADLEN] = '-'; +- if (smk_parse_rule(data, &rule, 1)) ++ /* ++ * In case of parsing only part of user buf, ++ * avoid having partial rule at the data buffer ++ */ ++ if (trunc) { ++ while (count > 0 && (data[count - 1] != '\n')) ++ --count; ++ if (count == 0) { ++ rc = -EINVAL; + goto out; ++ } + } + +- if (rule_list == NULL) { +- load = 1; +- rule_list = &rule.smk_subject->smk_rules; +- rule_lock = &rule.smk_subject->smk_rules_lock; ++ data[count] = '\0'; ++ tokens = (format == SMK_CHANGE_FMT ? 4 : 3); ++ while (cnt < count) { ++ if (format == SMK_FIXED24_FMT) { ++ rc = smk_parse_rule(data, &rule, 1); ++ if (rc != 0) { ++ rc = -EINVAL; ++ goto out; ++ } ++ cnt = count; ++ } else { ++ rc = smk_parse_long_rule(data + cnt, &rule, 1, tokens); ++ if (rc <= 0) { ++ rc = -EINVAL; ++ goto out; ++ } ++ cnt += rc; ++ } ++ ++ if (rule_list == NULL) ++ rc = smk_set_access(&rule, &rule.smk_subject->smk_rules, ++ &rule.smk_subject->smk_rules_lock, 1); ++ else ++ rc = smk_set_access(&rule, rule_list, rule_lock, 0); ++ ++ if (rc) ++ goto out; + } + +- rc = smk_set_access(&rule, rule_list, rule_lock, load); +- if (rc == 0) +- rc = count; ++ rc = cnt; + out: + kfree(data); + return rc; +@@ -1829,7 +1833,6 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, + { + struct smack_parsed_rule rule; + char *data; +- char *cod; + int res; + + data = simple_transaction_get(file, buf, count); +@@ -1842,18 +1845,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, + res = smk_parse_rule(data, &rule, 0); + } else { + /* +- * Copy the data to make sure the string is terminated. ++ * simple_transaction_get() returns null-terminated data + */ +- cod = kzalloc(count + 1, GFP_KERNEL); +- if (cod == NULL) +- return -ENOMEM; +- memcpy(cod, data, count); +- cod[count] = '\0'; +- res = smk_parse_long_rule(cod, &rule, 0, 0); +- kfree(cod); ++ res = smk_parse_long_rule(data, &rule, 0, 3); + } + +- if (res) ++ if (res < 0) + return -EINVAL; + + res = smk_access(rule.smk_subject, rule.smk_object, +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0013-Smack-Implement-lock-security-mode.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0013-Smack-Implement-lock-security-mode.patch new file mode 100644 index 0000000..065734d --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0013-Smack-Implement-lock-security-mode.patch @@ -0,0 +1,189 @@ +From a62902f65798858d0f8b7549ba70304ee047b2d6 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Fri, 11 Oct 2013 18:06:39 -0700 +Subject: [PATCH 13/54] Smack: Implement lock security mode + +Linux file locking does not follow the same rules +as other mechanisms. Even though it is a write operation +a process can set a read lock on files which it has open +only for read access. Two programs with read access to +a file can use read locks to communicate. + +This is not acceptable in a Mandatory Access Control +environment. Smack treats setting a read lock as the +write operation that it is. Unfortunately, many programs +assume that setting a read lock is a read operation. +These programs are unhappy in the Smack environment. + +This patch introduces a new access mode (lock) to address +this problem. A process with lock access to a file can +set a read lock. A process with write access to a file can +set a read lock or a write lock. This prevents a situation +where processes are granted write access just so they can +set read locks. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 12 ++++++++---- + security/smack/smack_access.c | 10 ++++++++++ + security/smack/smack_lsm.c | 9 +++++++-- + security/smack/smackfs.c | 10 ++++++++-- + 4 files changed, 33 insertions(+), 8 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 076b8e8..364cc64 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -177,9 +177,13 @@ struct smk_port_label { + #define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ + + /* +- * Flag for transmute access ++ * Flags for untraditional access modes. ++ * It shouldn't be necessary to avoid conflicts with definitions ++ * in fs.h, but do so anyway. + */ +-#define MAY_TRANSMUTE 64 ++#define MAY_TRANSMUTE 0x00001000 /* Controls directory labeling */ ++#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */ ++ + /* + * Just to make the common cases easier to deal with + */ +@@ -188,9 +192,9 @@ struct smk_port_label { + #define MAY_NOT 0 + + /* +- * Number of access types used by Smack (rwxat) ++ * Number of access types used by Smack (rwxatl) + */ +-#define SMK_NUM_ACCESS_TYPE 5 ++#define SMK_NUM_ACCESS_TYPE 6 + + /* SMACK data */ + struct smack_audit_data { +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index b3b59b1..14293cd 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -84,6 +84,8 @@ int log_policy = SMACK_AUDIT_DENIED; + * + * Do the object check first because that is more + * likely to differ. ++ * ++ * Allowing write access implies allowing locking. + */ + int smk_access_entry(char *subject_label, char *object_label, + struct list_head *rule_list) +@@ -99,6 +101,11 @@ int smk_access_entry(char *subject_label, char *object_label, + } + } + ++ /* ++ * MAY_WRITE implies MAY_LOCK. ++ */ ++ if ((may & MAY_WRITE) == MAY_WRITE) ++ may |= MAY_LOCK; + return may; + } + +@@ -245,6 +252,7 @@ out_audit: + static inline void smack_str_from_perm(char *string, int access) + { + int i = 0; ++ + if (access & MAY_READ) + string[i++] = 'r'; + if (access & MAY_WRITE) +@@ -255,6 +263,8 @@ static inline void smack_str_from_perm(char *string, int access) + string[i++] = 'a'; + if (access & MAY_TRANSMUTE) + string[i++] = 't'; ++ if (access & MAY_LOCK) ++ string[i++] = 'l'; + string[i] = '\0'; + } + /** +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 8825375..88d366e5 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1146,7 +1146,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, + * @file: the object + * @cmd: unused + * +- * Returns 0 if current has write access, error code otherwise ++ * Returns 0 if current has lock access, error code otherwise + */ + static int smack_file_lock(struct file *file, unsigned int cmd) + { +@@ -1154,7 +1154,7 @@ static int smack_file_lock(struct file *file, unsigned int cmd) + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- return smk_curacc(file->f_security, MAY_WRITE, &ad); ++ return smk_curacc(file->f_security, MAY_LOCK, &ad); + } + + /** +@@ -1178,8 +1178,13 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, + + switch (cmd) { + case F_GETLK: ++ break; + case F_SETLK: + case F_SETLKW: ++ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); ++ smk_ad_setfield_u_fs_path(&ad, file->f_path); ++ rc = smk_curacc(file->f_security, MAY_LOCK, &ad); ++ break; + case F_SETOWN: + case F_SETSIG: + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 80f4b4a..160aa08e 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -139,7 +139,7 @@ const char *smack_cipso_option = SMACK_CIPSO_OPTION; + * SMK_LOADLEN: Smack rule length + */ + #define SMK_OACCESS "rwxa" +-#define SMK_ACCESS "rwxat" ++#define SMK_ACCESS "rwxatl" + #define SMK_OACCESSLEN (sizeof(SMK_OACCESS) - 1) + #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) + #define SMK_OLOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN) +@@ -282,6 +282,10 @@ static int smk_perm_from_str(const char *string) + case 'T': + perm |= MAY_TRANSMUTE; + break; ++ case 'l': ++ case 'L': ++ perm |= MAY_LOCK; ++ break; + default: + return perm; + } +@@ -452,7 +456,7 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, + /* + * Minor hack for backward compatibility + */ +- if (count != SMK_OLOADLEN && count != SMK_LOADLEN) ++ if (count < SMK_OLOADLEN || count > SMK_LOADLEN) + return -EINVAL; + } else { + if (count >= PAGE_SIZE) { +@@ -592,6 +596,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) + seq_putc(s, 'a'); + if (srp->smk_access & MAY_TRANSMUTE) + seq_putc(s, 't'); ++ if (srp->smk_access & MAY_LOCK) ++ seq_putc(s, 'l'); + + seq_putc(s, '\n'); + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0014-Smack-Ptrace-access-check-mode.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0014-Smack-Ptrace-access-check-mode.patch new file mode 100644 index 0000000..3a7e8e2 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0014-Smack-Ptrace-access-check-mode.patch @@ -0,0 +1,34 @@ +From 1efeb1c2415e7b5b5ce3ae0233d6c522f9e89d2d Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Tue, 22 Oct 2013 11:47:45 -0700 +Subject: [PATCH 14/54] Smack: Ptrace access check mode + +When the ptrace security hooks were split the addition of +a mode parameter was not taken advantage of in the Smack +ptrace access check. This changes the access check from +always looking for read and write access to using the +passed mode. This will make use of /proc much happier. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 88d366e5..b0be893 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -185,7 +185,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ctp); + +- rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); ++ rc = smk_curacc(skp->smk_known, mode, &ad); + return rc; + } + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch new file mode 100644 index 0000000..bb01395 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch @@ -0,0 +1,107 @@ +From ba7db93834a82cc1e8a1a91af549d7d40bd8d764 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Thu, 28 Nov 2013 19:16:46 +0200 +Subject: [PATCH 15/54] smack: fix: allow either entry be missing on + access/access2 check (v2) + +This is a regression caused by f7112e6c. When either subject or +object is not found the answer for access should be no. This +patch fixes the situation. '0' is written back instead of failing +with -EINVAL. + +v2: cosmetic style fixes + +Signed-off-by: Jarkko Sakkinen +--- + security/smack/smackfs.c | 29 +++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 160aa08e..1c89ade 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -301,7 +301,8 @@ static int smk_perm_from_str(const char *string) + * @import: if non-zero, import labels + * @len: label length limit + * +- * Returns 0 on success, -1 on failure ++ * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject ++ * or object is missing. + */ + static int smk_fill_rule(const char *subject, const char *object, + const char *access1, const char *access2, +@@ -314,28 +315,28 @@ static int smk_fill_rule(const char *subject, const char *object, + if (import) { + rule->smk_subject = smk_import_entry(subject, len); + if (rule->smk_subject == NULL) +- return -1; ++ return -EINVAL; + + rule->smk_object = smk_import(object, len); + if (rule->smk_object == NULL) +- return -1; ++ return -EINVAL; + } else { + cp = smk_parse_smack(subject, len); + if (cp == NULL) +- return -1; ++ return -EINVAL; + skp = smk_find_entry(cp); + kfree(cp); + if (skp == NULL) +- return -1; ++ return -ENOENT; + rule->smk_subject = skp; + + cp = smk_parse_smack(object, len); + if (cp == NULL) +- return -1; ++ return -EINVAL; + skp = smk_find_entry(cp); + kfree(cp); + if (skp == NULL) +- return -1; ++ return -ENOENT; + rule->smk_object = skp->smk_known; + } + +@@ -381,6 +382,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, + { + ssize_t cnt = 0; + char *tok[4]; ++ int rc; + int i; + + /* +@@ -405,10 +407,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, + while (i < 4) + tok[i++] = NULL; + +- if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) +- return -1; +- +- return cnt; ++ rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0); ++ return rc == 0 ? cnt : rc; + } + + #define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ +@@ -1856,11 +1856,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, + res = smk_parse_long_rule(data, &rule, 0, 3); + } + +- if (res < 0) ++ if (res >= 0) ++ res = smk_access(rule.smk_subject, rule.smk_object, ++ rule.smk_access1, NULL); ++ else if (res != -ENOENT) + return -EINVAL; + +- res = smk_access(rule.smk_subject, rule.smk_object, +- rule.smk_access1, NULL); + data[0] = res == 0 ? '1' : '0'; + data[1] = '\0'; + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch new file mode 100644 index 0000000..43e9fc7 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch @@ -0,0 +1,104 @@ +From 7e4d45e539473706108e6b77dd9c7a6d70a40ffb Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 16 Dec 2013 16:27:26 -0800 +Subject: [PATCH 16/54] Smack: Prevent the * and @ labels from being used in + SMACK64EXEC + +Smack prohibits processes from using the star ("*") and web ("@") labels +because we don't want files with those labels getting created implicitly. +All setting of those labels should be done explicitly. The trouble is that +there is no check for these labels in the processing of SMACK64EXEC. That +is repaired. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 53 ++++++++++++++++++++++++++++++++-------------- + 1 file changed, 37 insertions(+), 16 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b0be893..62ebf4f 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -837,31 +837,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) + { + struct smk_audit_info ad; ++ struct smack_known *skp; ++ int check_priv = 0; ++ int check_import = 0; ++ int check_star = 0; + int rc = 0; + ++ /* ++ * Check label validity here so import won't fail in post_setxattr ++ */ + if (strcmp(name, XATTR_NAME_SMACK) == 0 || + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || +- strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || +- strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { +- if (!smack_privileged(CAP_MAC_ADMIN)) +- rc = -EPERM; +- /* +- * check label validity here so import wont fail on +- * post_setxattr +- */ +- if (size == 0 || size >= SMK_LONGLABEL || +- smk_import(value, size) == NULL) +- rc = -EINVAL; ++ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { ++ check_priv = 1; ++ check_import = 1; ++ } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || ++ strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { ++ check_priv = 1; ++ check_import = 1; ++ check_star = 1; + } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { +- if (!smack_privileged(CAP_MAC_ADMIN)) +- rc = -EPERM; ++ check_priv = 1; + if (size != TRANS_TRUE_SIZE || + strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) + rc = -EINVAL; + } else + rc = cap_inode_setxattr(dentry, name, value, size, flags); + ++ if (check_priv && !smack_privileged(CAP_MAC_ADMIN)) ++ rc = -EPERM; ++ ++ if (rc == 0 && check_import) { ++ skp = smk_import_entry(value, size); ++ if (skp == NULL || (check_star && ++ (skp == &smack_known_star || skp == &smack_known_web))) ++ rc = -EINVAL; ++ } ++ + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + +@@ -2847,8 +2859,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + if (rc >= 0) + transflag = SMK_INODE_TRANSMUTE; + } +- isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); +- isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); ++ /* ++ * Don't let the exec or mmap label be "*" or "@". ++ */ ++ skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); ++ if (skp == &smack_known_star || skp == &smack_known_web) ++ skp = NULL; ++ isp->smk_task = skp; ++ skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); ++ if (skp == &smack_known_star || skp == &smack_known_web) ++ skp = NULL; ++ isp->smk_mmap = skp; + + dput(dp); + break; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0017-Smack-Make-the-syslog-control-configurable.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0017-Smack-Make-the-syslog-control-configurable.patch new file mode 100644 index 0000000..a1bb4bf --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0017-Smack-Make-the-syslog-control-configurable.patch @@ -0,0 +1,252 @@ +From c7928b67e3b2cd91da4cec3ae3bff33306efebe4 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 23 Dec 2013 11:07:10 -0800 +Subject: [PATCH 17/54] Smack: Make the syslog control configurable + +The syslog control requires that the calling proccess +have the floor ("_") Smack label. Tizen does not run any +processes except for kernel helpers with the floor label. +This changes allows the admin to configure a specific +label for syslog. The default value is the star ("*") +label, effectively removing the restriction. The value +can be set using smackfs/syslog for anyone who wants +a more restrictive behavior. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack.h | 5 ++- + security/smack/smack_lsm.c | 4 +- + security/smack/smackfs.c | 103 +++++++++++++++++++++++++++++++++++++++++---- + 3 files changed, 99 insertions(+), 13 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 364cc64..d072fd3 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *); + extern int smack_cipso_direct; + extern int smack_cipso_mapped; + extern struct smack_known *smack_net_ambient; +-extern char *smack_onlycap; ++extern struct smack_known *smack_onlycap; ++extern struct smack_known *smack_syslog_label; + extern const char *smack_cipso_option; + + extern struct smack_known smack_known_floor; +@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap) + + if (!capable(cap)) + return 0; +- if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) ++ if (smack_onlycap == NULL || smack_onlycap == skp) + return 1; + return 0; + } +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 62ebf4f..67b7381d 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + * smack_syslog - Smack approval on syslog + * @type: message type + * +- * Require that the task has the floor label +- * + * Returns 0 on success, error code otherwise. + */ + static int smack_syslog(int typefrom_file) +@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file) + if (smack_privileged(CAP_MAC_OVERRIDE)) + return 0; + +- if (skp != &smack_known_floor) ++ if (smack_syslog_label != NULL && smack_syslog_label != skp) + rc = -EACCES; + + return rc; +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 1c89ade..f5a6bb8 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -52,6 +52,7 @@ enum smk_inos { + SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ + SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ + SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ ++ SMK_SYSLOG = 20, /* change syslog label) */ + }; + + /* +@@ -59,6 +60,7 @@ enum smk_inos { + */ + static DEFINE_MUTEX(smack_cipso_lock); + static DEFINE_MUTEX(smack_ambient_lock); ++static DEFINE_MUTEX(smack_syslog_lock); + static DEFINE_MUTEX(smk_netlbladdr_lock); + + /* +@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT; + * everyone. It is expected that the hat (^) label + * will be used if any label is used. + */ +-char *smack_onlycap; ++struct smack_known *smack_onlycap; ++ ++/* ++ * If this value is set restrict syslog use to the label specified. ++ * It can be reset via smackfs/syslog ++ */ ++struct smack_known *smack_syslog_label; + + /* + * Certain IP addresses may be designated as single label hosts. +@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = { + }; + + /** +- * smk_read_onlycap - read() for /smack/onlycap ++ * smk_read_onlycap - read() for smackfs/onlycap + * @filp: file pointer, not actually used + * @buf: where to put the result + * @cn: maximum to send along +@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, + return 0; + + if (smack_onlycap != NULL) +- smack = smack_onlycap; ++ smack = smack_onlycap->smk_known; + + asize = strlen(smack) + 1; + +@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, + } + + /** +- * smk_write_onlycap - write() for /smack/onlycap ++ * smk_write_onlycap - write() for smackfs/onlycap + * @file: file pointer, not actually used + * @buf: where to get the data from + * @count: bytes sent +@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, + * explicitly for clarity. The smk_access() implementation + * would use smk_access(smack_onlycap, MAY_WRITE) + */ +- if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) ++ if (smack_onlycap != NULL && smack_onlycap != skp) + return -EPERM; + + data = kzalloc(count, GFP_KERNEL); +@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, + if (copy_from_user(data, buf, count) != 0) + rc = -EFAULT; + else +- smack_onlycap = smk_import(data, count); ++ smack_onlycap = smk_import_entry(data, count); + + kfree(data); + return rc; +@@ -2159,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = { + }; + + /** +- * smk_fill_super - fill the /smackfs superblock ++ * smk_read_syslog - read() for smackfs/syslog ++ * @filp: file pointer, not actually used ++ * @buf: where to put the result ++ * @cn: maximum to send along ++ * @ppos: where to start ++ * ++ * Returns number of bytes read or error code, as appropriate ++ */ ++static ssize_t smk_read_syslog(struct file *filp, char __user *buf, ++ size_t cn, loff_t *ppos) ++{ ++ struct smack_known *skp; ++ ssize_t rc = -EINVAL; ++ int asize; ++ ++ if (*ppos != 0) ++ return 0; ++ ++ if (smack_syslog_label == NULL) ++ skp = &smack_known_star; ++ else ++ skp = smack_syslog_label; ++ ++ asize = strlen(skp->smk_known) + 1; ++ ++ if (cn >= asize) ++ rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known, ++ asize); ++ ++ return rc; ++} ++ ++/** ++ * smk_write_syslog - write() for smackfs/syslog ++ * @file: file pointer, not actually used ++ * @buf: where to get the data from ++ * @count: bytes sent ++ * @ppos: where to start ++ * ++ * Returns number of bytes written or error code, as appropriate ++ */ ++static ssize_t smk_write_syslog(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ char *data; ++ struct smack_known *skp; ++ int rc = count; ++ ++ if (!smack_privileged(CAP_MAC_ADMIN)) ++ return -EPERM; ++ ++ data = kzalloc(count, GFP_KERNEL); ++ if (data == NULL) ++ return -ENOMEM; ++ ++ if (copy_from_user(data, buf, count) != 0) ++ rc = -EFAULT; ++ else { ++ skp = smk_import_entry(data, count); ++ if (skp == NULL) ++ rc = -EINVAL; ++ else ++ smack_syslog_label = smk_import_entry(data, count); ++ } ++ ++ kfree(data); ++ return rc; ++} ++ ++static const struct file_operations smk_syslog_ops = { ++ .read = smk_read_syslog, ++ .write = smk_write_syslog, ++ .llseek = default_llseek, ++}; ++ ++ ++/** ++ * smk_fill_super - fill the smackfs superblock + * @sb: the empty superblock + * @data: unused + * @silent: unused + * +- * Fill in the well known entries for /smack ++ * Fill in the well known entries for the smack filesystem + * + * Returns 0 on success, an error code on failure + */ +@@ -2209,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) + S_IRUGO|S_IWUSR}, + [SMK_CHANGE_RULE] = { + "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, ++ [SMK_SYSLOG] = { ++ "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, + /* last one */ + {""} + }; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0018-Smack-change-rule-cap-check.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0018-Smack-change-rule-cap-check.patch new file mode 100644 index 0000000..1af9b40 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0018-Smack-change-rule-cap-check.patch @@ -0,0 +1,33 @@ +From 791a375032d5224c6ebb5937d5816cef2917874b Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Thu, 19 Dec 2013 13:23:26 -0800 +Subject: [PATCH 18/54] Smack: change rule cap check + +smk_write_change_rule() is calling capable rather than +the more correct smack_privileged(). This allows for setting +rules in violation of the onlycap facility. This is the +simple repair. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smackfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index f5a6bb8..3198cfe 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -2152,7 +2152,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf, + /* + * Must have privilege. + */ +- if (!capable(CAP_MAC_ADMIN)) ++ if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + + return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0019-Smack-Rationalize-mount-restrictions.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0019-Smack-Rationalize-mount-restrictions.patch new file mode 100644 index 0000000..ca3fabe --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0019-Smack-Rationalize-mount-restrictions.patch @@ -0,0 +1,185 @@ +From 4f315dddfeb6f5aadad30d85bf4374b4e05c6e43 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 30 Dec 2013 09:38:00 -0800 +Subject: [PATCH 19/54] Smack: Rationalize mount restrictions + +The mount restrictions imposed by Smack rely heavily on the +use of the filesystem "floor", which is the label that all +processes writing to the filesystem must have access to. It +turns out that while the "floor" notion is sound, it has yet +to be fully implemented and has never been used. + +The sb_mount and sb_umount hooks only make sense if the +filesystem floor is used actively, and it isn't. They can +be reintroduced if a rational restriction comes up. Until +then, they get removed. + +The sb_kern_mount hook is required for the option processing. +It is too permissive in the case of unprivileged mounts, +effectively bypassing the CAP_MAC_ADMIN restrictions if +any of the smack options are specified. Unprivileged mounts +are no longer allowed to set Smack filesystem options. +Additionally, the root and default values are set to the +label of the caller, in keeping with the policy that objects +get the label of their creator. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 83 ++++++++++++++++------------------------------ + 1 file changed, 29 insertions(+), 54 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 67b7381d..d552832 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -229,7 +229,7 @@ static int smack_syslog(int typefrom_file) + if (smack_privileged(CAP_MAC_OVERRIDE)) + return 0; + +- if (smack_syslog_label != NULL && smack_syslog_label != skp) ++ if (smack_syslog_label != NULL && smack_syslog_label != skp) + rc = -EACCES; + + return rc; +@@ -339,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + struct inode *inode = root->d_inode; + struct superblock_smack *sp = sb->s_security; + struct inode_smack *isp; ++ struct smack_known *skp; + char *op; + char *commap; + char *nsp; + int transmute = 0; ++ int specified = 0; + + if (sp->smk_initialized) + return 0; +@@ -357,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { + op += strlen(SMK_FSHAT); + nsp = smk_import(op, 0); +- if (nsp != NULL) ++ if (nsp != NULL) { + sp->smk_hat = nsp; ++ specified = 1; ++ } + } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { + op += strlen(SMK_FSFLOOR); + nsp = smk_import(op, 0); +- if (nsp != NULL) ++ if (nsp != NULL) { + sp->smk_floor = nsp; ++ specified = 1; ++ } + } else if (strncmp(op, SMK_FSDEFAULT, + strlen(SMK_FSDEFAULT)) == 0) { + op += strlen(SMK_FSDEFAULT); + nsp = smk_import(op, 0); +- if (nsp != NULL) ++ if (nsp != NULL) { + sp->smk_default = nsp; ++ specified = 1; ++ } + } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { + op += strlen(SMK_FSROOT); + nsp = smk_import(op, 0); +- if (nsp != NULL) ++ if (nsp != NULL) { + sp->smk_root = nsp; ++ specified = 1; ++ } + } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { + op += strlen(SMK_FSTRANS); + nsp = smk_import(op, 0); + if (nsp != NULL) { + sp->smk_root = nsp; + transmute = 1; ++ specified = 1; + } + } + } + ++ if (!smack_privileged(CAP_MAC_ADMIN)) { ++ /* ++ * Unprivileged mounts don't get to specify Smack values. ++ */ ++ if (specified) ++ return -EPERM; ++ /* ++ * Unprivileged mounts get root and default from the caller. ++ */ ++ skp = smk_of_current(); ++ sp->smk_root = skp->smk_known; ++ sp->smk_default = skp->smk_known; ++ } + /* + * Initialize the root inode. + */ +@@ -421,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry) + return rc; + } + +-/** +- * smack_sb_mount - Smack check for mounting +- * @dev_name: unused +- * @path: mount point +- * @type: unused +- * @flags: unused +- * @data: unused +- * +- * Returns 0 if current can write the floor of the filesystem +- * being mounted on, an error code otherwise. +- */ +-static int smack_sb_mount(const char *dev_name, struct path *path, +- const char *type, unsigned long flags, void *data) +-{ +- struct superblock_smack *sbp = path->dentry->d_sb->s_security; +- struct smk_audit_info ad; +- +- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); +- smk_ad_setfield_u_fs_path(&ad, *path); +- +- return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); +-} +- +-/** +- * smack_sb_umount - Smack check for unmounting +- * @mnt: file system to unmount +- * @flags: unused +- * +- * Returns 0 if current can write the floor of the filesystem +- * being unmounted, an error code otherwise. +- */ +-static int smack_sb_umount(struct vfsmount *mnt, int flags) +-{ +- struct superblock_smack *sbp; +- struct smk_audit_info ad; +- struct path path; +- +- path.dentry = mnt->mnt_root; +- path.mnt = mnt; +- +- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); +- smk_ad_setfield_u_fs_path(&ad, path); +- +- sbp = path.dentry->d_sb->s_security; +- return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); +-} +- + /* + * BPRM hooks + */ +@@ -3762,8 +3739,6 @@ struct security_operations smack_ops = { + .sb_copy_data = smack_sb_copy_data, + .sb_kern_mount = smack_sb_kern_mount, + .sb_statfs = smack_sb_statfs, +- .sb_mount = smack_sb_mount, +- .sb_umount = smack_sb_umount, + + .bprm_set_creds = smack_bprm_set_creds, + .bprm_committing_creds = smack_bprm_committing_creds, +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0020-Smack-File-receive-audit-correction.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0020-Smack-File-receive-audit-correction.patch new file mode 100644 index 0000000..cb8a86f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0020-Smack-File-receive-audit-correction.patch @@ -0,0 +1,39 @@ +From bc7377d7cd27b9d17384e1486ac769a37cf8f745 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 30 Dec 2013 17:37:45 -0800 +Subject: [PATCH 20/54] Smack: File receive audit correction + +Eric Paris politely points out: + + Inside smack_file_receive() it seems like you are initting the audit + field with LSM_AUDIT_DATA_TASK. And then use + smk_ad_setfield_u_fs_path(). + + Seems like LSM_AUDIT_DATA_PATH would make more sense. (and depending + on how it's used fix a crash...) + +He is correct. This puts things in order. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d552832..d814e35 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1351,7 +1351,7 @@ static int smack_file_receive(struct file *file) + int may = 0; + struct smk_audit_info ad; + +- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); ++ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + /* + * This code relies on bitmasks. +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch new file mode 100644 index 0000000..bf8dd26 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch @@ -0,0 +1,36 @@ +From ea81dc20148025d25305582164e614754880606c Mon Sep 17 00:00:00 2001 +From: Richard Guy Briggs +Date: Thu, 21 Nov 2013 13:57:33 -0500 +Subject: [PATCH 21/54] smack: call WARN_ONCE() instead of calling + audit_log_start() + +Remove the call to audit_log() (which call audit_log_start()) and deal with +the errors in the caller, logging only once if the condition is met. Calling +audit_log_start() in this location makes buffer allocation and locking more +complicated in the calling tree (audit_filter_user()). + +Signed-off-by: Richard Guy Briggs +Signed-off-by: Eric Paris +--- + security/smack/smack_lsm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d814e35..14f52be 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3616,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, + struct smack_known *skp; + char *rule = vrule; + +- if (!rule) { +- audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, +- "Smack: missing rule\n"); ++ if (unlikely(!rule)) { ++ WARN_ONCE(1, "Smack: missing rule\n"); + return -ENOENT; + } + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-Smack-Cgroup-filesystem-access.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-Smack-Cgroup-filesystem-access.patch new file mode 100644 index 0000000..802c575 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-Smack-Cgroup-filesystem-access.patch @@ -0,0 +1,82 @@ +From f2b14844c3072a3f58ddd8096569e189afc308aa Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Thu, 21 Nov 2013 10:55:10 +0200 +Subject: [PATCH 22/39] Smack: Cgroup filesystem access + +The cgroup filesystems are not mounted using conventional +mechanisms. This prevents the use of mount options to +set Smack attributes. This patch makes the behavior +of cgroup filesystems compatable with the way systemd +uses them. + +Change-Id: I1e0429f133db9e14117dc754d682dec08221354c +Signed-off-by: Casey Schaufler +Signed-off-by: Artem Bityutskiy +Signed-off-by: Stephane Desneux +--- + security/smack/smack_lsm.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 14f52be..acd8574 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -2713,6 +2713,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * of the superblock. + */ + if (opt_dentry->d_parent == opt_dentry) { ++ if (sbp->s_magic == CGROUP_SUPER_MAGIC) { ++ /* ++ * The cgroup filesystem is never mounted, ++ * so there's no opportunity to set the mount ++ * options. ++ */ ++ sbsp->smk_root = smack_known_star.smk_known; ++ sbsp->smk_default = smack_known_star.smk_known; ++ } + isp->smk_inode = sbsp->smk_root; + isp->smk_flags |= SMK_INODE_INSTANT; + goto unlockandout; +@@ -2726,16 +2735,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + switch (sbp->s_magic) { + case SMACK_MAGIC: ++ case PIPEFS_MAGIC: ++ case SOCKFS_MAGIC: ++ case CGROUP_SUPER_MAGIC: + /* + * Casey says that it's a little embarrassing + * that the smack file system doesn't do + * extended attributes. +- */ +- final = smack_known_star.smk_known; +- break; +- case PIPEFS_MAGIC: +- /* ++ * + * Casey says pipes are easy (?) ++ * ++ * Socket access is controlled by the socket ++ * structures associated with the task involved. ++ * ++ * Cgroupfs is special + */ + final = smack_known_star.smk_known; + break; +@@ -2747,13 +2760,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + final = ckp->smk_known; + break; +- case SOCKFS_MAGIC: +- /* +- * Socket access is controlled by the socket +- * structures associated with the task involved. +- */ +- final = smack_known_star.smk_known; +- break; + case PROC_SUPER_MAGIC: + /* + * Casey says procfs appears not to care. +-- +1.9.1 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-smack-fix-key-permission-verification.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-smack-fix-key-permission-verification.patch new file mode 100644 index 0000000..b61c2ef --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0022-smack-fix-key-permission-verification.patch @@ -0,0 +1,55 @@ +From 618719c14729b2c9ef82cb462308671d11284a38 Mon Sep 17 00:00:00 2001 +From: Dmitry Kasatkin +Date: Fri, 14 Mar 2014 17:44:49 +0000 +Subject: [PATCH 22/54] smack: fix key permission verification + +For any keyring access type SMACK always used MAY_READWRITE access check. +It prevents reading the key with label "_", which should be allowed for anyone. + +This patch changes default access check to MAY_READ and use MAY_READWRITE in only +appropriate cases. + +Change-Id: I372968d614550d4c691301b2ef4b6478e76c62bf +Signed-off-by: Dmitry Kasatkin +Signed-off-by: David Howells +Acked-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 14f52be..16dcf7f 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3465,6 +3465,7 @@ static void smack_inet_csk_clone(struct sock *sk, + * If you care about keys please have a look. + */ + #ifdef CONFIG_KEYS ++#include "../keys/internal.h" /* HACK FOR THE BACKPORT */ + + /** + * smack_key_alloc - Set the key security blob +@@ -3511,6 +3512,7 @@ static int smack_key_permission(key_ref_t key_ref, + struct key *keyp; + struct smk_audit_info ad; + struct smack_known *tkp = smk_of_task(cred->security); ++ int request = 0; + + keyp = key_ref_to_ptr(key_ref); + if (keyp == NULL) +@@ -3531,7 +3533,11 @@ static int smack_key_permission(key_ref_t key_ref, + ad.a.u.key_struct.key = keyp->serial; + ad.a.u.key_struct.key_desc = keyp->description; + #endif +- return smk_access(tkp, keyp->security, MAY_READWRITE, &ad); ++ if (perm & KEY_READ) ++ request = MAY_READ; ++ if (perm & (KEY_WRITE | KEY_LINK | KEY_SETATTR)) ++ request = MAY_WRITE; ++ return smk_access(tkp, keyp->security, request, &ad); + } + #endif /* CONFIG_KEYS */ + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0023-Minor-improvement-of-smack_sb_kern_mount.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0023-Minor-improvement-of-smack_sb_kern_mount.patch new file mode 100644 index 0000000..1c5a46f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0023-Minor-improvement-of-smack_sb_kern_mount.patch @@ -0,0 +1,37 @@ +From c10dea6e10fc8607744d5b21b7ef7191d4b1a066 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Bollo?= +Date: Wed, 8 Jan 2014 15:53:05 +0100 +Subject: [PATCH 23/54] Minor improvement of 'smack_sb_kern_mount' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix a possible memory access fault when transmute is true and isp is NULL. + +Signed-off-by: José Bollo +--- + security/smack/smack_lsm.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 16dcf7f..b093463 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -413,9 +413,11 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + * Initialize the root inode. + */ + isp = inode->i_security; +- if (inode->i_security == NULL) { +- inode->i_security = new_inode_smack(sp->smk_root); +- isp = inode->i_security; ++ if (isp == NULL) { ++ isp = new_inode_smack(sp->smk_root); ++ if (isp == NULL) ++ return -ENOMEM; ++ inode->i_security = isp; + } else + isp->smk_inode = sp->smk_root; + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch new file mode 100644 index 0000000..a2fc123 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch @@ -0,0 +1,118 @@ +From bf371cf1c4093db6a7a9c201edb6ca0e4231055c Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Tue, 11 Mar 2014 17:07:04 +0100 +Subject: [PATCH 24/54] Smack: fix the subject/object order in + smack_ptrace_traceme() + +The order of subject/object is currently reversed in +smack_ptrace_traceme(). It is currently checked if the tracee has a +capability to trace tracer and according to this rule a decision is made +whether the tracer will be allowed to trace tracee. + +Signed-off-by: Lukasz Pawelczyk +Signed-off-by: Rafal Krypa +--- + security/smack/smack.h | 1 + + security/smack/smack_access.c | 33 ++++++++++++++++++++++++++------- + security/smack/smack_lsm.c | 4 ++-- + 3 files changed, 29 insertions(+), 9 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index d072fd3..b9dfc4e 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -225,6 +225,7 @@ struct inode_smack *new_inode_smack(char *); + */ + int smk_access_entry(char *, char *, struct list_head *); + int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); ++int smk_tskacc(struct task_smack *, char *, u32, struct smk_audit_info *); + int smk_curacc(char *, u32, struct smk_audit_info *); + struct smack_known *smack_from_secid(const u32); + char *smk_parse_smack(const char *string, int len); +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 14293cd..f161deb 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -192,20 +192,21 @@ out_audit: + } + + /** +- * smk_curacc - determine if current has a specific access to an object ++ * smk_tskacc - determine if a task has a specific access to an object ++ * @tsp: a pointer to the subject task + * @obj_label: a pointer to the object's Smack label + * @mode: the access requested, in "MAY" format + * @a : common audit data + * +- * This function checks the current subject label/object label pair ++ * This function checks the subject task's label/object label pair + * in the access rule list and returns 0 if the access is permitted, +- * non zero otherwise. It allows that current may have the capability ++ * non zero otherwise. It allows that the task may have the capability + * to override the rules. + */ +-int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) ++int smk_tskacc(struct task_smack *subject, char *obj_label, ++ u32 mode, struct smk_audit_info *a) + { +- struct task_smack *tsp = current_security(); +- struct smack_known *skp = smk_of_task(tsp); ++ struct smack_known *skp = smk_of_task(subject); + int may; + int rc; + +@@ -219,7 +220,7 @@ int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) + * it can further restrict access. + */ + may = smk_access_entry(skp->smk_known, obj_label, +- &tsp->smk_rules); ++ &subject->smk_rules); + if (may < 0) + goto out_audit; + if ((mode & may) == mode) +@@ -241,6 +242,24 @@ out_audit: + return rc; + } + ++/** ++ * smk_curacc - determine if current has a specific access to an object ++ * @obj_label: a pointer to the object's Smack label ++ * @mode: the access requested, in "MAY" format ++ * @a : common audit data ++ * ++ * This function checks the current subject label/object label pair ++ * in the access rule list and returns 0 if the access is permitted, ++ * non zero otherwise. It allows that current may have the capability ++ * to override the rules. ++ */ ++int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) ++{ ++ struct task_smack *tsp = current_security(); ++ ++ return smk_tskacc(tsp, obj_label, mode, a); ++} ++ + #ifdef CONFIG_AUDIT + /** + * smack_str_from_perm : helper to transalate an int to a +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b093463..0bea427 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -207,11 +207,11 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + if (rc != 0) + return rc; + +- skp = smk_of_task(task_security(ptp)); ++ skp = smk_of_task(current_security()); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ptp); + +- rc = smk_curacc(skp->smk_known, MAY_READWRITE, &ad); ++ rc = smk_tskacc(ptp, skp->smk_known, MAY_READWRITE, &ad); + return rc; + } + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch new file mode 100644 index 0000000..2619497 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch @@ -0,0 +1,185 @@ +From ff5f986cfb30bb75d4972b2b2e36fec368c13f1c Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Tue, 11 Mar 2014 17:07:05 +0100 +Subject: [PATCH 25/54] Smack: unify all ptrace accesses in the smack + +The decision whether we can trace a process is made in the following +functions: + smack_ptrace_traceme() + smack_ptrace_access_check() + smack_bprm_set_creds() (in case the proces is traced) + +This patch unifies all those decisions by introducing one function that +checks whether ptrace is allowed: smk_ptrace_rule_check(). + +This makes possible to actually trace with TRACEME where first the +TRACEME itself must be allowed and then exec() on a traced process. + +Additional bugs fixed: +- The decision is made according to the mode parameter that is now correctly + translated from PTRACE_MODE_* to MAY_* instead of being treated 1:1. + PTRACE_MODE_READ requires MAY_READ. + PTRACE_MODE_ATTACH requires MAY_READWRITE. +- Add a smack audit log in case of exec() refused by bprm_set_creds(). +- Honor the PTRACE_MODE_NOAUDIT flag and don't put smack audit info + in case this flag is set. + +Signed-off-by: Lukasz Pawelczyk +Signed-off-by: Rafal Krypa +--- + security/smack/smack_lsm.c | 84 +++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 71 insertions(+), 13 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 0bea427..72438156 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -157,6 +157,54 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead, + return rc; + } + ++/** ++ * smk_ptrace_mode - helper function for converting PTRACE_MODE_* into MAY_* ++ * @mode - input mode in form of PTRACE_MODE_* ++ * ++ * Returns a converted MAY_* mode usable by smack rules ++ */ ++static inline unsigned int smk_ptrace_mode(unsigned int mode) ++{ ++ switch (mode) { ++ case PTRACE_MODE_READ: ++ return MAY_READ; ++ case PTRACE_MODE_ATTACH: ++ return MAY_READWRITE; ++ } ++ ++ return 0; ++} ++ ++/** ++ * smk_ptrace_rule_check - helper for ptrace access ++ * @tracer: tracer process ++ * @tracee_label: label of the process that's about to be traced ++ * @mode: ptrace attachment mode (PTRACE_MODE_*) ++ * @func: name of the function that called us, used for audit ++ * ++ * Returns 0 on access granted, -error on error ++ */ ++static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, ++ unsigned int mode, const char *func) ++{ ++ int rc; ++ struct smk_audit_info ad, *saip = NULL; ++ struct task_smack *tsp; ++ struct smack_known *skp; ++ ++ if ((mode & PTRACE_MODE_NOAUDIT) == 0) { ++ smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK); ++ smk_ad_setfield_u_tsk(&ad, tracer); ++ saip = &ad; ++ } ++ ++ tsp = task_security(tracer); ++ skp = smk_of_task(tsp); ++ ++ rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); ++ return rc; ++} ++ + /* + * LSM hooks. + * We he, that is fun! +@@ -165,16 +213,15 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead, + /** + * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH + * @ctp: child task pointer +- * @mode: ptrace attachment mode ++ * @mode: ptrace attachment mode (PTRACE_MODE_*) + * + * Returns 0 if access is OK, an error code otherwise + * +- * Do the capability checks, and require read and write. ++ * Do the capability checks. + */ + static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + { + int rc; +- struct smk_audit_info ad; + struct smack_known *skp; + + rc = cap_ptrace_access_check(ctp, mode); +@@ -182,10 +229,8 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + return rc; + + skp = smk_of_task(task_security(ctp)); +- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); +- smk_ad_setfield_u_tsk(&ad, ctp); + +- rc = smk_curacc(skp->smk_known, mode, &ad); ++ rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__); + return rc; + } + +@@ -195,12 +240,11 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + * + * Returns 0 if access is OK, an error code otherwise + * +- * Do the capability checks, and require read and write. ++ * Do the capability checks, and require PTRACE_MODE_ATTACH. + */ + static int smack_ptrace_traceme(struct task_struct *ptp) + { + int rc; +- struct smk_audit_info ad; + struct smack_known *skp; + + rc = cap_ptrace_traceme(ptp); +@@ -208,10 +252,9 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + return rc; + + skp = smk_of_task(current_security()); +- smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); +- smk_ad_setfield_u_tsk(&ad, ptp); + +- rc = smk_tskacc(ptp, skp->smk_known, MAY_READWRITE, &ad); ++ rc = smk_ptrace_rule_check(ptp, skp->smk_known, ++ PTRACE_MODE_ATTACH, __func__); + return rc; + } + +@@ -455,7 +498,7 @@ static int smack_sb_statfs(struct dentry *dentry) + * smack_bprm_set_creds - set creds for exec + * @bprm: the exec information + * +- * Returns 0 if it gets a blob, -ENOMEM otherwise ++ * Returns 0 if it gets a blob, -EPERM if exec forbidden and -ENOMEM otherwise + */ + static int smack_bprm_set_creds(struct linux_binprm *bprm) + { +@@ -475,7 +518,22 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) + if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) + return 0; + +- if (bprm->unsafe) ++ if (bprm->unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { ++ struct task_struct *tracer; ++ rc = 0; ++ ++ rcu_read_lock(); ++ tracer = ptrace_parent(current); ++ if (likely(tracer != NULL)) ++ rc = smk_ptrace_rule_check(tracer, ++ isp->smk_task->smk_known, ++ PTRACE_MODE_ATTACH, ++ __func__); ++ rcu_read_unlock(); ++ ++ if (rc != 0) ++ return rc; ++ } else if (bprm->unsafe) + return -EPERM; + + bsp->smk_task = isp->smk_task; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0026-Smack-adds-smackfs-ptrace-interface.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0026-Smack-adds-smackfs-ptrace-interface.patch new file mode 100644 index 0000000..0efd7db --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0026-Smack-adds-smackfs-ptrace-interface.patch @@ -0,0 +1,233 @@ +From 9cb98c12dbf89a36970b0ee9c4b61c98ccd61d76 Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Tue, 11 Mar 2014 17:07:06 +0100 +Subject: [PATCH 26/54] Smack: adds smackfs/ptrace interface + +This allows to limit ptrace beyond the regular smack access rules. +It adds a smackfs/ptrace interface that allows smack to be configured +to require equal smack labels for PTRACE_MODE_ATTACH access. +See the changes in Documentation/security/Smack.txt below for details. + +Signed-off-by: Lukasz Pawelczyk +Signed-off-by: Rafal Krypa +--- + Documentation/security/Smack.txt | 10 ++++++ + security/smack/smack.h | 9 +++++ + security/smack/smack_access.c | 5 ++- + security/smack/smack_lsm.c | 22 +++++++++++- + security/smack/smackfs.c | 74 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 118 insertions(+), 2 deletions(-) + +diff --git a/Documentation/security/Smack.txt b/Documentation/security/Smack.txt +index 7a2d30c..5597917 100644 +--- a/Documentation/security/Smack.txt ++++ b/Documentation/security/Smack.txt +@@ -204,6 +204,16 @@ onlycap + these capabilities are effective at for processes with any + label. The value is set by writing the desired label to the + file or cleared by writing "-" to the file. ++ptrace ++ This is used to define the current ptrace policy ++ 0 - default: this is the policy that relies on smack access rules. ++ For the PTRACE_READ a subject needs to have a read access on ++ object. For the PTRACE_ATTACH a read-write access is required. ++ 1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is ++ only allowed when subject's and object's labels are equal. ++ PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE. ++ 2 - draconian: this policy behaves like the 'exact' above with an ++ exception that it can't be overriden with CAP_SYS_PTRACE. + revoke-subject + Writing a Smack label here sets the access to '-' for all access + rules with that subject label. +diff --git a/security/smack/smack.h b/security/smack/smack.h +index b9dfc4e..fade085 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -177,6 +177,14 @@ struct smk_port_label { + #define SMACK_CIPSO_MAXCATNUM 184 /* 23 * 8 */ + + /* ++ * Ptrace rules ++ */ ++#define SMACK_PTRACE_DEFAULT 0 ++#define SMACK_PTRACE_EXACT 1 ++#define SMACK_PTRACE_DRACONIAN 2 ++#define SMACK_PTRACE_MAX SMACK_PTRACE_DRACONIAN ++ ++/* + * Flags for untraditional access modes. + * It shouldn't be necessary to avoid conflicts with definitions + * in fs.h, but do so anyway. +@@ -245,6 +253,7 @@ extern struct smack_known *smack_net_ambient; + extern struct smack_known *smack_onlycap; + extern struct smack_known *smack_syslog_label; + extern const char *smack_cipso_option; ++extern int smack_ptrace_rule; + + extern struct smack_known smack_known_floor; + extern struct smack_known smack_known_hat; +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index f161deb..c062e94 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -304,7 +304,10 @@ static void smack_log_callback(struct audit_buffer *ab, void *a) + audit_log_untrustedstring(ab, sad->subject); + audit_log_format(ab, " object="); + audit_log_untrustedstring(ab, sad->object); +- audit_log_format(ab, " requested=%s", sad->request); ++ if (sad->request[0] == '\0') ++ audit_log_format(ab, " labels_differ"); ++ else ++ audit_log_format(ab, " requested=%s", sad->request); + } + + /** +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 72438156..91a447a 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -178,7 +178,8 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode) + /** + * smk_ptrace_rule_check - helper for ptrace access + * @tracer: tracer process +- * @tracee_label: label of the process that's about to be traced ++ * @tracee_label: label of the process that's about to be traced, ++ * the pointer must originate from smack structures + * @mode: ptrace attachment mode (PTRACE_MODE_*) + * @func: name of the function that called us, used for audit + * +@@ -201,6 +202,25 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, + tsp = task_security(tracer); + skp = smk_of_task(tsp); + ++ if ((mode & PTRACE_MODE_ATTACH) && ++ (smack_ptrace_rule == SMACK_PTRACE_EXACT || ++ smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) { ++ if (skp->smk_known == tracee_label) ++ rc = 0; ++ else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN) ++ rc = -EACCES; ++ else if (capable(CAP_SYS_PTRACE)) ++ rc = 0; ++ else ++ rc = -EACCES; ++ ++ if (saip) ++ smack_log(skp->smk_known, tracee_label, 0, rc, saip); ++ ++ return rc; ++ } ++ ++ /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ + rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); + return rc; + } +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 3198cfe..177d878 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -53,6 +53,7 @@ enum smk_inos { + SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ + SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ + SMK_SYSLOG = 20, /* change syslog label) */ ++ SMK_PTRACE = 21, /* set ptrace rule */ + }; + + /* +@@ -101,6 +102,15 @@ struct smack_known *smack_onlycap; + struct smack_known *smack_syslog_label; + + /* ++ * Ptrace current rule ++ * SMACK_PTRACE_DEFAULT regular smack ptrace rules (/proc based) ++ * SMACK_PTRACE_EXACT labels must match, but can be overriden with ++ * CAP_SYS_PTRACE ++ * SMACK_PTRACE_DRACONIAN lables must match, CAP_SYS_PTRACE has no effect ++ */ ++int smack_ptrace_rule = SMACK_PTRACE_DEFAULT; ++ ++/* + * Certain IP addresses may be designated as single label hosts. + * Packets are sent there unlabeled, but only from tasks that + * can write to the specified label. +@@ -2244,6 +2254,68 @@ static const struct file_operations smk_syslog_ops = { + + + /** ++ * smk_read_ptrace - read() for /smack/ptrace ++ * @filp: file pointer, not actually used ++ * @buf: where to put the result ++ * @count: maximum to send along ++ * @ppos: where to start ++ * ++ * Returns number of bytes read or error code, as appropriate ++ */ ++static ssize_t smk_read_ptrace(struct file *filp, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ char temp[32]; ++ ssize_t rc; ++ ++ if (*ppos != 0) ++ return 0; ++ ++ sprintf(temp, "%d\n", smack_ptrace_rule); ++ rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); ++ return rc; ++} ++ ++/** ++ * smk_write_ptrace - write() for /smack/ptrace ++ * @file: file pointer ++ * @buf: data from user space ++ * @count: bytes sent ++ * @ppos: where to start - must be 0 ++ */ ++static ssize_t smk_write_ptrace(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ char temp[32]; ++ int i; ++ ++ if (!smack_privileged(CAP_MAC_ADMIN)) ++ return -EPERM; ++ ++ if (*ppos != 0 || count >= sizeof(temp) || count == 0) ++ return -EINVAL; ++ ++ if (copy_from_user(temp, buf, count) != 0) ++ return -EFAULT; ++ ++ temp[count] = '\0'; ++ ++ if (sscanf(temp, "%d", &i) != 1) ++ return -EINVAL; ++ if (i < SMACK_PTRACE_DEFAULT || i > SMACK_PTRACE_MAX) ++ return -EINVAL; ++ smack_ptrace_rule = i; ++ ++ return count; ++} ++ ++static const struct file_operations smk_ptrace_ops = { ++ .write = smk_write_ptrace, ++ .read = smk_read_ptrace, ++ .llseek = default_llseek, ++}; ++ ++/** + * smk_fill_super - fill the smackfs superblock + * @sb: the empty superblock + * @data: unused +@@ -2296,6 +2368,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) + "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, + [SMK_SYSLOG] = { + "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, ++ [SMK_PTRACE] = { ++ "ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR}, + /* last one */ + {""} + }; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0027-bugfix-patch-for-SMACK.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0027-bugfix-patch-for-SMACK.patch new file mode 100644 index 0000000..5f78abf --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0027-bugfix-patch-for-SMACK.patch @@ -0,0 +1,43 @@ +From 20a88e69ded71ba364c477c824c8173efeab873f Mon Sep 17 00:00:00 2001 +From: Pankaj Kumar +Date: Fri, 13 Dec 2013 15:12:22 +0530 +Subject: [PATCH 27/54] bugfix patch for SMACK + +1. In order to remove any SMACK extended attribute from a file, a user +should have CAP_MAC_ADMIN capability. But user without having this +capability is able to remove SMACK64MMAP security attribute. + +2. While validating size and value of smack extended attribute in +smack_inode_setsecurity hook, wrong error code is returned. + +Signed-off-by: Pankaj Kumar +Signed-off-by: Himanshu Shukla +--- + security/smack/smack_lsm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 91a447a..b47fd5f 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1018,7 +1018,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || + strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || + strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0 || +- strcmp(name, XATTR_NAME_SMACKMMAP)) { ++ strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { + if (!smack_privileged(CAP_MAC_ADMIN)) + rc = -EPERM; + } else +@@ -2156,7 +2156,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + int rc = 0; + + if (value == NULL || size > SMK_LONGLABEL || size == 0) +- return -EACCES; ++ return -EINVAL; + + skp = smk_import_entry(value, size); + if (skp == NULL) +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch new file mode 100644 index 0000000..1ad5727 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch @@ -0,0 +1,64 @@ +From c6b962ba0e84d84cb8434aae62108b537de04c2c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jos=C3=A9=20Bollo?= +Date: Thu, 3 Apr 2014 13:48:41 +0200 +Subject: [PATCH 28/54] SMACK: Fix handling value==NULL in post setxattr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function `smack_inode_post_setxattr` is called each +time that a setxattr is done, for any value of name. +The kernel allow to put value==NULL when size==0 +to set an empty attribute value. The systematic +call to smk_import_entry was causing the dereference +of a NULL pointer hence a KERNEL PANIC! + +The problem can be produced easily by issuing the +command `setfattr -n user.data file` under bash prompt +when SMACK is active. + +Moving the call to smk_import_entry as proposed by this +patch is correcting the behaviour because the function +smack_inode_post_setxattr is called for the SMACK's +attributes only if the function smack_inode_setxattr validated +the value and its size (what will not be the case when size==0). + +It also has a benefical effect to not fill the smack hash +with garbage values coming from any extended attribute +write. + +Change-Id: Iaf0039c2be9bccb6cee11c24a3b44d209101fe47 +Signed-off-by: José Bollo +--- + security/smack/smack_lsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b47fd5f..e6c0a57 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -960,18 +960,20 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, + return; + } + +- skp = smk_import_entry(value, size); + if (strcmp(name, XATTR_NAME_SMACK) == 0) { ++ skp = smk_import_entry(value, size); + if (skp != NULL) + isp->smk_inode = skp->smk_known; + else + isp->smk_inode = smack_known_invalid.smk_known; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { ++ skp = smk_import_entry(value, size); + if (skp != NULL) + isp->smk_task = skp; + else + isp->smk_task = &smack_known_invalid; + } else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { ++ skp = smk_import_entry(value, size); + if (skp != NULL) + isp->smk_mmap = skp; + else +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch new file mode 100644 index 0000000..b70522d --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch @@ -0,0 +1,64 @@ +From cb4e7f82cf806db0fb08aa83e6b3b4aa3918af60 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Thu, 10 Apr 2014 16:35:36 -0700 +Subject: [PATCH 29/54] Smack: Correctly remove SMACK64TRANSMUTE attribute + +Sam Henderson points out that removing the SMACK64TRANSMUTE +attribute from a directory does not result in the directory +transmuting. This is because the inode flag indicating that +the directory is transmuting isn't cleared. The fix is a tad +less than trivial because smk_task and smk_mmap should have +been broken out, too. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index e6c0a57..b259a0d 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1026,18 +1026,31 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) + } else + rc = cap_inode_removexattr(dentry, name); + ++ if (rc != 0) ++ return rc; ++ + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); +- if (rc == 0) +- rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + +- if (rc == 0) { +- isp = dentry->d_inode->i_security; ++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ if (rc != 0) ++ return rc; ++ ++ isp = dentry->d_inode->i_security; ++ /* ++ * Don't do anything special for these. ++ * XATTR_NAME_SMACKIPIN ++ * XATTR_NAME_SMACKIPOUT ++ * XATTR_NAME_SMACKEXEC ++ */ ++ if (strcmp(name, XATTR_NAME_SMACK) == 0) + isp->smk_task = NULL; ++ else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) + isp->smk_mmap = NULL; +- } ++ else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) ++ isp->smk_flags &= ~SMK_INODE_TRANSMUTE; + +- return rc; ++ return 0; + } + + /** +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch new file mode 100644 index 0000000..bc65513 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0030-Smack-bidirectional-UDS-connect-check.patch @@ -0,0 +1,204 @@ +From dab2915e5899611c1d90d5c35d4b463145ce9fad Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Thu, 10 Apr 2014 16:37:08 -0700 +Subject: [PATCH 30/54] Smack: bidirectional UDS connect check + +Smack IPC policy requires that the sender have write access +to the receiver. UDS streams don't do per-packet checks. The +only check is done at connect time. The existing code checks +if the connecting process can write to the other, but not the +other way around. This change adds a check that the other end +can write to the connecting process. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schuafler +--- + security/smack/smack.h | 6 +++--- + security/smack/smack_lsm.c | 44 ++++++++++++++++++++++++-------------------- + 2 files changed, 27 insertions(+), 23 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index fade085..020307e 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -80,8 +80,8 @@ struct superblock_smack { + + struct socket_smack { + struct smack_known *smk_out; /* outbound label */ +- char *smk_in; /* inbound label */ +- char *smk_packet; /* TCP peer label */ ++ struct smack_known *smk_in; /* inbound label */ ++ struct smack_known *smk_packet; /* TCP peer label */ + }; + + /* +@@ -133,7 +133,7 @@ struct smk_port_label { + struct list_head list; + struct sock *smk_sock; /* socket initialized on */ + unsigned short smk_port; /* the port number */ +- char *smk_in; /* incoming label */ ++ struct smack_known *smk_in; /* inbound label */ + struct smack_known *smk_out; /* outgoing label */ + }; + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b259a0d..21ef3a1 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1095,7 +1095,7 @@ static int smack_inode_getsecurity(const struct inode *inode, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- isp = ssp->smk_in; ++ isp = ssp->smk_in->smk_known; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) + isp = ssp->smk_out->smk_known; + else +@@ -1859,7 +1859,7 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) + if (ssp == NULL) + return -ENOMEM; + +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + ssp->smk_out = skp; + ssp->smk_packet = NULL; + +@@ -2099,7 +2099,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + + if (act == SMK_RECEIVING) { + skp = smack_net_ambient; +- object = ssp->smk_in; ++ object = ssp->smk_in->smk_known; + } else { + skp = ssp->smk_out; + object = smack_net_ambient->smk_known; +@@ -2129,9 +2129,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + list_for_each_entry(spp, &smk_ipv6_port_list, list) { + if (spp->smk_port != port) + continue; +- object = spp->smk_in; ++ object = spp->smk_in->smk_known; + if (act == SMK_CONNECTING) +- ssp->smk_packet = spp->smk_out->smk_known; ++ ssp->smk_packet = spp->smk_out; + break; + } + +@@ -2195,7 +2195,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { + ssp->smk_out = skp; + if (sock->sk->sk_family == PF_INET) { +@@ -3054,30 +3054,34 @@ static int smack_unix_stream_connect(struct sock *sock, + struct sock *other, struct sock *newsk) + { + struct smack_known *skp; ++ struct smack_known *okp; + struct socket_smack *ssp = sock->sk_security; + struct socket_smack *osp = other->sk_security; + struct socket_smack *nsp = newsk->sk_security; + struct smk_audit_info ad; + int rc = 0; +- + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; +- +- smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); +- smk_ad_setfield_u_net_sk(&ad, other); + #endif + + if (!smack_privileged(CAP_MAC_OVERRIDE)) { + skp = ssp->smk_out; +- rc = smk_access(skp, osp->smk_in, MAY_WRITE, &ad); ++ okp = osp->smk_out; ++#ifdef CONFIG_AUDIT ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ smk_ad_setfield_u_net_sk(&ad, other); ++#endif ++ rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad); ++ if (rc == 0) ++ rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL); + } + + /* + * Cross reference the peer labels for SO_PEERSEC. + */ + if (rc == 0) { +- nsp->smk_packet = ssp->smk_out->smk_known; +- ssp->smk_packet = osp->smk_out->smk_known; ++ nsp->smk_packet = ssp->smk_out; ++ ssp->smk_packet = osp->smk_out; + } + + return rc; +@@ -3109,7 +3113,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + return 0; + + skp = ssp->smk_out; +- return smk_access(skp, osp->smk_in, MAY_WRITE, &ad); ++ return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); + } + + /** +@@ -3204,7 +3208,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + if (found) + return skp; + +- if (ssp != NULL && ssp->smk_in == smack_known_star.smk_known) ++ if (ssp != NULL && ssp->smk_in == &smack_known_star) + return &smack_known_web; + return &smack_known_star; + } +@@ -3323,7 +3327,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + * This is the simplist possible security model + * for networking. + */ +- rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; +@@ -3358,7 +3362,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, + + ssp = sock->sk->sk_security; + if (ssp->smk_packet != NULL) { +- rcp = ssp->smk_packet; ++ rcp = ssp->smk_packet->smk_known; + slen = strlen(rcp) + 1; + } + +@@ -3443,7 +3447,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) + return; + + ssp = sk->sk_security; +- ssp->smk_in = skp->smk_known; ++ ssp->smk_in = skp; + ssp->smk_out = skp; + /* cssp->smk_packet is already set in smack_inet_csk_clone() */ + } +@@ -3503,7 +3507,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * Receiving a packet requires that the other end be able to write + * here. Read access is not required. + */ +- rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + if (rc != 0) + return rc; + +@@ -3547,7 +3551,7 @@ static void smack_inet_csk_clone(struct sock *sk, + + if (req->peer_secid != 0) { + skp = smack_from_secid(req->peer_secid); +- ssp->smk_packet = skp->smk_known; ++ ssp->smk_packet = skp; + } else + ssp->smk_packet = NULL; + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0031-Smack-Verify-read-access-on-file-open-v3.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0031-Smack-Verify-read-access-on-file-open-v3.patch new file mode 100644 index 0000000..8648539 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0031-Smack-Verify-read-access-on-file-open-v3.patch @@ -0,0 +1,62 @@ +From cc70dd7060ebfe5ed72c88c6316d0e295ce081a9 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 21 Apr 2014 11:10:26 -0700 +Subject: [PATCH 31/54] Smack: Verify read access on file open - v3 + +Smack believes that many of the operatons that can +be performed on an open file descriptor are read operations. +The fstat and lseek system calls are examples. +An implication of this is that files shouldn't be open +if the task doesn't have read access even if it has +write access and the file is being opened write only. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 21ef3a1..6776130 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1462,19 +1462,32 @@ static int smack_file_receive(struct file *file) + /** + * smack_file_open - Smack dentry open processing + * @file: the object +- * @cred: unused ++ * @cred: task credential + * + * Set the security blob in the file structure. ++ * Allow the open only if the task has read access. There are ++ * many read operations (e.g. fstat) that you can do with an ++ * fd even if you have the file open write-only. + * + * Returns 0 + */ + static int smack_file_open(struct file *file, const struct cred *cred) + { ++ struct task_smack *tsp = cred->security; + struct inode_smack *isp = file_inode(file)->i_security; ++ struct smk_audit_info ad; ++ int rc; + +- file->f_security = isp->smk_inode; ++ if (smack_privileged(CAP_MAC_OVERRIDE)) ++ return 0; + +- return 0; ++ smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); ++ smk_ad_setfield_u_fs_path(&ad, file->f_path); ++ rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); ++ if (rc == 0) ++ file->f_security = isp->smk_inode; ++ ++ return rc; + } + + /* +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0032-Smack-Label-cgroup-files-for-systemd.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0032-Smack-Label-cgroup-files-for-systemd.patch new file mode 100644 index 0000000..cb40c2f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0032-Smack-Label-cgroup-files-for-systemd.patch @@ -0,0 +1,80 @@ +From d7ad31586a99cf4a7715589e36e9e8cde2365ae1 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Mon, 28 Apr 2014 15:23:01 -0700 +Subject: [PATCH 32/54] Smack: Label cgroup files for systemd + +The cgroup filesystem isn't ready for an LSM to +properly use extented attributes. This patch makes +files created in the cgroup filesystem usable by +a system running Smack and systemd. + +Targeted for git://git.gitorious.org/smack-next/kernel.git + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 6776130..1085bb7 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -2821,6 +2821,15 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * of the superblock. + */ + if (opt_dentry->d_parent == opt_dentry) { ++ if (sbp->s_magic == CGROUP_SUPER_MAGIC) { ++ /* ++ * The cgroup filesystem is never mounted, ++ * so there's no opportunity to set the mount ++ * options. ++ */ ++ sbsp->smk_root = smack_known_star.smk_known; ++ sbsp->smk_default = smack_known_star.smk_known; ++ } + isp->smk_inode = sbsp->smk_root; + isp->smk_flags |= SMK_INODE_INSTANT; + goto unlockandout; +@@ -2834,16 +2843,20 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + switch (sbp->s_magic) { + case SMACK_MAGIC: ++ case PIPEFS_MAGIC: ++ case SOCKFS_MAGIC: ++ case CGROUP_SUPER_MAGIC: + /* + * Casey says that it's a little embarrassing + * that the smack file system doesn't do + * extended attributes. +- */ +- final = smack_known_star.smk_known; +- break; +- case PIPEFS_MAGIC: +- /* ++ * + * Casey says pipes are easy (?) ++ * ++ * Socket access is controlled by the socket ++ * structures associated with the task involved. ++ * ++ * Cgroupfs is special + */ + final = smack_known_star.smk_known; + break; +@@ -2855,13 +2868,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + final = ckp->smk_known; + break; +- case SOCKFS_MAGIC: +- /* +- * Socket access is controlled by the socket +- * structures associated with the task involved. +- */ +- final = smack_known_star.smk_known; +- break; + case PROC_SUPER_MAGIC: + /* + * Casey says procfs appears not to care. +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0033-Warning-in-scanf-string-typing.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0033-Warning-in-scanf-string-typing.patch new file mode 100644 index 0000000..44b1f98 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0033-Warning-in-scanf-string-typing.patch @@ -0,0 +1,32 @@ +From 3514fd7a5df09a5a45673139be44e2bd0394d1a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toralf=20F=C3=B6rster?= +Date: Sun, 27 Apr 2014 19:33:34 +0200 +Subject: [PATCH 33/54] Warning in scanf string typing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes a warning about the mismatch of types between +the declared unsigned and integer. + +Signed-off-by: Toralf Förster +--- + security/smack/smackfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 177d878..32b2488 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -1193,7 +1193,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + + data[count] = '\0'; + +- rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", ++ rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s", + &host[0], &host[1], &host[2], &host[3], &m, smack); + if (rc != 6) { + rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch new file mode 100644 index 0000000..538408f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch @@ -0,0 +1,45 @@ +From fbe0bb11353782b18ebf9455f36cce1da1003a90 Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Thu, 7 Aug 2014 20:52:33 +0400 +Subject: [PATCH 34/54] Smack: fix behavior of smack_inode_listsecurity + +Security operation ->inode_listsecurity is used for generating list of +available extended attributes for syscall listxattr. Currently it's used +only in nfs4 or if filesystem doesn't provide i_op->listxattr. + +The list is the set of NULL-terminated names, one after the other. +This method must include zero byte at the and into result. + +Also this function must return length even if string does not fit into +output buffer or it is NULL, see similar method in selinux and man listxattr. + +Signed-off-by: Konstantin Khlebnikov +--- + security/smack/smack_lsm.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 1085bb7..f72d17c 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1122,13 +1122,12 @@ static int smack_inode_getsecurity(const struct inode *inode, + static int smack_inode_listsecurity(struct inode *inode, char *buffer, + size_t buffer_size) + { +- int len = strlen(XATTR_NAME_SMACK); ++ int len = sizeof(XATTR_NAME_SMACK); + +- if (buffer != NULL && len <= buffer_size) { ++ if (buffer != NULL && len <= buffer_size) + memcpy(buffer, XATTR_NAME_SMACK, len); +- return len; +- } +- return -EINVAL; ++ ++ return len; + } + + /** +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0035-Smack-handle-zero-length-security-labels-without-pan.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0035-Smack-handle-zero-length-security-labels-without-pan.patch new file mode 100644 index 0000000..b22dbed --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0035-Smack-handle-zero-length-security-labels-without-pan.patch @@ -0,0 +1,62 @@ +From 725aece63ff35520dbd369079dd2f6430f795a5f Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Thu, 7 Aug 2014 20:52:43 +0400 +Subject: [PATCH 35/54] Smack: handle zero-length security labels without panic + +Zero-length security labels are invalid but kernel should handle them. + +This patch fixes kernel panic after setting zero-length security labels: +# attr -S -s "SMACK64" -V "" file + +And after writing zero-length string into smackfs files syslog and onlycp: +# python -c 'import os; os.write(1, "")' > /smack/syslog + +The problem is caused by brain-damaged logic in function smk_parse_smack() +which takes pointer to buffer and its length but if length below or equal zero +it thinks that the buffer is zero-terminated. Unfortunately callers of this +function are widely used and proper fix requires serious refactoring. + +Signed-off-by: Konstantin Khlebnikov +--- + security/smack/smack_lsm.c | 2 +- + security/smack/smackfs.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index f72d17c..8d23c23 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -923,7 +923,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, + rc = -EPERM; + + if (rc == 0 && check_import) { +- skp = smk_import_entry(value, size); ++ skp = size ? smk_import_entry(value, size) : NULL; + if (skp == NULL || (check_star && + (skp == &smack_known_star || skp == &smack_known_web))) + rc = -EINVAL; +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 32b2488..585bea0 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -1677,7 +1677,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, + if (smack_onlycap != NULL && smack_onlycap != skp) + return -EPERM; + +- data = kzalloc(count, GFP_KERNEL); ++ data = kzalloc(count + 1, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + +@@ -2228,7 +2228,7 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf, + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + +- data = kzalloc(count, GFP_KERNEL); ++ data = kzalloc(count + 1, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch new file mode 100644 index 0000000..2c72253 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch @@ -0,0 +1,54 @@ +From a48c9922ebf7553ec8bcecb9a41e04e120c454ec Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Thu, 7 Aug 2014 20:52:49 +0400 +Subject: [PATCH 36/54] Smack: remove unneeded NULL-termination from securtity + label + +Values of extended attributes are stored as binary blobs. NULL-termination +of them isn't required. It just wastes disk space and confuses command-line +tools like getfattr because they have to print that zero byte at the end. + +This patch removes terminating zero byte from initial security label in +smack_inode_init_security and cuts it out in function smack_inode_getsecurity +which is used by syscall getxattr. This change seems completely safe, because +function smk_parse_smack ignores everything after first zero byte. + +Signed-off-by: Konstantin Khlebnikov +--- + security/smack/smack_lsm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 8d23c23..1befb0a 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -672,7 +672,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + } + + if (len) +- *len = strlen(isp) + 1; ++ *len = strlen(isp); + + return 0; + } +@@ -1076,7 +1076,7 @@ static int smack_inode_getsecurity(const struct inode *inode, + + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { + isp = smk_of_inode(inode); +- ilen = strlen(isp) + 1; ++ ilen = strlen(isp); + *buffer = isp; + return ilen; + } +@@ -1101,7 +1101,7 @@ static int smack_inode_getsecurity(const struct inode *inode, + else + return -EOPNOTSUPP; + +- ilen = strlen(isp) + 1; ++ ilen = strlen(isp); + if (rc == 0) { + *buffer = isp; + rc = ilen; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0037-Smack-Fix-setting-label-on-successful-file-open.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0037-Smack-Fix-setting-label-on-successful-file-open.patch new file mode 100644 index 0000000..071b4ef --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0037-Smack-Fix-setting-label-on-successful-file-open.patch @@ -0,0 +1,32 @@ +From c0b37ae4c6cee96e2d6ae755b32c039cba38f4b2 Mon Sep 17 00:00:00 2001 +From: Marcin Niesluchowski +Date: Tue, 19 Aug 2014 14:26:32 +0200 +Subject: [PATCH 37/54] Smack: Fix setting label on successful file open + +While opening with CAP_MAC_OVERRIDE file label is not set. +Other calls may access it after CAP_MAC_OVERRIDE is dropped from process. + +Signed-off-by: Marcin Niesluchowski +--- + security/smack/smack_lsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 1befb0a..97eab635 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1477,8 +1477,10 @@ static int smack_file_open(struct file *file, const struct cred *cred) + struct smk_audit_info ad; + int rc; + +- if (smack_privileged(CAP_MAC_OVERRIDE)) ++ if (smack_privileged(CAP_MAC_OVERRIDE)) { ++ file->f_security = isp->smk_inode; + return 0; ++ } + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch new file mode 100644 index 0000000..a4aaf01 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0038-Smack-Bring-up-access-mode.patch @@ -0,0 +1,805 @@ +From bf68e15045643cd5195e8d634712081d0b3b4904 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Wed, 27 Aug 2014 14:51:27 -0700 +Subject: [PATCH 38/54] Smack: Bring-up access mode + +People keep asking me for permissive mode, and I keep saying "no". + +Permissive mode is wrong for more reasons than I can enumerate, +but the compelling one is that it's once on, never off. + +Nonetheless, there is an argument to be made for running a +process with lots of permissions, logging which are required, +and then locking the process down. There wasn't a way to do +that with Smack, but this provides it. + +The notion is that you start out by giving the process an +appropriate Smack label, such as "ATBirds". You create rules +with a wide range of access and the "b" mode. On Tizen it +might be: + + ATBirds System rwxalb + ATBirds User rwxalb + ATBirds _ rwxalb + User ATBirds wb + System ATBirds wb + +Accesses that fail will generate audit records. Accesses +that succeed because of rules marked with a "b" generate +log messages identifying the rule, the program and as much +object information as is convenient. + +When the system is properly configured and the programs +brought in line with the labeling scheme the "b" mode can +be removed from the rules. When the system is ready for +production the facility can be configured out. + +This provides the developer the convenience of permissive +mode without creating a system that looks like it is +enforcing a policy while it is not. + +Signed-off-by: Casey Schaufler +--- + security/smack/Kconfig | 16 +++ + security/smack/smack.h | 5 +- + security/smack/smack_access.c | 24 +++- + security/smack/smack_lsm.c | 265 ++++++++++++++++++++++++++++++++++++++---- + security/smack/smackfs.c | 11 +- + 5 files changed, 294 insertions(+), 27 deletions(-) + +diff --git a/security/smack/Kconfig b/security/smack/Kconfig +index e69de9c..b065f97 100644 +--- a/security/smack/Kconfig ++++ b/security/smack/Kconfig +@@ -12,3 +12,19 @@ config SECURITY_SMACK + of other mandatory security schemes. + If you are unsure how to answer this question, answer N. + ++config SECURITY_SMACK_BRINGUP ++ bool "Reporting on access granted by Smack rules" ++ depends on SECURITY_SMACK ++ default n ++ help ++ Enable the bring-up ("b") access mode in Smack rules. ++ When access is granted by a rule with the "b" mode a ++ message about the access requested is generated. The ++ intention is that a process can be granted a wide set ++ of access initially with the bringup mode set on the ++ rules. The developer can use the information to ++ identify which rules are necessary and what accesses ++ may be inappropriate. The developer can reduce the ++ access rule set once the behavior is well understood. ++ This is a superior mechanism to the oft abused ++ "permissive" mode of other systems. +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 020307e..2d13d5f 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -191,6 +191,7 @@ struct smk_port_label { + */ + #define MAY_TRANSMUTE 0x00001000 /* Controls directory labeling */ + #define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */ ++#define MAY_BRINGUP 0x00004000 /* Report use of this rule */ + + /* + * Just to make the common cases easier to deal with +@@ -200,9 +201,9 @@ struct smk_port_label { + #define MAY_NOT 0 + + /* +- * Number of access types used by Smack (rwxatl) ++ * Number of access types used by Smack (rwxatlb) + */ +-#define SMK_NUM_ACCESS_TYPE 6 ++#define SMK_NUM_ACCESS_TYPE 7 + + /* SMACK data */ + struct smack_audit_data { +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index c062e94..31dbd048 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -178,16 +178,27 @@ int smk_access(struct smack_known *subject_known, char *object_label, + &subject_known->smk_rules); + rcu_read_unlock(); + +- if (may > 0 && (request & may) == request) ++ if (may <= 0 || (request & may) != request) { ++ rc = -EACCES; + goto out_audit; ++ } ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++ /* ++ * Return a positive value if using bringup mode. ++ * This allows the hooks to identify checks that ++ * succeed because of "b" rules. ++ */ ++ if (may & MAY_BRINGUP) ++ rc = MAY_BRINGUP; ++#endif + +- rc = -EACCES; + out_audit: + #ifdef CONFIG_AUDIT + if (a) + smack_log(subject_known->smk_known, object_label, request, + rc, a); + #endif ++ + return rc; + } + +@@ -214,7 +225,7 @@ int smk_tskacc(struct task_smack *subject, char *obj_label, + * Check the global rule list + */ + rc = smk_access(skp, obj_label, mode, NULL); +- if (rc == 0) { ++ if (rc >= 0) { + /* + * If there is an entry in the task's rule list + * it can further restrict access. +@@ -328,6 +339,13 @@ void smack_log(char *subject_label, char *object_label, int request, + struct smack_audit_data *sad; + struct common_audit_data *a = &ad->a; + ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++ /* ++ * The result may be positive in bringup mode. ++ */ ++ if (result > 0) ++ result = 0; ++#endif + /* check if we have to log the current event */ + if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) + return; +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 97eab635..6f32c67 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -54,6 +54,149 @@ + + LIST_HEAD(smk_ipv6_port_list); + ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static void smk_bu_mode(int mode, char *s) ++{ ++ int i = 0; ++ ++ if (mode & MAY_READ) ++ s[i++] = 'r'; ++ if (mode & MAY_WRITE) ++ s[i++] = 'w'; ++ if (mode & MAY_EXEC) ++ s[i++] = 'x'; ++ if (mode & MAY_APPEND) ++ s[i++] = 'a'; ++ if (mode & MAY_TRANSMUTE) ++ s[i++] = 't'; ++ if (mode & MAY_LOCK) ++ s[i++] = 'l'; ++ if (i == 0) ++ s[i++] = '-'; ++ s[i] = '\0'; ++} ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_note(char *note, struct smack_known *sskp, char *osp, ++ int mode, int rc) ++{ ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) %s\n", ++ sskp->smk_known, osp, acc, note); ++ return 0; ++} ++#else ++#define smk_bu_note(note, sskp, osp, mode, RC) (RC) ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_current(char *note, char *osp, int mode, int rc) ++{ ++ struct task_smack *tsp = current_security(); ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) %s %s\n", ++ tsp->smk_task->smk_known, osp, acc, current->comm, note); ++ return 0; ++} ++#else ++#define smk_bu_current(note, osp, mode, RC) (RC) ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_task(struct task_struct *otp, int mode, int rc) ++{ ++ struct task_smack *tsp = current_security(); ++ struct task_smack *otsp = task_security(otp); ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) %s to %s\n", ++ tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, ++ current->comm, otp->comm); ++ return 0; ++} ++#else ++#define smk_bu_task(otp, mode, RC) (RC) ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_inode(struct inode *inode, int mode, int rc) ++{ ++ struct task_smack *tsp = current_security(); ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n", ++ tsp->smk_task->smk_known, smk_of_inode(inode), acc, ++ inode->i_sb->s_id, inode->i_ino, current->comm); ++ return 0; ++} ++#else ++#define smk_bu_inode(inode, mode, RC) (RC) ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_file(struct file *file, int mode, int rc) ++{ ++ struct task_smack *tsp = current_security(); ++ struct smack_known *sskp = tsp->smk_task; ++ struct inode *inode = file->f_inode; ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", ++ sskp->smk_known, (char *)file->f_security, acc, ++ inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, ++ current->comm); ++ return 0; ++} ++#else ++#define smk_bu_file(file, mode, RC) (RC) ++#endif ++ ++#ifdef CONFIG_SECURITY_SMACK_BRINGUP ++static int smk_bu_credfile(const struct cred *cred, struct file *file, ++ int mode, int rc) ++{ ++ struct task_smack *tsp = cred->security; ++ struct smack_known *sskp = tsp->smk_task; ++ struct inode *inode = file->f_inode; ++ char acc[SMK_NUM_ACCESS_TYPE + 1]; ++ ++ if (rc <= 0) ++ return rc; ++ ++ smk_bu_mode(mode, acc); ++ pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", ++ sskp->smk_known, smk_of_inode(inode), acc, ++ inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, ++ current->comm); ++ return 0; ++} ++#else ++#define smk_bu_credfile(cred, file, mode, RC) (RC) ++#endif ++ + /** + * smk_fetch - Fetch the smack label from a file. + * @ip: a pointer to the inode +@@ -507,6 +650,7 @@ static int smack_sb_statfs(struct dentry *dentry) + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + + rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); ++ rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc); + return rc; + } + +@@ -697,11 +841,13 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, + + isp = smk_of_inode(old_dentry->d_inode); + rc = smk_curacc(isp, MAY_WRITE, &ad); ++ rc = smk_bu_inode(old_dentry->d_inode, MAY_WRITE, rc); + + if (rc == 0 && new_dentry->d_inode != NULL) { + isp = smk_of_inode(new_dentry->d_inode); + smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); + rc = smk_curacc(isp, MAY_WRITE, &ad); ++ rc = smk_bu_inode(new_dentry->d_inode, MAY_WRITE, rc); + } + + return rc; +@@ -728,6 +874,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) + * You need write access to the thing you're unlinking + */ + rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad); ++ rc = smk_bu_inode(ip, MAY_WRITE, rc); + if (rc == 0) { + /* + * You also need write access to the containing directory +@@ -735,6 +882,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); + smk_ad_setfield_u_fs_inode(&ad, dir); + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dir, MAY_WRITE, rc); + } + return rc; + } +@@ -759,6 +907,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) + * You need write access to the thing you're removing + */ + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); + if (rc == 0) { + /* + * You also need write access to the containing directory +@@ -766,6 +915,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); + smk_ad_setfield_u_fs_inode(&ad, dir); + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dir, MAY_WRITE, rc); + } + + return rc; +@@ -797,11 +947,13 @@ static int smack_inode_rename(struct inode *old_inode, + + isp = smk_of_inode(old_dentry->d_inode); + rc = smk_curacc(isp, MAY_READWRITE, &ad); ++ rc = smk_bu_inode(old_dentry->d_inode, MAY_READWRITE, rc); + + if (rc == 0 && new_dentry->d_inode != NULL) { + isp = smk_of_inode(new_dentry->d_inode); + smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); + rc = smk_curacc(isp, MAY_READWRITE, &ad); ++ rc = smk_bu_inode(new_dentry->d_inode, MAY_READWRITE, rc); + } + return rc; + } +@@ -819,6 +971,7 @@ static int smack_inode_permission(struct inode *inode, int mask) + { + struct smk_audit_info ad; + int no_block = mask & MAY_NOT_BLOCK; ++ int rc; + + mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); + /* +@@ -832,7 +985,9 @@ static int smack_inode_permission(struct inode *inode, int mask) + return -ECHILD; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); + smk_ad_setfield_u_fs_inode(&ad, inode); +- return smk_curacc(smk_of_inode(inode), mask, &ad); ++ rc = smk_curacc(smk_of_inode(inode), mask, &ad); ++ rc = smk_bu_inode(inode, mask, rc); ++ return rc; + } + + /** +@@ -845,6 +1000,8 @@ static int smack_inode_permission(struct inode *inode, int mask) + static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) + { + struct smk_audit_info ad; ++ int rc; ++ + /* + * Need to allow for clearing the setuid bit. + */ +@@ -853,7 +1010,9 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + +- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); ++ return rc; + } + + /** +@@ -867,13 +1026,16 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) + { + struct smk_audit_info ad; + struct path path; ++ int rc; + + path.dentry = dentry; + path.mnt = mnt; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, path); +- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); ++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); ++ return rc; + } + + /** +@@ -932,8 +1094,10 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + +- if (rc == 0) ++ if (rc == 0) { + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); ++ } + + return rc; + } +@@ -993,11 +1157,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, + static int smack_inode_getxattr(struct dentry *dentry, const char *name) + { + struct smk_audit_info ad; ++ int rc; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + +- return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); ++ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); ++ return rc; + } + + /** +@@ -1033,6 +1200,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); ++ rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); + if (rc != 0) + return rc; + +@@ -1213,11 +1381,15 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + +- if (_IOC_DIR(cmd) & _IOC_WRITE) ++ if (_IOC_DIR(cmd) & _IOC_WRITE) { + rc = smk_curacc(file->f_security, MAY_WRITE, &ad); ++ rc = smk_bu_file(file, MAY_WRITE, rc); ++ } + +- if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) ++ if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { + rc = smk_curacc(file->f_security, MAY_READ, &ad); ++ rc = smk_bu_file(file, MAY_READ, rc); ++ } + + return rc; + } +@@ -1232,10 +1404,13 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, + static int smack_file_lock(struct file *file, unsigned int cmd) + { + struct smk_audit_info ad; ++ int rc; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- return smk_curacc(file->f_security, MAY_LOCK, &ad); ++ rc = smk_curacc(file->f_security, MAY_LOCK, &ad); ++ rc = smk_bu_file(file, MAY_LOCK, rc); ++ return rc; + } + + /** +@@ -1265,12 +1440,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + rc = smk_curacc(file->f_security, MAY_LOCK, &ad); ++ rc = smk_bu_file(file, MAY_LOCK, rc); + break; + case F_SETOWN: + case F_SETSIG: + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + rc = smk_curacc(file->f_security, MAY_WRITE, &ad); ++ rc = smk_bu_file(file, MAY_WRITE, rc); + break; + default: + break; +@@ -1425,6 +1602,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, + /* we don't log here as rc can be overriden */ + skp = smk_find_entry(file->f_security); + rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL); ++ rc = smk_bu_note("sigiotask", skp, tkp->smk_known, MAY_WRITE, rc); + if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) + rc = 0; + +@@ -1442,6 +1620,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, + */ + static int smack_file_receive(struct file *file) + { ++ int rc; + int may = 0; + struct smk_audit_info ad; + +@@ -1455,7 +1634,9 @@ static int smack_file_receive(struct file *file) + if (file->f_mode & FMODE_WRITE) + may |= MAY_WRITE; + +- return smk_curacc(file->f_security, may, &ad); ++ rc = smk_curacc(file->f_security, may, &ad); ++ rc = smk_bu_file(file, may, rc); ++ return rc; + } + + /** +@@ -1485,6 +1666,7 @@ static int smack_file_open(struct file *file, const struct cred *cred) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); ++ rc = smk_bu_credfile(cred, file, MAY_READ, rc); + if (rc == 0) + file->f_security = isp->smk_inode; + +@@ -1641,10 +1823,13 @@ static int smk_curacc_on_task(struct task_struct *p, int access, + { + struct smk_audit_info ad; + struct smack_known *skp = smk_of_task(task_security(p)); ++ int rc; + + smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); +- return smk_curacc(skp->smk_known, access, &ad); ++ rc = smk_curacc(skp->smk_known, access, &ad); ++ rc = smk_bu_task(p, access, rc); ++ return rc; + } + + /** +@@ -1798,6 +1983,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + struct smk_audit_info ad; + struct smack_known *skp; + struct smack_known *tkp = smk_of_task(task_security(p)); ++ int rc; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); +@@ -1805,15 +1991,20 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + * Sending a signal requires that the sender + * can write the receiver. + */ +- if (secid == 0) +- return smk_curacc(tkp->smk_known, MAY_WRITE, &ad); ++ if (secid == 0) { ++ rc = smk_curacc(tkp->smk_known, MAY_WRITE, &ad); ++ rc = smk_bu_task(p, MAY_WRITE, rc); ++ return rc; ++ } + /* + * If the secid isn't 0 we're dealing with some USB IO + * specific behavior. This is not clean. For one thing + * we can't take privilege into account. + */ + skp = smack_from_secid(secid); +- return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad); ++ rc = smk_access(skp, tkp->smk_known, MAY_WRITE, &ad); ++ rc = smk_bu_note("USB signal", skp, tkp->smk_known, MAY_WRITE, rc); ++ return rc; + } + + /** +@@ -2005,6 +2196,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + sk_lbl = SMACK_UNLABELED_SOCKET; + skp = ssp->smk_out; + rc = smk_access(skp, hostsp, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 host check", skp, hostsp, MAY_WRITE, rc); + } else { + sk_lbl = SMACK_CIPSO_SOCKET; + rc = 0; +@@ -2107,6 +2299,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + unsigned short port = 0; + char *object; + struct smk_audit_info ad; ++ int rc; + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; + #endif +@@ -2160,7 +2353,9 @@ auditout: + else + ad.a.u.net->v6info.daddr = address->sin6_addr; + #endif +- return smk_access(skp, object, MAY_WRITE, &ad); ++ rc = smk_access(skp, object, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); ++ return rc; + } + + /** +@@ -2399,12 +2594,15 @@ static int smk_curacc_shm(struct shmid_kernel *shp, int access) + { + char *ssp = smack_of_shm(shp); + struct smk_audit_info ad; ++ int rc; + + #ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = shp->shm_perm.id; + #endif +- return smk_curacc(ssp, access, &ad); ++ rc = smk_curacc(ssp, access, &ad); ++ rc = smk_bu_current("shm", ssp, access, rc); ++ return rc; + } + + /** +@@ -2523,12 +2721,15 @@ static int smk_curacc_sem(struct sem_array *sma, int access) + { + char *ssp = smack_of_sem(sma); + struct smk_audit_info ad; ++ int rc; + + #ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = sma->sem_perm.id; + #endif +- return smk_curacc(ssp, access, &ad); ++ rc = smk_curacc(ssp, access, &ad); ++ rc = smk_bu_current("sem", ssp, access, rc); ++ return rc; + } + + /** +@@ -2653,12 +2854,15 @@ static int smk_curacc_msq(struct msg_queue *msq, int access) + { + char *msp = smack_of_msq(msq); + struct smk_audit_info ad; ++ int rc; + + #ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = msq->q_perm.id; + #endif +- return smk_curacc(msp, access, &ad); ++ rc = smk_curacc(msp, access, &ad); ++ rc = smk_bu_current("msq", msp, access, rc); ++ return rc; + } + + /** +@@ -2754,12 +2958,15 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) + char *isp = ipp->security; + int may = smack_flags_to_may(flag); + struct smk_audit_info ad; ++ int rc; + + #ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = ipp->id; + #endif +- return smk_curacc(isp, may, &ad); ++ rc = smk_curacc(isp, may, &ad); ++ rc = smk_bu_current("svipc", isp, may, rc); ++ return rc; + } + + /** +@@ -3092,8 +3299,13 @@ static int smack_unix_stream_connect(struct sock *sock, + smk_ad_setfield_u_net_sk(&ad, other); + #endif + rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad); +- if (rc == 0) ++ rc = smk_bu_note("UDS connect", skp, okp->smk_known, ++ MAY_WRITE, rc); ++ if (rc == 0) { + rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL); ++ rc = smk_bu_note("UDS connect", okp, okp->smk_known, ++ MAY_WRITE, rc); ++ } + } + + /* +@@ -3121,6 +3333,7 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + struct socket_smack *osp = other->sk->sk_security; + struct smack_known *skp; + struct smk_audit_info ad; ++ int rc; + + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; +@@ -3133,7 +3346,10 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + return 0; + + skp = ssp->smk_out; +- return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); ++ rc = smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); ++ rc = smk_bu_note("UDS send", skp, osp->smk_in->smk_known, ++ MAY_WRITE, rc); ++ return rc; + } + + /** +@@ -3348,6 +3564,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + * for networking. + */ + rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in->smk_known, ++ MAY_WRITE, rc); + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; +@@ -3528,6 +3746,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * here. Read access is not required. + */ + rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in->smk_known, ++ MAY_WRITE, rc); + if (rc != 0) + return rc; + +@@ -3632,6 +3852,7 @@ static int smack_key_permission(key_ref_t key_ref, + struct smk_audit_info ad; + struct smack_known *tkp = smk_of_task(cred->security); + int request = 0; ++ int rc; + + keyp = key_ref_to_ptr(key_ref); + if (keyp == NULL) +@@ -3656,7 +3877,9 @@ static int smack_key_permission(key_ref_t key_ref, + request = MAY_READ; + if (perm & (KEY_WRITE | KEY_LINK | KEY_SETATTR)) + request = MAY_WRITE; +- return smk_access(tkp, keyp->security, request, &ad); ++ rc = smk_access(tkp, keyp->security, request, &ad); ++ rc = smk_bu_note("key access", tkp, keyp->security, request, rc); ++ return rc; + } + #endif /* CONFIG_KEYS */ + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index 585bea0..cf4e16b 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -304,6 +304,10 @@ static int smk_perm_from_str(const char *string) + case 'L': + perm |= MAY_LOCK; + break; ++ case 'b': ++ case 'B': ++ perm |= MAY_BRINGUP; ++ break; + default: + return perm; + } +@@ -616,6 +620,8 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) + seq_putc(s, 't'); + if (srp->smk_access & MAY_LOCK) + seq_putc(s, 'l'); ++ if (srp->smk_access & MAY_BRINGUP) ++ seq_putc(s, 'b'); + + seq_putc(s, '\n'); + } +@@ -1880,7 +1886,10 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, + else if (res != -ENOENT) + return -EINVAL; + +- data[0] = res == 0 ? '1' : '0'; ++ /* ++ * smk_access() can return a value > 0 in the "bringup" case. ++ */ ++ data[0] = res >= 0 ? '1' : '0'; + data[1] = '\0'; + + simple_transaction_set(file, 2); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0039-Small-fixes-in-comments-describing-function-paramete.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0039-Small-fixes-in-comments-describing-function-paramete.patch new file mode 100644 index 0000000..e8477ff --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0039-Small-fixes-in-comments-describing-function-paramete.patch @@ -0,0 +1,63 @@ +From 59332d77a0cd1574189276f202cc1df7478f5620 Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Fri, 29 Aug 2014 17:02:53 +0200 +Subject: [PATCH 39/54] Small fixes in comments describing function parameters + +Signed-off-by: Lukasz Pawelczyk +--- + security/smack/smack_lsm.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 6f32c67..a510828 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -771,8 +771,8 @@ static void smack_inode_free_security(struct inode *inode) + + /** + * smack_inode_init_security - copy out the smack from an inode +- * @inode: the inode +- * @dir: unused ++ * @inode: the newly created inode ++ * @dir: containing directory object + * @qstr: unused + * @name: where to put the attribute name + * @value: where to put the attribute value +@@ -923,10 +923,10 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) + + /** + * smack_inode_rename - Smack check on rename +- * @old_inode: the old directory +- * @old_dentry: unused +- * @new_inode: the new directory +- * @new_dentry: unused ++ * @old_inode: unused ++ * @old_dentry: the old object ++ * @new_inode: unused ++ * @new_dentry: the new object + * + * Read and write access is required on both the old and + * new directories. +@@ -1017,7 +1017,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) + + /** + * smack_inode_getattr - Smack check for getting attributes +- * @mnt: unused ++ * @mnt: vfsmount of the object + * @dentry: the object + * + * Returns 0 if access is permitted, an error code otherwise +@@ -1042,8 +1042,8 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) + * smack_inode_setxattr - Smack check for setting xattrs + * @dentry: the object + * @name: name of the attribute +- * @value: unused +- * @size: unused ++ * @value: value of the attribute ++ * @size: size of the value + * @flags: unused + * + * This protects the Smack attribute explicitly. +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0040-Fix-a-bidirectional-UDS-connect-check-typo.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0040-Fix-a-bidirectional-UDS-connect-check-typo.patch new file mode 100644 index 0000000..81559c7 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0040-Fix-a-bidirectional-UDS-connect-check-typo.patch @@ -0,0 +1,32 @@ +From 91bd808e9e5b10a9116cec72b393621bd40e772e Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Fri, 29 Aug 2014 17:02:54 +0200 +Subject: [PATCH 40/54] Fix a bidirectional UDS connect check typo + +The 54e70ec5eb090193b03e69d551fa6771a5a217c4 commit introduced a +bidirectional check that should have checked for mutual WRITE access +between two labels. Due to a typo the second check was incorrect. + +Signed-off-by: Lukasz Pawelczyk +--- + security/smack/smack_lsm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index a510828..1c98a28 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3302,8 +3302,8 @@ static int smack_unix_stream_connect(struct sock *sock, + rc = smk_bu_note("UDS connect", skp, okp->smk_known, + MAY_WRITE, rc); + if (rc == 0) { +- rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL); +- rc = smk_bu_note("UDS connect", okp, okp->smk_known, ++ rc = smk_access(okp, skp->smk_known, MAY_WRITE, NULL); ++ rc = smk_bu_note("UDS connect", okp, skp->smk_known, + MAY_WRITE, rc); + } + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch new file mode 100644 index 0000000..0ffc9a4 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch @@ -0,0 +1,1461 @@ +From 77d870a0af741cbd7423a32228540fe5cf3b0a41 Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Fri, 29 Aug 2014 17:02:55 +0200 +Subject: [PATCH 41/54] Make Smack operate on smack_known struct where it still + used char* + +Smack used to use a mix of smack_known struct and char* throughout its +APIs and implementation. This patch unifies the behaviour and makes it +store and operate exclusively on smack_known struct pointers when managing +labels. + +Signed-off-by: Lukasz Pawelczyk + +Conflicts: + security/smack/smack_access.c + security/smack/smack_lsm.c +--- + security/smack/smack.h | 34 ++--- + security/smack/smack_access.c | 94 +++++-------- + security/smack/smack_lsm.c | 299 +++++++++++++++++++++--------------------- + security/smack/smackfs.c | 61 +++++---- + 4 files changed, 233 insertions(+), 255 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 2d13d5f..b828a37 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -71,11 +71,11 @@ struct smack_known { + #define SMK_CIPSOLEN 24 + + struct superblock_smack { +- char *smk_root; +- char *smk_floor; +- char *smk_hat; +- char *smk_default; +- int smk_initialized; ++ struct smack_known *smk_root; ++ struct smack_known *smk_floor; ++ struct smack_known *smk_hat; ++ struct smack_known *smk_default; ++ int smk_initialized; + }; + + struct socket_smack { +@@ -88,7 +88,7 @@ struct socket_smack { + * Inode smack data + */ + struct inode_smack { +- char *smk_inode; /* label of the fso */ ++ struct smack_known *smk_inode; /* label of the fso */ + struct smack_known *smk_task; /* label of the task */ + struct smack_known *smk_mmap; /* label of the mmap domain */ + struct mutex smk_lock; /* initialization lock */ +@@ -112,7 +112,7 @@ struct task_smack { + struct smack_rule { + struct list_head list; + struct smack_known *smk_subject; +- char *smk_object; ++ struct smack_known *smk_object; + int smk_access; + }; + +@@ -123,7 +123,7 @@ struct smk_netlbladdr { + struct list_head list; + struct sockaddr_in smk_host; /* network address */ + struct in_addr smk_mask; /* network mask */ +- char *smk_label; /* label */ ++ struct smack_known *smk_label; /* label */ + }; + + /* +@@ -227,23 +227,23 @@ struct smk_audit_info { + /* + * These functions are in smack_lsm.c + */ +-struct inode_smack *new_inode_smack(char *); ++struct inode_smack *new_inode_smack(struct smack_known *); + + /* + * These functions are in smack_access.c + */ + int smk_access_entry(char *, char *, struct list_head *); +-int smk_access(struct smack_known *, char *, int, struct smk_audit_info *); +-int smk_tskacc(struct task_smack *, char *, u32, struct smk_audit_info *); +-int smk_curacc(char *, u32, struct smk_audit_info *); ++int smk_access(struct smack_known *, struct smack_known *, ++ int, struct smk_audit_info *); ++int smk_tskacc(struct task_smack *, struct smack_known *, ++ u32, struct smk_audit_info *); ++int smk_curacc(struct smack_known *, u32, struct smk_audit_info *); + struct smack_known *smack_from_secid(const u32); + char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); +-char *smk_import(const char *, int); + struct smack_known *smk_import_entry(const char *, int); + void smk_insert_entry(struct smack_known *skp); + struct smack_known *smk_find_entry(const char *); +-u32 smack_to_secid(const char *); + + /* + * Shared data. +@@ -253,7 +253,7 @@ extern int smack_cipso_mapped; + extern struct smack_known *smack_net_ambient; + extern struct smack_known *smack_onlycap; + extern struct smack_known *smack_syslog_label; +-extern const char *smack_cipso_option; ++extern struct smack_known smack_cipso_option; + extern int smack_ptrace_rule; + + extern struct smack_known smack_known_floor; +@@ -282,9 +282,9 @@ static inline int smk_inode_transmutable(const struct inode *isp) + } + + /* +- * Present a pointer to the smack label in an inode blob. ++ * Present a pointer to the smack label entry in an inode blob. + */ +-static inline char *smk_of_inode(const struct inode *isp) ++static inline struct smack_known *smk_of_inode(const struct inode *isp) + { + struct inode_smack *sip = isp->i_security; + return sip->smk_inode; +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 31dbd048..c6c9245 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -94,7 +94,7 @@ int smk_access_entry(char *subject_label, char *object_label, + struct smack_rule *srp; + + list_for_each_entry_rcu(srp, rule_list, list) { +- if (srp->smk_object == object_label && ++ if (srp->smk_object->smk_known == object_label && + srp->smk_subject->smk_known == subject_label) { + may = srp->smk_access; + break; +@@ -111,8 +111,8 @@ int smk_access_entry(char *subject_label, char *object_label, + + /** + * smk_access - determine if a subject has a specific access to an object +- * @subject_known: a pointer to the subject's Smack label entry +- * @object_label: a pointer to the object's Smack label ++ * @subject: a pointer to the subject's Smack label entry ++ * @object: a pointer to the object's Smack label entry + * @request: the access requested, in "MAY" format + * @a : a pointer to the audit data + * +@@ -122,8 +122,8 @@ int smk_access_entry(char *subject_label, char *object_label, + * + * Smack labels are shared on smack_list + */ +-int smk_access(struct smack_known *subject_known, char *object_label, +- int request, struct smk_audit_info *a) ++int smk_access(struct smack_known *subject, struct smack_known *object, ++ int request, struct smk_audit_info *a) + { + int may = MAY_NOT; + int rc = 0; +@@ -133,7 +133,7 @@ int smk_access(struct smack_known *subject_known, char *object_label, + * + * A star subject can't access any object. + */ +- if (subject_known == &smack_known_star) { ++ if (subject == &smack_known_star) { + rc = -EACCES; + goto out_audit; + } +@@ -142,28 +142,28 @@ int smk_access(struct smack_known *subject_known, char *object_label, + * Tasks cannot be assigned the internet label. + * An internet subject can access any object. + */ +- if (object_label == smack_known_web.smk_known || +- subject_known == &smack_known_web) ++ if (object == &smack_known_web || ++ subject == &smack_known_web) + goto out_audit; + /* + * A star object can be accessed by any subject. + */ +- if (object_label == smack_known_star.smk_known) ++ if (object == &smack_known_star) + goto out_audit; + /* + * An object can be accessed in any way by a subject + * with the same label. + */ +- if (subject_known->smk_known == object_label) ++ if (subject->smk_known == object->smk_known) + goto out_audit; + /* + * A hat subject can read any object. + * A floor object can be read by any subject. + */ + if ((request & MAY_ANYREAD) == request) { +- if (object_label == smack_known_floor.smk_known) ++ if (object == &smack_known_floor) + goto out_audit; +- if (subject_known == &smack_known_hat) ++ if (subject == &smack_known_hat) + goto out_audit; + } + /* +@@ -174,8 +174,8 @@ int smk_access(struct smack_known *subject_known, char *object_label, + * indicates there is no entry for this pair. + */ + rcu_read_lock(); +- may = smk_access_entry(subject_known->smk_known, object_label, +- &subject_known->smk_rules); ++ may = smk_access_entry(subject->smk_known, object->smk_known, ++ &subject->smk_rules); + rcu_read_unlock(); + + if (may <= 0 || (request & may) != request) { +@@ -195,8 +195,8 @@ int smk_access(struct smack_known *subject_known, char *object_label, + out_audit: + #ifdef CONFIG_AUDIT + if (a) +- smack_log(subject_known->smk_known, object_label, request, +- rc, a); ++ smack_log(subject->smk_known, object->smk_known, ++ request, rc, a); + #endif + + return rc; +@@ -204,8 +204,8 @@ out_audit: + + /** + * smk_tskacc - determine if a task has a specific access to an object +- * @tsp: a pointer to the subject task +- * @obj_label: a pointer to the object's Smack label ++ * @tsp: a pointer to the subject's task ++ * @obj_known: a pointer to the object's label entry + * @mode: the access requested, in "MAY" format + * @a : common audit data + * +@@ -214,24 +214,25 @@ out_audit: + * non zero otherwise. It allows that the task may have the capability + * to override the rules. + */ +-int smk_tskacc(struct task_smack *subject, char *obj_label, ++int smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known, + u32 mode, struct smk_audit_info *a) + { +- struct smack_known *skp = smk_of_task(subject); ++ struct smack_known *sbj_known = smk_of_task(tsp); + int may; + int rc; + + /* + * Check the global rule list + */ +- rc = smk_access(skp, obj_label, mode, NULL); ++ rc = smk_access(sbj_known, obj_known, mode, NULL); + if (rc >= 0) { + /* + * If there is an entry in the task's rule list + * it can further restrict access. + */ +- may = smk_access_entry(skp->smk_known, obj_label, +- &subject->smk_rules); ++ may = smk_access_entry(sbj_known->smk_known, ++ obj_known->smk_known, ++ &tsp->smk_rules); + if (may < 0) + goto out_audit; + if ((mode & may) == mode) +@@ -248,14 +249,15 @@ int smk_tskacc(struct task_smack *subject, char *obj_label, + out_audit: + #ifdef CONFIG_AUDIT + if (a) +- smack_log(skp->smk_known, obj_label, mode, rc, a); ++ smack_log(sbj_known->smk_known, obj_known->smk_known, ++ mode, rc, a); + #endif + return rc; + } + + /** + * smk_curacc - determine if current has a specific access to an object +- * @obj_label: a pointer to the object's Smack label ++ * @obj_known: a pointer to the object's Smack label entry + * @mode: the access requested, in "MAY" format + * @a : common audit data + * +@@ -264,11 +266,12 @@ out_audit: + * non zero otherwise. It allows that current may have the capability + * to override the rules. + */ +-int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) ++int smk_curacc(struct smack_known *obj_known, ++ u32 mode, struct smk_audit_info *a) + { + struct task_smack *tsp = current_security(); + +- return smk_tskacc(tsp, obj_label, mode, a); ++ return smk_tskacc(tsp, obj_known, mode, a); + } + + #ifdef CONFIG_AUDIT +@@ -565,27 +568,6 @@ unlockout: + } + + /** +- * smk_import - import a smack label +- * @string: a text string that might be a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. +- * +- * Returns a pointer to the label in the label list that +- * matches the passed string, adding it if necessary. +- */ +-char *smk_import(const char *string, int len) +-{ +- struct smack_known *skp; +- +- /* labels cannot begin with a '-' */ +- if (string[0] == '-') +- return NULL; +- skp = smk_import_entry(string, len); +- if (skp == NULL) +- return NULL; +- return skp->smk_known; +-} +- +-/** + * smack_from_secid - find the Smack label associated with a secid + * @secid: an integer that might be associated with a Smack label + * +@@ -611,19 +593,3 @@ struct smack_known *smack_from_secid(const u32 secid) + rcu_read_unlock(); + return &smack_known_invalid; + } +- +-/** +- * smack_to_secid - find the secid associated with a Smack label +- * @smack: the Smack label +- * +- * Returns the appropriate secid if there is one, +- * otherwise 0 +- */ +-u32 smack_to_secid(const char *smack) +-{ +- struct smack_known *skp = smk_find_entry(smack); +- +- if (skp == NULL) +- return 0; +- return skp->smk_secid; +-} +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 1c98a28..2f62a68 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -78,8 +78,8 @@ static void smk_bu_mode(int mode, char *s) + #endif + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP +-static int smk_bu_note(char *note, struct smack_known *sskp, char *osp, +- int mode, int rc) ++static int smk_bu_note(char *note, struct smack_known *sskp, ++ struct smack_known *oskp, int mode, int rc) + { + char acc[SMK_NUM_ACCESS_TYPE + 1]; + +@@ -88,15 +88,16 @@ static int smk_bu_note(char *note, struct smack_known *sskp, char *osp, + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s\n", +- sskp->smk_known, osp, acc, note); ++ sskp->smk_known, oskp->smk_known, acc, note); + return 0; + } + #else +-#define smk_bu_note(note, sskp, osp, mode, RC) (RC) ++#define smk_bu_note(note, sskp, oskp, mode, RC) (RC) + #endif + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP +-static int smk_bu_current(char *note, char *osp, int mode, int rc) ++static int smk_bu_current(char *note, struct smack_known *oskp, ++ int mode, int rc) + { + struct task_smack *tsp = current_security(); + char acc[SMK_NUM_ACCESS_TYPE + 1]; +@@ -106,11 +107,12 @@ static int smk_bu_current(char *note, char *osp, int mode, int rc) + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s %s\n", +- tsp->smk_task->smk_known, osp, acc, current->comm, note); ++ tsp->smk_task->smk_known, oskp->smk_known, ++ acc, current->comm, note); + return 0; + } + #else +-#define smk_bu_current(note, osp, mode, RC) (RC) ++#define smk_bu_current(note, oskp, mode, RC) (RC) + #endif + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP +@@ -144,7 +146,7 @@ static int smk_bu_inode(struct inode *inode, int mode, int rc) + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n", +- tsp->smk_task->smk_known, smk_of_inode(inode), acc, ++ tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc, + inode->i_sb->s_id, inode->i_ino, current->comm); + return 0; + } +@@ -188,7 +190,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", +- sskp->smk_known, smk_of_inode(inode), acc, ++ sskp->smk_known, smk_of_inode(inode)->smk_known, acc, + inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, + current->comm); + return 0; +@@ -230,11 +232,11 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, + + /** + * new_inode_smack - allocate an inode security blob +- * @smack: a pointer to the Smack label to use in the blob ++ * @skp: a pointer to the Smack label entry to use in the blob + * + * Returns the new blob or NULL if there's no memory available + */ +-struct inode_smack *new_inode_smack(char *smack) ++struct inode_smack *new_inode_smack(struct smack_known *skp) + { + struct inode_smack *isp; + +@@ -242,7 +244,7 @@ struct inode_smack *new_inode_smack(char *smack) + if (isp == NULL) + return NULL; + +- isp->smk_inode = smack; ++ isp->smk_inode = skp; + isp->smk_flags = 0; + mutex_init(&isp->smk_lock); + +@@ -321,20 +323,20 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode) + /** + * smk_ptrace_rule_check - helper for ptrace access + * @tracer: tracer process +- * @tracee_label: label of the process that's about to be traced, +- * the pointer must originate from smack structures ++ * @tracee_known: label entry of the process that's about to be traced + * @mode: ptrace attachment mode (PTRACE_MODE_*) + * @func: name of the function that called us, used for audit + * + * Returns 0 on access granted, -error on error + */ +-static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, ++static int smk_ptrace_rule_check(struct task_struct *tracer, ++ struct smack_known *tracee_known, + unsigned int mode, const char *func) + { + int rc; + struct smk_audit_info ad, *saip = NULL; + struct task_smack *tsp; +- struct smack_known *skp; ++ struct smack_known *tracer_known; + + if ((mode & PTRACE_MODE_NOAUDIT) == 0) { + smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK); +@@ -343,12 +345,12 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, + } + + tsp = task_security(tracer); +- skp = smk_of_task(tsp); ++ tracer_known = smk_of_task(tsp); + + if ((mode & PTRACE_MODE_ATTACH) && + (smack_ptrace_rule == SMACK_PTRACE_EXACT || + smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) { +- if (skp->smk_known == tracee_label) ++ if (tracer_known->smk_known == tracee_known->smk_known) + rc = 0; + else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN) + rc = -EACCES; +@@ -358,13 +360,15 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, + rc = -EACCES; + + if (saip) +- smack_log(skp->smk_known, tracee_label, 0, rc, saip); ++ smack_log(tracer_known->smk_known, ++ tracee_known->smk_known, ++ 0, rc, saip); + + return rc; + } + + /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ +- rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); ++ rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); + return rc; + } + +@@ -393,7 +397,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + + skp = smk_of_task(task_security(ctp)); + +- rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__); ++ rc = smk_ptrace_rule_check(current, skp, mode, __func__); + return rc; + } + +@@ -416,8 +420,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp) + + skp = smk_of_task(current_security()); + +- rc = smk_ptrace_rule_check(ptp, skp->smk_known, +- PTRACE_MODE_ATTACH, __func__); ++ rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); + return rc; + } + +@@ -461,10 +464,10 @@ static int smack_sb_alloc_security(struct super_block *sb) + if (sbsp == NULL) + return -ENOMEM; + +- sbsp->smk_root = smack_known_floor.smk_known; +- sbsp->smk_default = smack_known_floor.smk_known; +- sbsp->smk_floor = smack_known_floor.smk_known; +- sbsp->smk_hat = smack_known_hat.smk_known; ++ sbsp->smk_root = &smack_known_floor; ++ sbsp->smk_default = &smack_known_floor; ++ sbsp->smk_floor = &smack_known_floor; ++ sbsp->smk_hat = &smack_known_hat; + /* + * smk_initialized will be zero from kzalloc. + */ +@@ -548,7 +551,6 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + struct smack_known *skp; + char *op; + char *commap; +- char *nsp; + int transmute = 0; + int specified = 0; + +@@ -564,38 +566,38 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + + if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { + op += strlen(SMK_FSHAT); +- nsp = smk_import(op, 0); +- if (nsp != NULL) { +- sp->smk_hat = nsp; ++ skp = smk_import_entry(op, 0); ++ if (skp != NULL) { ++ sp->smk_hat = skp; + specified = 1; + } + } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { + op += strlen(SMK_FSFLOOR); +- nsp = smk_import(op, 0); +- if (nsp != NULL) { +- sp->smk_floor = nsp; ++ skp = smk_import_entry(op, 0); ++ if (skp != NULL) { ++ sp->smk_floor = skp; + specified = 1; + } + } else if (strncmp(op, SMK_FSDEFAULT, + strlen(SMK_FSDEFAULT)) == 0) { + op += strlen(SMK_FSDEFAULT); +- nsp = smk_import(op, 0); +- if (nsp != NULL) { +- sp->smk_default = nsp; ++ skp = smk_import_entry(op, 0); ++ if (skp != NULL) { ++ sp->smk_default = skp; + specified = 1; + } + } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { + op += strlen(SMK_FSROOT); +- nsp = smk_import(op, 0); +- if (nsp != NULL) { +- sp->smk_root = nsp; ++ skp = smk_import_entry(op, 0); ++ if (skp != NULL) { ++ sp->smk_root = skp; + specified = 1; + } + } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { + op += strlen(SMK_FSTRANS); +- nsp = smk_import(op, 0); +- if (nsp != NULL) { +- sp->smk_root = nsp; ++ skp = smk_import_entry(op, 0); ++ if (skp != NULL) { ++ sp->smk_root = skp; + transmute = 1; + specified = 1; + } +@@ -612,8 +614,8 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) + * Unprivileged mounts get root and default from the caller. + */ + skp = smk_of_current(); +- sp->smk_root = skp->smk_known; +- sp->smk_default = skp->smk_known; ++ sp->smk_root = skp; ++ sp->smk_default = skp; + } + /* + * Initialize the root inode. +@@ -690,7 +692,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) + tracer = ptrace_parent(current); + if (likely(tracer != NULL)) + rc = smk_ptrace_rule_check(tracer, +- isp->smk_task->smk_known, ++ isp->smk_task, + PTRACE_MODE_ATTACH, + __func__); + rcu_read_unlock(); +@@ -751,7 +753,7 @@ static int smack_inode_alloc_security(struct inode *inode) + { + struct smack_known *skp = smk_of_current(); + +- inode->i_security = new_inode_smack(skp->smk_known); ++ inode->i_security = new_inode_smack(skp); + if (inode->i_security == NULL) + return -ENOMEM; + return 0; +@@ -786,8 +788,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + { + struct inode_smack *issp = inode->i_security; + struct smack_known *skp = smk_of_current(); +- char *isp = smk_of_inode(inode); +- char *dsp = smk_of_inode(dir); ++ struct smack_known *isp = smk_of_inode(inode); ++ struct smack_known *dsp = smk_of_inode(dir); + int may; + + if (name) +@@ -795,7 +797,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + + if (value) { + rcu_read_lock(); +- may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules); ++ may = smk_access_entry(skp->smk_known, dsp->smk_known, ++ &skp->smk_rules); + rcu_read_unlock(); + + /* +@@ -810,13 +813,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_flags |= SMK_INODE_CHANGED; + } + +- *value = kstrdup(isp, GFP_NOFS); ++ *value = kstrdup(isp->smk_known, GFP_NOFS); + if (*value == NULL) + return -ENOMEM; + } + + if (len) +- *len = strlen(isp); ++ *len = strlen(isp->smk_known); + + return 0; + } +@@ -832,7 +835,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry) + { +- char *isp; ++ struct smack_known *isp; + struct smk_audit_info ad; + int rc; + +@@ -939,7 +942,7 @@ static int smack_inode_rename(struct inode *old_inode, + struct dentry *new_dentry) + { + int rc; +- char *isp; ++ struct smack_known *isp; + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); +@@ -1127,9 +1130,9 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, + if (strcmp(name, XATTR_NAME_SMACK) == 0) { + skp = smk_import_entry(value, size); + if (skp != NULL) +- isp->smk_inode = skp->smk_known; ++ isp->smk_inode = skp; + else +- isp->smk_inode = smack_known_invalid.smk_known; ++ isp->smk_inode = &smack_known_invalid; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { + skp = smk_import_entry(value, size); + if (skp != NULL) +@@ -1238,14 +1241,14 @@ static int smack_inode_getsecurity(const struct inode *inode, + struct socket *sock; + struct super_block *sbp; + struct inode *ip = (struct inode *)inode; +- char *isp; ++ struct smack_known *isp; + int ilen; + int rc = 0; + + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { + isp = smk_of_inode(inode); +- ilen = strlen(isp); +- *buffer = isp; ++ ilen = strlen(isp->smk_known); ++ *buffer = isp->smk_known; + return ilen; + } + +@@ -1263,15 +1266,15 @@ static int smack_inode_getsecurity(const struct inode *inode, + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) +- isp = ssp->smk_in->smk_known; ++ isp = ssp->smk_in; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) +- isp = ssp->smk_out->smk_known; ++ isp = ssp->smk_out; + else + return -EOPNOTSUPP; + +- ilen = strlen(isp); ++ ilen = strlen(isp->smk_known); + if (rc == 0) { +- *buffer = isp; ++ *buffer = isp->smk_known; + rc = ilen; + } + +@@ -1307,7 +1310,7 @@ static void smack_inode_getsecid(const struct inode *inode, u32 *secid) + { + struct inode_smack *isp = inode->i_security; + +- *secid = smack_to_secid(isp->smk_inode); ++ *secid = isp->smk_inode->smk_secid; + } + + /* +@@ -1346,7 +1349,7 @@ static int smack_file_alloc_security(struct file *file) + { + struct smack_known *skp = smk_of_current(); + +- file->f_security = skp->smk_known; ++ file->f_security = skp; + return 0; + } + +@@ -1474,7 +1477,7 @@ static int smack_mmap_file(struct file *file, + struct smack_known *mkp; + struct smack_rule *srp; + struct task_smack *tsp; +- char *osmack; ++ struct smack_known *okp; + struct inode_smack *isp; + int may; + int mmay; +@@ -1500,18 +1503,19 @@ static int smack_mmap_file(struct file *file, + * to that rule's object label. + */ + list_for_each_entry_rcu(srp, &skp->smk_rules, list) { +- osmack = srp->smk_object; ++ okp = srp->smk_object; + /* + * Matching labels always allows access. + */ +- if (mkp->smk_known == osmack) ++ if (mkp->smk_known == okp->smk_known) + continue; + /* + * If there is a matching local rule take + * that into account as well. + */ +- may = smk_access_entry(srp->smk_subject->smk_known, osmack, +- &tsp->smk_rules); ++ may = smk_access_entry(srp->smk_subject->smk_known, ++ okp->smk_known, ++ &tsp->smk_rules); + if (may == -ENOENT) + may = srp->smk_access; + else +@@ -1528,8 +1532,8 @@ static int smack_mmap_file(struct file *file, + * If there isn't one a SMACK64MMAP subject + * can't have as much access as current. + */ +- mmay = smk_access_entry(mkp->smk_known, osmack, +- &mkp->smk_rules); ++ mmay = smk_access_entry(mkp->smk_known, okp->smk_known, ++ &mkp->smk_rules); + if (mmay == -ENOENT) { + rc = -EACCES; + break; +@@ -1538,8 +1542,8 @@ static int smack_mmap_file(struct file *file, + * If there is a local entry it modifies the + * potential access, too. + */ +- tmay = smk_access_entry(mkp->smk_known, osmack, +- &tsp->smk_rules); ++ tmay = smk_access_entry(mkp->smk_known, okp->smk_known, ++ &tsp->smk_rules); + if (tmay != -ENOENT) + mmay &= tmay; + +@@ -1570,7 +1574,7 @@ static int smack_file_set_fowner(struct file *file) + { + struct smack_known *skp = smk_of_current(); + +- file->f_security = skp->smk_known; ++ file->f_security = skp; + return 0; + } + +@@ -1600,15 +1604,15 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, + file = container_of(fown, struct file, f_owner); + + /* we don't log here as rc can be overriden */ +- skp = smk_find_entry(file->f_security); +- rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL); +- rc = smk_bu_note("sigiotask", skp, tkp->smk_known, MAY_WRITE, rc); ++ skp = file->f_security; ++ rc = smk_access(skp, tkp, MAY_WRITE, NULL); ++ rc = smk_bu_note("sigiotask", skp, tkp, MAY_WRITE, rc); + if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) + rc = 0; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, tsk); +- smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad); ++ smack_log(skp->smk_known, tkp->smk_known, MAY_WRITE, rc, &ad); + return rc; + } + +@@ -1805,7 +1809,7 @@ static int smack_kernel_create_files_as(struct cred *new, + struct inode_smack *isp = inode->i_security; + struct task_smack *tsp = new->security; + +- tsp->smk_forked = smk_find_entry(isp->smk_inode); ++ tsp->smk_forked = isp->smk_inode; + tsp->smk_task = tsp->smk_forked; + return 0; + } +@@ -1827,7 +1831,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access, + + smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); +- rc = smk_curacc(skp->smk_known, access, &ad); ++ rc = smk_curacc(skp, access, &ad); + rc = smk_bu_task(p, access, rc); + return rc; + } +@@ -1992,7 +1996,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + * can write the receiver. + */ + if (secid == 0) { +- rc = smk_curacc(tkp->smk_known, MAY_WRITE, &ad); ++ rc = smk_curacc(tkp, MAY_WRITE, &ad); + rc = smk_bu_task(p, MAY_WRITE, rc); + return rc; + } +@@ -2002,8 +2006,8 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + * we can't take privilege into account. + */ + skp = smack_from_secid(secid); +- rc = smk_access(skp, tkp->smk_known, MAY_WRITE, &ad); +- rc = smk_bu_note("USB signal", skp, tkp->smk_known, MAY_WRITE, rc); ++ rc = smk_access(skp, tkp, MAY_WRITE, &ad); ++ rc = smk_bu_note("USB signal", skp, tkp, MAY_WRITE, rc); + return rc; + } + +@@ -2038,7 +2042,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) + struct inode_smack *isp = inode->i_security; + struct smack_known *skp = smk_of_task(task_security(p)); + +- isp->smk_inode = skp->smk_known; ++ isp->smk_inode = skp; + } + + /* +@@ -2096,7 +2100,7 @@ static void smack_sk_free_security(struct sock *sk) + * + * Returns the label of the far end or NULL if it's not special. + */ +-static char *smack_host_label(struct sockaddr_in *sip) ++static struct smack_known *smack_host_label(struct sockaddr_in *sip) + { + struct smk_netlbladdr *snp; + struct in_addr *siap = &sip->sin_addr; +@@ -2113,7 +2117,7 @@ static char *smack_host_label(struct sockaddr_in *sip) + if ((&snp->smk_host.sin_addr)->s_addr == + (siap->s_addr & (&snp->smk_mask)->s_addr)) { + /* we have found the special CIPSO option */ +- if (snp->smk_label == smack_cipso_option) ++ if (snp->smk_label == &smack_cipso_option) + return NULL; + return snp->smk_label; + } +@@ -2178,13 +2182,13 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + struct smack_known *skp; + int rc; + int sk_lbl; +- char *hostsp; ++ struct smack_known *hkp; + struct socket_smack *ssp = sk->sk_security; + struct smk_audit_info ad; + + rcu_read_lock(); +- hostsp = smack_host_label(sap); +- if (hostsp != NULL) { ++ hkp = smack_host_label(sap); ++ if (hkp != NULL) { + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; + +@@ -2195,8 +2199,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + #endif + sk_lbl = SMACK_UNLABELED_SOCKET; + skp = ssp->smk_out; +- rc = smk_access(skp, hostsp, MAY_WRITE, &ad); +- rc = smk_bu_note("IPv4 host check", skp, hostsp, MAY_WRITE, rc); ++ rc = smk_access(skp, hkp, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc); + } else { + sk_lbl = SMACK_CIPSO_SOCKET; + rc = 0; +@@ -2297,7 +2301,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + struct socket_smack *ssp = sk->sk_security; + struct smack_known *skp; + unsigned short port = 0; +- char *object; ++ struct smack_known *object; + struct smk_audit_info ad; + int rc; + #ifdef CONFIG_AUDIT +@@ -2306,10 +2310,10 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + + if (act == SMK_RECEIVING) { + skp = smack_net_ambient; +- object = ssp->smk_in->smk_known; ++ object = ssp->smk_in; + } else { + skp = ssp->smk_out; +- object = smack_net_ambient->smk_known; ++ object = smack_net_ambient; + } + + /* +@@ -2336,7 +2340,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, + list_for_each_entry(spp, &smk_ipv6_port_list, list) { + if (spp->smk_port != port) + continue; +- object = spp->smk_in->smk_known; ++ object = spp->smk_in; + if (act == SMK_CONNECTING) + ssp->smk_packet = spp->smk_out; + break; +@@ -2387,7 +2391,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + return -EINVAL; + + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { +- nsp->smk_inode = skp->smk_known; ++ nsp->smk_inode = skp; + nsp->smk_flags |= SMK_INODE_INSTANT; + return 0; + } +@@ -2529,7 +2533,7 @@ static int smack_msg_msg_alloc_security(struct msg_msg *msg) + { + struct smack_known *skp = smk_of_current(); + +- msg->security = skp->smk_known; ++ msg->security = skp; + return 0; + } + +@@ -2550,9 +2554,9 @@ static void smack_msg_msg_free_security(struct msg_msg *msg) + * + * Returns a pointer to the smack value + */ +-static char *smack_of_shm(struct shmid_kernel *shp) ++static struct smack_known *smack_of_shm(struct shmid_kernel *shp) + { +- return (char *)shp->shm_perm.security; ++ return (struct smack_known *)shp->shm_perm.security; + } + + /** +@@ -2566,7 +2570,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) + struct kern_ipc_perm *isp = &shp->shm_perm; + struct smack_known *skp = smk_of_current(); + +- isp->security = skp->smk_known; ++ isp->security = skp; + return 0; + } + +@@ -2592,7 +2596,7 @@ static void smack_shm_free_security(struct shmid_kernel *shp) + */ + static int smk_curacc_shm(struct shmid_kernel *shp, int access) + { +- char *ssp = smack_of_shm(shp); ++ struct smack_known *ssp = smack_of_shm(shp); + struct smk_audit_info ad; + int rc; + +@@ -2677,9 +2681,9 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, + * + * Returns a pointer to the smack value + */ +-static char *smack_of_sem(struct sem_array *sma) ++static struct smack_known *smack_of_sem(struct sem_array *sma) + { +- return (char *)sma->sem_perm.security; ++ return (struct smack_known *)sma->sem_perm.security; + } + + /** +@@ -2693,7 +2697,7 @@ static int smack_sem_alloc_security(struct sem_array *sma) + struct kern_ipc_perm *isp = &sma->sem_perm; + struct smack_known *skp = smk_of_current(); + +- isp->security = skp->smk_known; ++ isp->security = skp; + return 0; + } + +@@ -2719,7 +2723,7 @@ static void smack_sem_free_security(struct sem_array *sma) + */ + static int smk_curacc_sem(struct sem_array *sma, int access) + { +- char *ssp = smack_of_sem(sma); ++ struct smack_known *ssp = smack_of_sem(sma); + struct smk_audit_info ad; + int rc; + +@@ -2815,7 +2819,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq) + struct kern_ipc_perm *kisp = &msq->q_perm; + struct smack_known *skp = smk_of_current(); + +- kisp->security = skp->smk_known; ++ kisp->security = skp; + return 0; + } + +@@ -2836,11 +2840,11 @@ static void smack_msg_queue_free_security(struct msg_queue *msq) + * smack_of_msq - the smack pointer for the msq + * @msq: the object + * +- * Returns a pointer to the smack value ++ * Returns a pointer to the smack label entry + */ +-static char *smack_of_msq(struct msg_queue *msq) ++static struct smack_known *smack_of_msq(struct msg_queue *msq) + { +- return (char *)msq->q_perm.security; ++ return (struct smack_known *)msq->q_perm.security; + } + + /** +@@ -2852,7 +2856,7 @@ static char *smack_of_msq(struct msg_queue *msq) + */ + static int smk_curacc_msq(struct msg_queue *msq, int access) + { +- char *msp = smack_of_msq(msq); ++ struct smack_known *msp = smack_of_msq(msq); + struct smk_audit_info ad; + int rc; + +@@ -2955,7 +2959,7 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, + */ + static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) + { +- char *isp = ipp->security; ++ struct smack_known *iskp = ipp->security; + int may = smack_flags_to_may(flag); + struct smk_audit_info ad; + int rc; +@@ -2964,8 +2968,8 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = ipp->id; + #endif +- rc = smk_curacc(isp, may, &ad); +- rc = smk_bu_current("svipc", isp, may, rc); ++ rc = smk_curacc(iskp, may, &ad); ++ rc = smk_bu_current("svipc", iskp, may, rc); + return rc; + } + +@@ -2976,9 +2980,9 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) + */ + static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) + { +- char *smack = ipp->security; ++ struct smack_known *iskp = ipp->security; + +- *secid = smack_to_secid(smack); ++ *secid = iskp->smk_secid; + } + + /** +@@ -2995,7 +2999,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + struct inode_smack *isp; + struct smack_known *skp; + struct smack_known *ckp = smk_of_current(); +- char *final; ++ struct smack_known *final; + char trattr[TRANS_TRUE_SIZE]; + int transflag = 0; + int rc; +@@ -3035,8 +3039,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * so there's no opportunity to set the mount + * options. + */ +- sbsp->smk_root = smack_known_star.smk_known; +- sbsp->smk_default = smack_known_star.smk_known; ++ sbsp->smk_root = &smack_known_star; ++ sbsp->smk_default = &smack_known_star; + } + isp->smk_inode = sbsp->smk_root; + isp->smk_flags |= SMK_INODE_INSTANT; +@@ -3066,7 +3070,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * + * Cgroupfs is special + */ +- final = smack_known_star.smk_known; ++ final = &smack_known_star; + break; + case DEVPTS_SUPER_MAGIC: + /* +@@ -3074,7 +3078,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * Programs that change smack have to treat the + * pty with respect. + */ +- final = ckp->smk_known; ++ final = ckp; + break; + case PROC_SUPER_MAGIC: + /* +@@ -3088,7 +3092,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * but watch out, because they're volitile, + * getting recreated on every reboot. + */ +- final = smack_known_star.smk_known; ++ final = &smack_known_star; + /* + * No break. + * +@@ -3107,7 +3111,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * UNIX domain sockets use lower level socket data. + */ + if (S_ISSOCK(inode->i_mode)) { +- final = smack_known_star.smk_known; ++ final = &smack_known_star; + break; + } + /* +@@ -3124,7 +3128,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + dp = dget(opt_dentry); + skp = smk_fetch(XATTR_NAME_SMACK, inode, dp); + if (skp != NULL) +- final = skp->smk_known; ++ final = skp; + + /* + * Transmuting directory +@@ -3173,7 +3177,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + } + + if (final == NULL) +- isp->smk_inode = ckp->smk_known; ++ isp->smk_inode = ckp; + else + isp->smk_inode = final; + +@@ -3298,12 +3302,11 @@ static int smack_unix_stream_connect(struct sock *sock, + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + smk_ad_setfield_u_net_sk(&ad, other); + #endif +- rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad); +- rc = smk_bu_note("UDS connect", skp, okp->smk_known, +- MAY_WRITE, rc); ++ rc = smk_access(skp, okp, MAY_WRITE, &ad); ++ rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); + if (rc == 0) { +- rc = smk_access(okp, skp->smk_known, MAY_WRITE, NULL); +- rc = smk_bu_note("UDS connect", okp, skp->smk_known, ++ rc = smk_access(okp, skp, MAY_WRITE, NULL); ++ rc = smk_bu_note("UDS connect", okp, skp, + MAY_WRITE, rc); + } + } +@@ -3331,7 +3334,6 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + { + struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *osp = other->sk->sk_security; +- struct smack_known *skp; + struct smk_audit_info ad; + int rc; + +@@ -3345,10 +3347,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) + if (smack_privileged(CAP_MAC_OVERRIDE)) + return 0; + +- skp = ssp->smk_out; +- rc = smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); +- rc = smk_bu_note("UDS send", skp, osp->smk_in->smk_known, +- MAY_WRITE, rc); ++ rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); ++ rc = smk_bu_note("UDS send", ssp->smk_out, osp->smk_in, MAY_WRITE, rc); + return rc; + } + +@@ -3563,8 +3563,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + * This is the simplist possible security model + * for networking. + */ +- rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); +- rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in->smk_known, ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in, + MAY_WRITE, rc); + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); +@@ -3708,7 +3708,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct netlbl_lsm_secattr secattr; + struct sockaddr_in addr; + struct iphdr *hdr; +- char *hsp; ++ struct smack_known *hskp; + int rc; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT +@@ -3745,9 +3745,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + * Receiving a packet requires that the other end be able to write + * here. Read access is not required. + */ +- rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); +- rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in->smk_known, +- MAY_WRITE, rc); ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc); + if (rc != 0) + return rc; + +@@ -3765,10 +3764,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + hdr = ip_hdr(skb); + addr.sin_addr.s_addr = hdr->saddr; + rcu_read_lock(); +- hsp = smack_host_label(&addr); ++ hskp = smack_host_label(&addr); + rcu_read_unlock(); + +- if (hsp == NULL) ++ if (hskp == NULL) + rc = netlbl_req_setattr(req, &skp->smk_netlabel); + else + netlbl_req_delattr(req); +@@ -3821,7 +3820,7 @@ static int smack_key_alloc(struct key *key, const struct cred *cred, + { + struct smack_known *skp = smk_of_task(cred->security); + +- key->security = skp->smk_known; ++ key->security = skp; + return 0; + } + +@@ -3910,6 +3909,7 @@ static int smack_key_permission(key_ref_t key_ref, + */ + static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) + { ++ struct smack_known *skp; + char **rule = (char **)vrule; + *rule = NULL; + +@@ -3919,7 +3919,9 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) + if (op != Audit_equal && op != Audit_not_equal) + return -EINVAL; + +- *rule = smk_import(rulestr, 0); ++ skp = smk_import_entry(rulestr, 0); ++ if (skp) ++ *rule = skp->smk_known; + + return 0; + } +@@ -4038,7 +4040,12 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) + */ + static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) + { +- *secid = smack_to_secid(secdata); ++ struct smack_known *skp = smk_find_entry(secdata); ++ ++ if (skp) ++ *secid = skp->smk_secid; ++ else ++ *secid = 0; + return 0; + } + +diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c +index cf4e16b..c3f363a 100644 +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -131,14 +131,17 @@ LIST_HEAD(smack_rule_list); + + struct smack_parsed_rule { + struct smack_known *smk_subject; +- char *smk_object; ++ struct smack_known *smk_object; + int smk_access1; + int smk_access2; + }; + + static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; + +-const char *smack_cipso_option = SMACK_CIPSO_OPTION; ++struct smack_known smack_cipso_option = { ++ .smk_known = SMACK_CIPSO_OPTION, ++ .smk_secid = 0, ++}; + + /* + * Values for parsing cipso rules +@@ -339,7 +342,7 @@ static int smk_fill_rule(const char *subject, const char *object, + if (rule->smk_subject == NULL) + return -EINVAL; + +- rule->smk_object = smk_import(object, len); ++ rule->smk_object = smk_import_entry(object, len); + if (rule->smk_object == NULL) + return -EINVAL; + } else { +@@ -359,7 +362,7 @@ static int smk_fill_rule(const char *subject, const char *object, + kfree(cp); + if (skp == NULL) + return -ENOENT; +- rule->smk_object = skp->smk_known; ++ rule->smk_object = skp; + } + + rule->smk_access1 = smk_perm_from_str(access1); +@@ -598,13 +601,15 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max) + * anything you read back. + */ + if (strlen(srp->smk_subject->smk_known) >= max || +- strlen(srp->smk_object) >= max) ++ strlen(srp->smk_object->smk_known) >= max) + return; + + if (srp->smk_access == 0) + return; + +- seq_printf(s, "%s %s", srp->smk_subject->smk_known, srp->smk_object); ++ seq_printf(s, "%s %s", ++ srp->smk_subject->smk_known, ++ srp->smk_object->smk_known); + + seq_putc(s, ' '); + +@@ -1073,7 +1078,7 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v) + for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++); + + seq_printf(s, "%u.%u.%u.%u/%d %s\n", +- hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); ++ hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label->smk_known); + + return 0; + } +@@ -1153,10 +1158,10 @@ static void smk_netlbladdr_insert(struct smk_netlbladdr *new) + static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) + { +- struct smk_netlbladdr *skp; ++ struct smk_netlbladdr *snp; + struct sockaddr_in newname; + char *smack; +- char *sp; ++ struct smack_known *skp; + char *data; + char *host = (char *)&newname.sin_addr.s_addr; + int rc; +@@ -1219,15 +1224,15 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + * If smack begins with '-', it is an option, don't import it + */ + if (smack[0] != '-') { +- sp = smk_import(smack, 0); +- if (sp == NULL) { ++ skp = smk_import_entry(smack, 0); ++ if (skp == NULL) { + rc = -EINVAL; + goto free_out; + } + } else { + /* check known options */ +- if (strcmp(smack, smack_cipso_option) == 0) +- sp = (char *)smack_cipso_option; ++ if (strcmp(smack, smack_cipso_option.smk_known) == 0) ++ skp = &smack_cipso_option; + else { + rc = -EINVAL; + goto free_out; +@@ -1250,9 +1255,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + nsa = newname.sin_addr.s_addr; + /* try to find if the prefix is already in the list */ + found = 0; +- list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) { +- if (skp->smk_host.sin_addr.s_addr == nsa && +- skp->smk_mask.s_addr == mask.s_addr) { ++ list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) { ++ if (snp->smk_host.sin_addr.s_addr == nsa && ++ snp->smk_mask.s_addr == mask.s_addr) { + found = 1; + break; + } +@@ -1260,26 +1265,26 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + smk_netlabel_audit_set(&audit_info); + + if (found == 0) { +- skp = kzalloc(sizeof(*skp), GFP_KERNEL); +- if (skp == NULL) ++ snp = kzalloc(sizeof(*snp), GFP_KERNEL); ++ if (snp == NULL) + rc = -ENOMEM; + else { + rc = 0; +- skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; +- skp->smk_mask.s_addr = mask.s_addr; +- skp->smk_label = sp; +- smk_netlbladdr_insert(skp); ++ snp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; ++ snp->smk_mask.s_addr = mask.s_addr; ++ snp->smk_label = skp; ++ smk_netlbladdr_insert(snp); + } + } else { + /* we delete the unlabeled entry, only if the previous label + * wasn't the special CIPSO option */ +- if (skp->smk_label != smack_cipso_option) ++ if (snp->smk_label != &smack_cipso_option) + rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, +- &skp->smk_host.sin_addr, &skp->smk_mask, ++ &snp->smk_host.sin_addr, &snp->smk_mask, + PF_INET, &audit_info); + else + rc = 0; +- skp->smk_label = sp; ++ snp->smk_label = skp; + } + + /* +@@ -1287,10 +1292,10 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, + * this host so that incoming packets get labeled. + * but only if we didn't get the special CIPSO option + */ +- if (rc == 0 && sp != smack_cipso_option) ++ if (rc == 0 && skp != &smack_cipso_option) + rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, +- &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, +- smack_to_secid(skp->smk_label), &audit_info); ++ &snp->smk_host.sin_addr, &snp->smk_mask, PF_INET, ++ snp->smk_label->smk_secid, &audit_info); + + if (rc == 0) + rc = count; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch new file mode 100644 index 0000000..274d3df --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch @@ -0,0 +1,52 @@ +From 8515408b0cb0e819fdb197796a7509f4833fd8dd Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Thu, 9 Oct 2014 16:18:55 -0700 +Subject: [PATCH 42/54] Smack: Lock mode for the floor and hat labels + +The lock access mode allows setting a read lock on a file +for with the process has only read access. The floor label is +defined to make it easy to have the basic system installed such +that everyone can read it. Once there's a desire to read lock +(rationally or otherwise) a floor file a rule needs to get set. +This happens all the time, so make the floor label a little bit +more special and allow everyone lock access, too. By implication, +give processes with the hat label (hat can read everything) +lock access as well. This reduces clutter in the Smack rule set. + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_access.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index c6c9245..09077a5 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -142,8 +142,7 @@ int smk_access(struct smack_known *subject, struct smack_known *object, + * Tasks cannot be assigned the internet label. + * An internet subject can access any object. + */ +- if (object == &smack_known_web || +- subject == &smack_known_web) ++ if (object == &smack_known_web || subject == &smack_known_web) + goto out_audit; + /* + * A star object can be accessed by any subject. +@@ -157,10 +156,11 @@ int smk_access(struct smack_known *subject, struct smack_known *object, + if (subject->smk_known == object->smk_known) + goto out_audit; + /* +- * A hat subject can read any object. +- * A floor object can be read by any subject. ++ * A hat subject can read or lock any object. ++ * A floor object can be read or locked by any subject. + */ +- if ((request & MAY_ANYREAD) == request) { ++ if ((request & MAY_ANYREAD) == request || ++ (request & MAY_LOCK) == request) { + if (object == &smack_known_floor) + goto out_audit; + if (subject == &smack_known_hat) +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch new file mode 100644 index 0000000..1a5b545 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch @@ -0,0 +1,79 @@ +From f85163c82300f68eb73002d1b0e1a92288ff41fe Mon Sep 17 00:00:00 2001 +From: Rohit +Date: Wed, 15 Oct 2014 17:40:41 +0530 +Subject: [PATCH 43/54] Security: smack: replace kzalloc with kmem_cache for + inode_smack + +The patch use kmem_cache to allocate/free inode_smack since they are +alloced in high volumes making it a perfect case for kmem_cache. + +As per analysis, 24 bytes of memory is wasted per allocation due +to internal fragmentation. With kmem_cache, this can be avoided. + +Accounting of memory allocation is below : + total slack net count-alloc/free caller +Before (with kzalloc) +1919872 719952 1919872 29998/0 new_inode_smack+0x14 + +After (with kmem_cache) +1201680 0 1201680 30042/0 new_inode_smack+0x18 + +>From above data, we found that 719952 bytes(~700 KB) of memory is +saved on allocation of 29998 smack inodes. + +Signed-off-by: Rohit +--- + security/smack/smack_lsm.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 2f62a68..b3978ea 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -53,6 +53,7 @@ + #define SMK_SENDING 2 + + LIST_HEAD(smk_ipv6_port_list); ++static struct kmem_cache *smack_inode_cache; + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP + static void smk_bu_mode(int mode, char *s) +@@ -240,7 +241,7 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) + { + struct inode_smack *isp; + +- isp = kzalloc(sizeof(struct inode_smack), GFP_NOFS); ++ isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS); + if (isp == NULL) + return NULL; + +@@ -767,7 +768,7 @@ static int smack_inode_alloc_security(struct inode *inode) + */ + static void smack_inode_free_security(struct inode *inode) + { +- kfree(inode->i_security); ++ kmem_cache_free(smack_inode_cache, inode->i_security); + inode->i_security = NULL; + } + +@@ -4266,10 +4267,16 @@ static __init int smack_init(void) + if (!security_module_enable(&smack_ops)) + return 0; + ++ smack_inode_cache = KMEM_CACHE(inode_smack, 0); ++ if (!smack_inode_cache) ++ return -ENOMEM; ++ + tsp = new_task_smack(&smack_known_floor, &smack_known_floor, + GFP_KERNEL); +- if (tsp == NULL) ++ if (tsp == NULL) { ++ kmem_cache_destroy(smack_inode_cache); + return -ENOMEM; ++ } + + printk(KERN_INFO "Smack: Initializing.\n"); + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch new file mode 100644 index 0000000..25e04db --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch @@ -0,0 +1,95 @@ +From dba5d8f4af7c92a247c4c0ab2688b9f01a4f34fc Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Sat, 8 Nov 2014 17:48:05 +0300 +Subject: [PATCH 44/54] security: smack: fix out-of-bounds access in + smk_parse_smack() + +Setting smack label on file (e.g. 'attr -S -s SMACK64 -V "test" test') +triggered following spew on the kernel with KASan applied: + ================================================================== + BUG: AddressSanitizer: out of bounds access in strncpy+0x28/0x60 at addr ffff8800059ad064 + ============================================================================= + BUG kmalloc-8 (Not tainted): kasan error + ----------------------------------------------------------------------------- + + Disabling lock debugging due to kernel taint + INFO: Slab 0xffffea0000166b40 objects=128 used=7 fp=0xffff8800059ad080 flags=0x4000000000000080 + INFO: Object 0xffff8800059ad060 @offset=96 fp=0xffff8800059ad080 + + Bytes b4 ffff8800059ad050: a0 df 9a 05 00 88 ff ff 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ + Object ffff8800059ad060: 74 65 73 74 6b 6b 6b a5 testkkk. + Redzone ffff8800059ad068: cc cc cc cc cc cc cc cc ........ + Padding ffff8800059ad078: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ + CPU: 0 PID: 528 Comm: attr Tainted: G B 3.18.0-rc1-mm1+ #5 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 + 0000000000000000 ffff8800059ad064 ffffffff81534cf2 ffff880005a5bc40 + ffffffff8112fe1a 0000000100800006 0000000f059ad060 ffff880006000f90 + 0000000000000296 ffffea0000166b40 ffffffff8107ca97 ffff880005891060 + Call Trace: + ? dump_stack (lib/dump_stack.c:52) + ? kasan_report_error (mm/kasan/report.c:102 mm/kasan/report.c:178) + ? preempt_count_sub (kernel/sched/core.c:2651) + ? __asan_load1 (mm/kasan/kasan.h:50 mm/kasan/kasan.c:248 mm/kasan/kasan.c:358) + ? strncpy (lib/string.c:121) + ? strncpy (lib/string.c:121) + ? smk_parse_smack (security/smack/smack_access.c:457) + ? setxattr (fs/xattr.c:343) + ? smk_import_entry (security/smack/smack_access.c:514) + ? smack_inode_setxattr (security/smack/smack_lsm.c:1093 (discriminator 1)) + ? security_inode_setxattr (security/security.c:602) + ? vfs_setxattr (fs/xattr.c:134) + ? setxattr (fs/xattr.c:343) + ? setxattr (fs/xattr.c:360) + ? get_parent_ip (kernel/sched/core.c:2606) + ? preempt_count_sub (kernel/sched/core.c:2651) + ? __percpu_counter_add (arch/x86/include/asm/preempt.h:98 lib/percpu_counter.c:90) + ? get_parent_ip (kernel/sched/core.c:2606) + ? preempt_count_sub (kernel/sched/core.c:2651) + ? __mnt_want_write (arch/x86/include/asm/preempt.h:98 fs/namespace.c:359) + ? path_setxattr (fs/xattr.c:380) + ? SyS_lsetxattr (fs/xattr.c:397) + ? system_call_fastpath (arch/x86/kernel/entry_64.S:423) + Read of size 1 by task attr: + Memory state around the buggy address: + ffff8800059ace80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff8800059acf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ffff8800059acf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + >ffff8800059ad000: 00 fc fc fc 00 fc fc fc 05 fc fc fc 04 fc fc fc + ^ + ffff8800059ad080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8800059ad100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ffff8800059ad180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ================================================================== + +strncpy() copies one byte more than the source string has. +Fix this by passing the correct length to strncpy(). + +Now we can remove initialization of the last byte in 'smack' string +because kzalloc() already did this for us. + +Signed-off-by: Andrey Ryabinin +--- + security/smack/smack_access.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 09077a5..8d0cd73 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -452,10 +452,9 @@ char *smk_parse_smack(const char *string, int len) + return NULL; + + smack = kzalloc(i + 1, GFP_KERNEL); +- if (smack != NULL) { +- strncpy(smack, string, i + 1); +- smack[i] = '\0'; +- } ++ if (smack != NULL) ++ strncpy(smack, string, i); ++ + return smack; + } + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0045-smack-miscellaneous-small-fixes-in-function-comments.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0045-smack-miscellaneous-small-fixes-in-function-comments.patch new file mode 100644 index 0000000..317707f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0045-smack-miscellaneous-small-fixes-in-function-comments.patch @@ -0,0 +1,62 @@ +From 72b47845b28439881d4db37b13eb97dccdc50e0f Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Wed, 26 Nov 2014 15:31:06 +0100 +Subject: [PATCH 45/54] smack: miscellaneous small fixes in function comments + +Signed-off-by: Lukasz Pawelczyk +--- + security/smack/smack_lsm.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index b3978ea..eacd7fc 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -202,6 +202,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, + + /** + * smk_fetch - Fetch the smack label from a file. ++ * @name: type of the label (attribute) + * @ip: a pointer to the inode + * @dp: a pointer to the dentry + * +@@ -254,7 +255,9 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) + + /** + * new_task_smack - allocate a task security blob +- * @smack: a pointer to the Smack label to use in the blob ++ * @task: a pointer to the Smack label for the running task ++ * @forked: a pointer to the Smack label for the forked task ++ * @gfp: type of the memory for the allocation + * + * Returns the new blob or NULL if there's no memory available + */ +@@ -277,8 +280,9 @@ static struct task_smack *new_task_smack(struct smack_known *task, + + /** + * smk_copy_rules - copy a rule set +- * @nhead - new rules header pointer +- * @ohead - old rules header pointer ++ * @nhead: new rules header pointer ++ * @ohead: old rules header pointer ++ * @gfp: type of the memory for the allocation + * + * Returns 0 on success, -ENOMEM on error + */ +@@ -3836,11 +3840,11 @@ static void smack_key_free(struct key *key) + key->security = NULL; + } + +-/* ++/** + * smack_key_permission - Smack access on a key + * @key_ref: gets to the object + * @cred: the credentials to use +- * @perm: unused ++ * @perm: requested key permissions + * + * Return 0 if the task has read and write to the object, + * an error code otherwise +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0046-smack-fix-logic-in-smack_inode_init_security-functio.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0046-smack-fix-logic-in-smack_inode_init_security-functio.patch new file mode 100644 index 0000000..ec5221d --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0046-smack-fix-logic-in-smack_inode_init_security-functio.patch @@ -0,0 +1,43 @@ +From b9fb9ef37ee4c2d9c30564afa8bfbb1bc3d58124 Mon Sep 17 00:00:00 2001 +From: Lukasz Pawelczyk +Date: Wed, 26 Nov 2014 15:31:07 +0100 +Subject: [PATCH 46/54] smack: fix logic in smack_inode_init_security function + +In principle if this function was called with "value" == NULL and "len" +not NULL it could return different results for the "len" compared to a +case where "name" was not NULL. This is a hypothetical case that does +not exist in the kernel, but it's a logic bug nonetheless. + +Signed-off-by: Lukasz Pawelczyk +--- + security/smack/smack_lsm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index eacd7fc..2ec6cdb 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -800,7 +800,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + if (name) + *name = XATTR_SMACK_SUFFIX; + +- if (value) { ++ if (value && len) { + rcu_read_lock(); + may = smk_access_entry(skp->smk_known, dsp->smk_known, + &skp->smk_rules); +@@ -821,10 +821,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + *value = kstrdup(isp->smk_known, GFP_NOFS); + if (*value == NULL) + return -ENOMEM; +- } + +- if (len) + *len = strlen(isp->smk_known); ++ } + + return 0; + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch new file mode 100644 index 0000000..255da99 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch @@ -0,0 +1,56 @@ +From 11d11ff47a952f09a85be5ed85c83ee19f8a74d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=81ukasz=20Stelmach?= +Date: Tue, 16 Dec 2014 16:53:08 +0100 +Subject: [PATCH 47/54] smack: introduce a special case for tmpfs in + smack_d_instantiate() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Files created with __shmem_file_stup() appear to have somewhat fake +dentries which make them look like root directories and not get +the label the current process or ("*") star meant for tmpfs files. + +Signed-off-by: Łukasz Stelmach +--- + security/smack/smack_lsm.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 2ec6cdb..bc43227 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3037,7 +3037,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * of the superblock. + */ + if (opt_dentry->d_parent == opt_dentry) { +- if (sbp->s_magic == CGROUP_SUPER_MAGIC) { ++ switch (sbp->s_magic) { ++ case CGROUP_SUPER_MAGIC: + /* + * The cgroup filesystem is never mounted, + * so there's no opportunity to set the mount +@@ -3045,8 +3046,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + sbsp->smk_root = &smack_known_star; + sbsp->smk_default = &smack_known_star; ++ isp->smk_inode = sbsp->smk_root; ++ break; ++ case TMPFS_MAGIC: ++ /* ++ * What about shmem/tmpfs anonymous files with dentry ++ * obtained from d_alloc_pseudo()? ++ */ ++ isp->smk_inode = smk_of_current(); ++ break; ++ default: ++ isp->smk_inode = sbsp->smk_root; ++ break; + } +- isp->smk_inode = sbsp->smk_root; + isp->smk_flags |= SMK_INODE_INSTANT; + goto unlockandout; + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch new file mode 100644 index 0000000..6df1e69 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch @@ -0,0 +1,40 @@ +From 8f134ed7adfba222fc1ea182accc95e7fb8e2be3 Mon Sep 17 00:00:00 2001 +From: Zbigniew Jasinski +Date: Mon, 29 Dec 2014 15:34:58 +0100 +Subject: [PATCH 48/54] smack: Fix a bidirectional UDS connect check typo + +The 54e70ec5eb090193b03e69d551fa6771a5a217c4 commit introduced a +bidirectional check that should have checked for mutual WRITE access +between two labels. Due to a typo subject's OUT label is checked with +object's OUT. Should be OUT to IN. + +Signed-off-by: Zbigniew Jasinski +--- + security/smack/smack_lsm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index bc43227..c6f8664 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3313,7 +3313,7 @@ static int smack_unix_stream_connect(struct sock *sock, + + if (!smack_privileged(CAP_MAC_OVERRIDE)) { + skp = ssp->smk_out; +- okp = osp->smk_out; ++ okp = osp->smk_in; + #ifdef CONFIG_AUDIT + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + smk_ad_setfield_u_net_sk(&ad, other); +@@ -3321,6 +3321,8 @@ static int smack_unix_stream_connect(struct sock *sock, + rc = smk_access(skp, okp, MAY_WRITE, &ad); + rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); + if (rc == 0) { ++ okp = osp->smk_out; ++ skp = ssp->smk_in; + rc = smk_access(okp, skp, MAY_WRITE, NULL); + rc = smk_bu_note("UDS connect", okp, skp, + MAY_WRITE, rc); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0049-Smack-Rework-file-hooks.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0049-Smack-Rework-file-hooks.patch new file mode 100644 index 0000000..bceea97 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0049-Smack-Rework-file-hooks.patch @@ -0,0 +1,172 @@ +From d27c9576dedafae4f315dc8a64501c1d4aef5cff Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Fri, 12 Dec 2014 17:19:19 -0800 +Subject: [PATCH 49/54] Smack: Rework file hooks + +This is one of those cases where you look at code you did +years ago and wonder what you might have been thinking. +There are a number of LSM hooks that work off of file pointers, +and most of them really want the security data from the inode. +Some, however, really want the security context that the process +had when the file was opened. The difference went undetected in +Smack until it started getting used in a real system with real +testing. At that point it was clear that something was amiss. + +This patch corrects the misuse of the f_security value in several +of the hooks. The behavior will not usually be any different, as +the process had to be able to open the file in the first place, and +the old check almost always succeeded, as will the new, but for +different reasons. + +Thanks to the Samsung Tizen development team that identified this. + +Change-Id: If23494f46eaf27e0247a5f0daf31a4415ae936c8 +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 38 ++++++++++++++++++-------------------- + 1 file changed, 18 insertions(+), 20 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index c6f8664..9aa34d3 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -160,7 +160,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) + { + struct task_smack *tsp = current_security(); + struct smack_known *sskp = tsp->smk_task; +- struct inode *inode = file->f_inode; ++ struct inode *inode = file_inode(file); + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) +@@ -1347,6 +1347,9 @@ static int smack_file_permission(struct file *file, int mask) + * The security blob for a file is a pointer to the master + * label list, so no allocation is done. + * ++ * f_security is the owner security information. It ++ * isn't used on file access checks, it's for send_sigio. ++ * + * Returns 0 + */ + static int smack_file_alloc_security(struct file *file) +@@ -1384,17 +1387,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, + { + int rc = 0; + struct smk_audit_info ad; ++ struct inode *inode = file_inode(file); + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + + if (_IOC_DIR(cmd) & _IOC_WRITE) { +- rc = smk_curacc(file->f_security, MAY_WRITE, &ad); ++ rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); + rc = smk_bu_file(file, MAY_WRITE, rc); + } + + if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { +- rc = smk_curacc(file->f_security, MAY_READ, &ad); ++ rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad); + rc = smk_bu_file(file, MAY_READ, rc); + } + +@@ -1412,10 +1416,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd) + { + struct smk_audit_info ad; + int rc; ++ struct inode *inode = file_inode(file); + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- rc = smk_curacc(file->f_security, MAY_LOCK, &ad); ++ rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); + rc = smk_bu_file(file, MAY_LOCK, rc); + return rc; + } +@@ -1437,7 +1442,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, + { + struct smk_audit_info ad; + int rc = 0; +- ++ struct inode *inode = file_inode(file); + + switch (cmd) { + case F_GETLK: +@@ -1446,14 +1451,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, + case F_SETLKW: + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- rc = smk_curacc(file->f_security, MAY_LOCK, &ad); ++ rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); + rc = smk_bu_file(file, MAY_LOCK, rc); + break; + case F_SETOWN: + case F_SETSIG: + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- rc = smk_curacc(file->f_security, MAY_WRITE, &ad); ++ rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); + rc = smk_bu_file(file, MAY_WRITE, rc); + break; + default: +@@ -1571,14 +1576,10 @@ static int smack_mmap_file(struct file *file, + * smack_file_set_fowner - set the file security blob value + * @file: object in question + * +- * Returns 0 +- * Further research may be required on this one. + */ + static int smack_file_set_fowner(struct file *file) + { +- struct smack_known *skp = smk_of_current(); +- +- file->f_security = skp; ++ file->f_security = smk_of_current(); + return 0; + } + +@@ -1631,6 +1632,7 @@ static int smack_file_receive(struct file *file) + int rc; + int may = 0; + struct smk_audit_info ad; ++ struct inode *inode = file_inode(file); + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +@@ -1642,7 +1644,7 @@ static int smack_file_receive(struct file *file) + if (file->f_mode & FMODE_WRITE) + may |= MAY_WRITE; + +- rc = smk_curacc(file->f_security, may, &ad); ++ rc = smk_curacc(smk_of_inode(inode), may, &ad); + rc = smk_bu_file(file, may, rc); + return rc; + } +@@ -1662,21 +1664,17 @@ static int smack_file_receive(struct file *file) + static int smack_file_open(struct file *file, const struct cred *cred) + { + struct task_smack *tsp = cred->security; +- struct inode_smack *isp = file_inode(file)->i_security; ++ struct inode *inode = file_inode(file); + struct smk_audit_info ad; + int rc; + +- if (smack_privileged(CAP_MAC_OVERRIDE)) { +- file->f_security = isp->smk_inode; ++ if (smack_privileged(CAP_MAC_OVERRIDE)) + return 0; +- } + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); + smk_ad_setfield_u_fs_path(&ad, file->f_path); +- rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); ++ rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad); + rc = smk_bu_credfile(cred, file, MAY_READ, rc); +- if (rc == 0) +- file->f_security = isp->smk_inode; + + return rc; + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch new file mode 100644 index 0000000..bbaf99f --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0050-Smack-secmark-support-for-netfilter.patch @@ -0,0 +1,448 @@ +From ca4b65446c72278483c473c189191f50f2b2466e Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Fri, 12 Dec 2014 17:08:40 -0800 +Subject: [PATCH 50/54] Smack: secmark support for netfilter + +Smack uses CIPSO to label internet packets and thus provide +for access control on delivery of packets. The netfilter facility +was not used to allow for Smack to work properly without netfilter +configuration. Smack does not need netfilter, however there are +cases where it would be handy. + +As a side effect, the labeling of local IPv4 packets can be optimized +and the handling of local IPv6 packets is just all out better. + +The best part is that the netfilter tools use "contexts" that +are just strings, and they work just as well for Smack as they +do for SELinux. + +All of the conditional compilation for IPv6 was implemented +by Rafal Krypa + +Signed-off-by: Casey Schaufler +--- + security/smack/Kconfig | 12 +++++ + security/smack/Makefile | 1 + + security/smack/smack.h | 1 + + security/smack/smack_lsm.c | 94 +++++++++++++++++++++++++++++++++++---- + security/smack/smack_netfilter.c | 96 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 196 insertions(+), 8 deletions(-) + create mode 100644 security/smack/smack_netfilter.c + +diff --git a/security/smack/Kconfig b/security/smack/Kconfig +index b065f97..271adae 100644 +--- a/security/smack/Kconfig ++++ b/security/smack/Kconfig +@@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP + access rule set once the behavior is well understood. + This is a superior mechanism to the oft abused + "permissive" mode of other systems. ++ If you are unsure how to answer this question, answer N. ++ ++config SECURITY_SMACK_NETFILTER ++ bool "Packet marking using secmarks for netfilter" ++ depends on SECURITY_SMACK ++ depends on NETWORK_SECMARK ++ depends on NETFILTER ++ default n ++ help ++ This enables security marking of network packets using ++ Smack labels. ++ If you are unsure how to answer this question, answer N. +diff --git a/security/smack/Makefile b/security/smack/Makefile +index 67a63aa..616cf93 100644 +--- a/security/smack/Makefile ++++ b/security/smack/Makefile +@@ -5,3 +5,4 @@ + obj-$(CONFIG_SECURITY_SMACK) := smack.o + + smack-y := smack_lsm.o smack_access.o smackfs.o ++smack-$(CONFIG_NETFILTER) += smack_netfilter.o +diff --git a/security/smack/smack.h b/security/smack/smack.h +index b828a37..7629eae 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *); + /* + * Shared data. + */ ++extern int smack_enabled; + extern int smack_cipso_direct; + extern int smack_cipso_mapped; + extern struct smack_known *smack_net_ambient; +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 9aa34d3..ae3e1b6 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -52,8 +52,11 @@ + #define SMK_RECEIVING 1 + #define SMK_SENDING 2 + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + LIST_HEAD(smk_ipv6_port_list); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + static struct kmem_cache *smack_inode_cache; ++int smack_enabled; + + #ifdef CONFIG_SECURITY_SMACK_BRINGUP + static void smk_bu_mode(int mode, char *s) +@@ -2214,6 +2217,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) + return smack_netlabel(sk, sk_lbl); + } + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + /** + * smk_ipv6_port_label - Smack port access table management + * @sock: socket +@@ -2363,6 +2367,7 @@ auditout: + rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); + return rc; + } ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + + /** + * smack_inode_setsecurity - set smack xattrs +@@ -2423,8 +2428,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, + } else + return -EOPNOTSUPP; + ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + if (sock->sk->sk_family == PF_INET6) + smk_ipv6_port_label(sock, NULL); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + + return 0; + } +@@ -2452,6 +2459,7 @@ static int smack_socket_post_create(struct socket *sock, int family, + return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); + } + ++#ifndef CONFIG_SECURITY_SMACK_NETFILTER + /** + * smack_socket_bind - record port binding information. + * @sock: the socket +@@ -2465,11 +2473,14 @@ static int smack_socket_post_create(struct socket *sock, int family, + static int smack_socket_bind(struct socket *sock, struct sockaddr *address, + int addrlen) + { ++#if IS_ENABLED(CONFIG_IPV6) + if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) + smk_ipv6_port_label(sock, address); ++#endif + + return 0; + } ++#endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ + + /** + * smack_socket_connect - connect access check +@@ -2498,8 +2509,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, + case PF_INET6: + if (addrlen < sizeof(struct sockaddr_in6)) + return -EINVAL; ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, + SMK_CONNECTING); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + break; + } + return rc; +@@ -3382,7 +3395,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + int size) + { + struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + int rc = 0; + + /* +@@ -3396,7 +3411,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, + rc = smack_netlabel_send(sock->sk, sip); + break; + case AF_INET6: ++#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) + rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); ++#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ + break; + } + return rc; +@@ -3487,6 +3504,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, + return smack_net_ambient; + } + ++#if IS_ENABLED(CONFIG_IPV6) + static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) + { + u8 nexthdr; +@@ -3533,6 +3551,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) + } + return proto; + } ++#endif /* CONFIG_IPV6 */ + + /** + * smack_socket_sock_rcv_skb - Smack packet delivery access check +@@ -3545,15 +3564,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + struct netlbl_lsm_secattr secattr; + struct socket_smack *ssp = sk->sk_security; +- struct smack_known *skp; +- struct sockaddr_in6 sadd; ++ struct smack_known *skp = NULL; + int rc = 0; + struct smk_audit_info ad; + #ifdef CONFIG_AUDIT + struct lsm_network_audit net; + #endif ++#if IS_ENABLED(CONFIG_IPV6) ++ struct sockaddr_in6 sadd; ++ int proto; ++#endif /* CONFIG_IPV6 */ ++ + switch (sk->sk_family) { + case PF_INET: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ /* ++ * If there is a secmark use it rather than the CIPSO label. ++ * If there is no secmark fall back to CIPSO. ++ * The secmark is assumed to reflect policy better. ++ */ ++ if (skb && skb->secmark != 0) { ++ skp = smack_from_secid(skb->secmark); ++ goto access_check; ++ } ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + /* + * Translate what netlabel gave us. + */ +@@ -3567,6 +3601,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + + netlbl_secattr_destroy(&secattr); + ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++access_check: ++#endif + #ifdef CONFIG_AUDIT + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + ad.a.u.net->family = sk->sk_family; +@@ -3585,14 +3622,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) + if (rc != 0) + netlbl_skbuff_err(skb, rc, 0); + break; ++#if IS_ENABLED(CONFIG_IPV6) + case PF_INET6: +- rc = smk_skb_to_addr_ipv6(skb, &sadd); +- if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) +- rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); ++ proto = smk_skb_to_addr_ipv6(skb, &sadd); ++ if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) ++ break; ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ if (skb && skb->secmark != 0) ++ skp = smack_from_secid(skb->secmark); + else +- rc = 0; ++ skp = smack_net_ambient; ++#ifdef CONFIG_AUDIT ++ smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ++ ad.a.u.net->family = sk->sk_family; ++ ad.a.u.net->netif = skb->skb_iif; ++ ipv6_skb_to_auditdata(skb, &ad.a, NULL); ++#endif /* CONFIG_AUDIT */ ++ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); ++ rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, ++ MAY_WRITE, rc); ++#else /* CONFIG_SECURITY_SMACK_NETFILTER */ ++ rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + break; ++#endif /* CONFIG_IPV6 */ + } ++ + return rc; + } + +@@ -3654,16 +3709,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + if (skb != NULL) { + if (skb->protocol == htons(ETH_P_IP)) + family = PF_INET; ++#if IS_ENABLED(CONFIG_IPV6) + else if (skb->protocol == htons(ETH_P_IPV6)) + family = PF_INET6; ++#endif /* CONFIG_IPV6 */ + } + if (family == PF_UNSPEC && sock != NULL) + family = sock->sk->sk_family; + +- if (family == PF_UNIX) { ++ switch (family) { ++ case PF_UNIX: + ssp = sock->sk->sk_security; + s = ssp->smk_out->smk_secid; +- } else if (family == PF_INET || family == PF_INET6) { ++ break; ++ case PF_INET: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ s = skb->secmark; ++ if (s != 0) ++ break; ++#endif + /* + * Translate what netlabel gave us. + */ +@@ -3676,6 +3740,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, + s = skp->smk_secid; + } + netlbl_secattr_destroy(&secattr); ++ break; ++#if IS_ENABLED(CONFIG_IPV6) ++ case PF_INET6: ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ s = skb->secmark; ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ ++ break; ++#endif /* CONFIG_IPV6 */ + } + *secid = s; + if (s == 0) +@@ -3731,6 +3803,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct lsm_network_audit net; + #endif + ++#if IS_ENABLED(CONFIG_IPV6) + if (family == PF_INET6) { + /* + * Handle mapped IPv4 packets arriving +@@ -3742,6 +3815,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + else + return 0; + } ++#endif /* CONFIG_IPV6 */ + + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); +@@ -4201,7 +4275,9 @@ struct security_operations smack_ops = { + .unix_may_send = smack_unix_may_send, + + .socket_post_create = smack_socket_post_create, ++#ifndef CONFIG_SECURITY_SMACK_NETFILTER + .socket_bind = smack_socket_bind, ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + .socket_connect = smack_socket_connect, + .socket_sendmsg = smack_socket_sendmsg, + .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, +@@ -4282,6 +4358,8 @@ static __init int smack_init(void) + if (!security_module_enable(&smack_ops)) + return 0; + ++ smack_enabled = 1; ++ + smack_inode_cache = KMEM_CACHE(inode_smack, 0); + if (!smack_inode_cache) + return -ENOMEM; +diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c +new file mode 100644 +index 0000000..c952632 +--- /dev/null ++++ b/security/smack/smack_netfilter.c +@@ -0,0 +1,96 @@ ++/* ++ * Simplified MAC Kernel (smack) security module ++ * ++ * This file contains the Smack netfilter implementation ++ * ++ * Author: ++ * Casey Schaufler ++ * ++ * Copyright (C) 2014 Casey Schaufler ++ * Copyright (C) 2014 Intel Corporation. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2, ++ * as published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include "smack.h" ++ ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ ++static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct socket_smack *ssp; ++ struct smack_known *skp; ++ ++ if (skb && skb->sk && skb->sk->sk_security) { ++ ssp = skb->sk->sk_security; ++ skp = ssp->smk_out; ++ skb->secmark = skp->smk_secid; ++ } ++ ++ return NF_ACCEPT; ++} ++#endif /* IPV6 */ ++ ++static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, ++ struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct socket_smack *ssp; ++ struct smack_known *skp; ++ ++ if (skb && skb->sk && skb->sk->sk_security) { ++ ssp = skb->sk->sk_security; ++ skp = ssp->smk_out; ++ skb->secmark = skp->smk_secid; ++ } ++ ++ return NF_ACCEPT; ++} ++ ++static struct nf_hook_ops smack_nf_ops[] = { ++ { ++ .hook = smack_ipv4_output, ++ .owner = THIS_MODULE, ++ .pf = NFPROTO_IPV4, ++ .hooknum = NF_INET_LOCAL_OUT, ++ .priority = NF_IP_PRI_SELINUX_FIRST, ++ }, ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ { ++ .hook = smack_ipv6_output, ++ .owner = THIS_MODULE, ++ .pf = NFPROTO_IPV6, ++ .hooknum = NF_INET_LOCAL_OUT, ++ .priority = NF_IP6_PRI_SELINUX_FIRST, ++ }, ++#endif /* IPV6 */ ++}; ++ ++static int __init smack_nf_ip_init(void) ++{ ++ int err; ++ ++ if (smack_enabled == 0) ++ return 0; ++ ++ printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); ++ ++ err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); ++ if (err) ++ pr_info("Smack: nf_register_hooks: error %d\n", err); ++ ++ return 0; ++} ++ ++__initcall(smack_nf_ip_init); +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch new file mode 100644 index 0000000..9bb0fc6 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch @@ -0,0 +1,31 @@ +From 7c99b043770ddb2c258531163b631ff3256757e4 Mon Sep 17 00:00:00 2001 +From: Rafal Krypa +Date: Thu, 8 Jan 2015 18:52:45 +0100 +Subject: [PATCH 51/54] smack: Add missing logging in bidirectional UDS connect + check + +During UDS connection check, both sides are checked for write access to +the other side. But only the first check is performed with audit support. +The second one didn't produce any audit logs. This simple patch fixes that. + +Signed-off-by: Rafal Krypa +--- + security/smack/smack_lsm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index ae3e1b6..12eb355 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3334,7 +3334,7 @@ static int smack_unix_stream_connect(struct sock *sock, + if (rc == 0) { + okp = osp->smk_out; + skp = ssp->smk_in; +- rc = smk_access(okp, skp, MAY_WRITE, NULL); ++ rc = smk_access(okp, skp, MAY_WRITE, &ad); + rc = smk_bu_note("UDS connect", okp, skp, + MAY_WRITE, rc); + } +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0052-smack-fix-possible-use-after-frees-in-task_security-.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0052-smack-fix-possible-use-after-frees-in-task_security-.patch new file mode 100644 index 0000000..7486945 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0052-smack-fix-possible-use-after-frees-in-task_security-.patch @@ -0,0 +1,253 @@ +From 7089ef9dcab89e60396bafb8c6cc0398f09da902 Mon Sep 17 00:00:00 2001 +From: Andrey Ryabinin +Date: Tue, 13 Jan 2015 18:52:40 +0300 +Subject: [PATCH 52/54] smack: fix possible use after frees in task_security() + callers + +We hit use after free on dereferncing pointer to task_smack struct in +smk_of_task() called from smack_task_to_inode(). + +task_security() macro uses task_cred_xxx() to get pointer to the task_smack. +task_cred_xxx() could be used only for non-pointer members of task's +credentials. It cannot be used for pointer members since what they point +to may disapper after dropping RCU read lock. + +Mainly task_security() used this way: + smk_of_task(task_security(p)) + +Intead of this introduce function smk_of_task_struct() which +takes task_struct as argument and returns pointer to smk_known struct +and do this under RCU read lock. +Bogus task_security() macro is not used anymore, so remove it. + +KASan's report for this: + + AddressSanitizer: use after free in smack_task_to_inode+0x50/0x70 at addr c4635600 + ============================================================================= + BUG kmalloc-64 (Tainted: PO): kasan error + ----------------------------------------------------------------------------- + + Disabling lock debugging due to kernel taint + INFO: Allocated in new_task_smack+0x44/0xd8 age=39 cpu=0 pid=1866 + kmem_cache_alloc_trace+0x88/0x1bc + new_task_smack+0x44/0xd8 + smack_cred_prepare+0x48/0x21c + security_prepare_creds+0x44/0x4c + prepare_creds+0xdc/0x110 + smack_setprocattr+0x104/0x150 + security_setprocattr+0x4c/0x54 + proc_pid_attr_write+0x12c/0x194 + vfs_write+0x1b0/0x370 + SyS_write+0x5c/0x94 + ret_fast_syscall+0x0/0x48 + INFO: Freed in smack_cred_free+0xc4/0xd0 age=27 cpu=0 pid=1564 + kfree+0x270/0x290 + smack_cred_free+0xc4/0xd0 + security_cred_free+0x34/0x3c + put_cred_rcu+0x58/0xcc + rcu_process_callbacks+0x738/0x998 + __do_softirq+0x264/0x4cc + do_softirq+0x94/0xf4 + irq_exit+0xbc/0x120 + handle_IRQ+0x104/0x134 + gic_handle_irq+0x70/0xac + __irq_svc+0x44/0x78 + _raw_spin_unlock+0x18/0x48 + sync_inodes_sb+0x17c/0x1d8 + sync_filesystem+0xac/0xfc + vdfs_file_fsync+0x90/0xc0 + vfs_fsync_range+0x74/0x7c + INFO: Slab 0xd3b23f50 objects=32 used=31 fp=0xc4635600 flags=0x4080 + INFO: Object 0xc4635600 @offset=5632 fp=0x (null) + + Bytes b4 c46355f0: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ + Object c4635600: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk + Object c4635610: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk + Object c4635620: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk + Object c4635630: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk. + Redzone c4635640: bb bb bb bb .... + Padding c46356e8: 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZZZZZZZZZ + Padding c46356f8: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ + CPU: 5 PID: 834 Comm: launchpad_prelo Tainted: PBO 3.10.30 #1 + Backtrace: + [] (dump_backtrace+0x0/0x158) from [] (show_stack+0x20/0x24) + r7:c4634010 r6:d3b23f50 r5:c4635600 r4:d1002140 + [] (show_stack+0x0/0x24) from [] (dump_stack+0x20/0x28) + [] (dump_stack+0x0/0x28) from [] (print_trailer+0x124/0x144) + [] (print_trailer+0x0/0x144) from [] (object_err+0x3c/0x44) + r7:c4635600 r6:d1002140 r5:d3b23f50 r4:c4635600 + [] (object_err+0x0/0x44) from [] (kasan_report_error+0x2b8/0x538) + r6:d1002140 r5:d3b23f50 r4:c6429cf8 r3:c09e1aa7 + [] (kasan_report_error+0x0/0x538) from [] (__asan_load4+0xd4/0xf8) + [] (__asan_load4+0x0/0xf8) from [] (smack_task_to_inode+0x50/0x70) + r5:c4635600 r4:ca9da000 + [] (smack_task_to_inode+0x0/0x70) from [] (security_task_to_inode+0x3c/0x44) + r5:cca25e80 r4:c0ba9780 + [] (security_task_to_inode+0x0/0x44) from [] (pid_revalidate+0x124/0x178) + r6:00000000 r5:cca25e80 r4:cbabe3c0 r3:00008124 + [] (pid_revalidate+0x0/0x178) from [] (lookup_fast+0x35c/0x43y4) + r9:c6429efc r8:00000101 r7:c079d940 r6:c6429e90 r5:c6429ed8 r4:c83c4148 + [] (lookup_fast+0x0/0x434) from [] (do_last.isra.24+0x1c0/0x1108) + [] (do_last.isra.24+0x0/0x1108) from [] (path_openat.isra.25+0xf4/0x648) + [] (path_openat.isra.25+0x0/0x648) from [] (do_filp_open+0x3c/0x88) + [] (do_filp_open+0x0/0x88) from [] (do_sys_open+0xf0/0x198) + r7:00000001 r6:c0ea2180 r5:0000000b r4:00000000 + [] (do_sys_open+0x0/0x198) from [] (SyS_open+0x30/0x34) + [] (SyS_open+0x0/0x34) from [] (ret_fast_syscall+0x0/0x48) + Read of size 4 by thread T834: + Memory state around the buggy address: + c4635380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + c4635400: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc + c4635480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + c4635500: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc + c4635580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + >c4635600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + ^ + c4635680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb + c4635700: 00 00 00 00 04 fc fc fc fc fc fc fc fc fc fc fc + c4635780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + c4635800: 00 00 00 00 00 00 04 fc fc fc fc fc fc fc fc fc + c4635880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc + ================================================================== + +Signed-off-by: Andrey Ryabinin +Cc: +--- + security/smack/smack.h | 10 ++++++++++ + security/smack/smack_lsm.c | 24 +++++++++++++----------- + 2 files changed, 23 insertions(+), 11 deletions(-) + +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 7629eae..67ccb7b 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -299,6 +299,16 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) + return tsp->smk_task; + } + ++static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) ++{ ++ struct smack_known *skp; ++ ++ rcu_read_lock(); ++ skp = smk_of_task(__task_cred(t)->security); ++ rcu_read_unlock(); ++ return skp; ++} ++ + /* + * Present a pointer to the forked smack label entry in an task blob. + */ +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 12eb355..05ffb24 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -43,8 +43,6 @@ + #include + #include "smack.h" + +-#define task_security(task) (task_cred_xxx((task), security)) +- + #define TRANS_TRUE "TRUE" + #define TRANS_TRUE_SIZE 4 + +@@ -123,7 +121,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp, + static int smk_bu_task(struct task_struct *otp, int mode, int rc) + { + struct task_smack *tsp = current_security(); +- struct task_smack *otsp = task_security(otp); ++ struct smack_known *smk_task = smk_of_task_struct(otp); + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) +@@ -131,7 +129,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s to %s\n", +- tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, ++ tsp->smk_task->smk_known, smk_task->smk_known, acc, + current->comm, otp->comm); + return 0; + } +@@ -352,7 +350,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, + saip = &ad; + } + +- tsp = task_security(tracer); ++ rcu_read_lock(); ++ tsp = __task_cred(tracer)->security; + tracer_known = smk_of_task(tsp); + + if ((mode & PTRACE_MODE_ATTACH) && +@@ -372,11 +371,14 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, + tracee_known->smk_known, + 0, rc, saip); + ++ rcu_read_unlock(); + return rc; + } + + /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ + rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); ++ ++ rcu_read_unlock(); + return rc; + } + +@@ -403,7 +405,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) + if (rc != 0) + return rc; + +- skp = smk_of_task(task_security(ctp)); ++ skp = smk_of_task_struct(ctp); + + rc = smk_ptrace_rule_check(current, skp, mode, __func__); + return rc; +@@ -1831,7 +1833,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access, + const char *caller) + { + struct smk_audit_info ad; +- struct smack_known *skp = smk_of_task(task_security(p)); ++ struct smack_known *skp = smk_of_task_struct(p); + int rc; + + smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); +@@ -1884,7 +1886,7 @@ static int smack_task_getsid(struct task_struct *p) + */ + static void smack_task_getsecid(struct task_struct *p, u32 *secid) + { +- struct smack_known *skp = smk_of_task(task_security(p)); ++ struct smack_known *skp = smk_of_task_struct(p); + + *secid = skp->smk_secid; + } +@@ -1991,7 +1993,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, + { + struct smk_audit_info ad; + struct smack_known *skp; +- struct smack_known *tkp = smk_of_task(task_security(p)); ++ struct smack_known *tkp = smk_of_task_struct(p); + int rc; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); +@@ -2045,7 +2047,7 @@ static int smack_task_wait(struct task_struct *p) + static void smack_task_to_inode(struct task_struct *p, struct inode *inode) + { + struct inode_smack *isp = inode->i_security; +- struct smack_known *skp = smk_of_task(task_security(p)); ++ struct smack_known *skp = smk_of_task_struct(p); + + isp->smk_inode = skp; + } +@@ -3227,7 +3229,7 @@ unlockandout: + */ + static int smack_getprocattr(struct task_struct *p, char *name, char **value) + { +- struct smack_known *skp = smk_of_task(task_security(p)); ++ struct smack_known *skp = smk_of_task_struct(p); + char *cp; + int slen; + +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0053-Smack-Repair-netfilter-dependency.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0053-Smack-Repair-netfilter-dependency.patch new file mode 100644 index 0000000..3e2a081 --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0053-Smack-Repair-netfilter-dependency.patch @@ -0,0 +1,39 @@ +From 31bb2085e178585b3c04b46da686429bf916b39c Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Fri, 23 Jan 2015 09:31:01 -0800 +Subject: [PATCH 53/54] Smack: Repair netfilter dependency +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On 1/23/2015 8:20 AM, Jim Davis wrote: +> Building with the attached random configuration file, +> +> security/smack/smack_netfilter.c: In function ‘smack_ipv4_output’: +> security/smack/smack_netfilter.c:55:6: error: ‘struct sk_buff’ has no +> member named ‘secmark’ +> skb->secmark = skp->smk_secid; +> ^ +> make[2]: *** [security/smack/smack_netfilter.o] Error 1 + +The existing Makefile used the wrong configuration option to +determine if smack_netfilter should be built. This sets it right. + +Signed-off-by: Casey Schaufler +--- + security/smack/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/smack/Makefile b/security/smack/Makefile +index 616cf93..ee2ebd5 100644 +--- a/security/smack/Makefile ++++ b/security/smack/Makefile +@@ -5,4 +5,4 @@ + obj-$(CONFIG_SECURITY_SMACK) := smack.o + + smack-y := smack_lsm.o smack_access.o smackfs.o +-smack-$(CONFIG_NETFILTER) += smack_netfilter.o ++smack-$(CONFIG_SECURITY_SMACK_NETFILTER) += smack_netfilter.o +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0054-Smack-secmark-connections.patch b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0054-Smack-secmark-connections.patch new file mode 100644 index 0000000..e64ff9e --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/0054-Smack-secmark-connections.patch @@ -0,0 +1,50 @@ +From 6a5bed53d2a016b6dfe09abcaabd0278f06838f4 Mon Sep 17 00:00:00 2001 +From: Casey Schaufler +Date: Wed, 11 Feb 2015 12:52:32 -0800 +Subject: [PATCH 54/54] Smack: secmark connections + +If the secmark is available us it on connection as +well as packet delivery. + +Signed-off-by: Casey Schaufler +--- + security/smack/smack_lsm.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 05ffb24..895fe5c 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3819,6 +3819,18 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + } + #endif /* CONFIG_IPV6 */ + ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++ /* ++ * If there is a secmark use it rather than the CIPSO label. ++ * If there is no secmark fall back to CIPSO. ++ * The secmark is assumed to reflect policy better. ++ */ ++ if (skb && skb->secmark != 0) { ++ skp = smack_from_secid(skb->secmark); ++ goto access_check; ++ } ++#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ ++ + netlbl_secattr_init(&secattr); + rc = netlbl_skbuff_getattr(skb, family, &secattr); + if (rc == 0) +@@ -3827,6 +3839,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, + skp = &smack_known_huh; + netlbl_secattr_destroy(&secattr); + ++#ifdef CONFIG_SECURITY_SMACK_NETFILTER ++access_check: ++#endif ++ + #ifdef CONFIG_AUDIT + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + ad.a.u.net->family = family; +-- +2.1.4 + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README new file mode 100644 index 0000000..44216cf --- /dev/null +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas/smack/README @@ -0,0 +1,153 @@ +Patches in this directory were generated on top of the kernel + + git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas-backport.git + +branch + + bsp/v3.10.31-ltsi/rcar-gen2-1.9.2 + +This patches are subdivided in 3 sets. + +Set 1: from 3.10-rc1 to 3.14 + + 0001-Smack-Local-IPv6-port-based-controls.patch + 0002-Smack-Improve-access-check-performance.patch + 0003-Smack-Add-smkfstransmute-mount-option.patch + 0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch + 0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch + 0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch + 0007-xattr-Constify-name-member-of-struct-xattr.patch + 0008-security-smack-fix-memleak-in-smk_write_rules_list.patch + 0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch + 0010-Smack-network-label-match-fix.patch + 0011-Smack-IPv6-casting-error-fix-for-3.11.patch + 0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch + 0013-Smack-Implement-lock-security-mode.patch + 0014-Smack-Ptrace-access-check-mode.patch + 0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch + 0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch + 0017-Smack-Make-the-syslog-control-configurable.patch + 0018-Smack-change-rule-cap-check.patch + 0019-Smack-Rationalize-mount-restrictions.patch + 0020-Smack-File-receive-audit-correction.patch + 0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch + + +Set 2: from 3.14 to 3.19 + + 0022-smack-fix-key-permission-verification.patch + 0023-Minor-improvement-of-smack_sb_kern_mount.patch + 0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch + 0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch + 0026-Smack-adds-smackfs-ptrace-interface.patch + 0027-bugfix-patch-for-SMACK.patch + 0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch + 0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch + 0030-Smack-bidirectional-UDS-connect-check.patch + 0031-Smack-Verify-read-access-on-file-open-v3.patch + 0032-Smack-Label-cgroup-files-for-systemd.patch + 0033-Warning-in-scanf-string-typing.patch + 0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch + 0035-Smack-handle-zero-length-security-labels-without-pan.patch + 0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch + 0037-Smack-Fix-setting-label-on-successful-file-open.patch + 0038-Smack-Bring-up-access-mode.patch + 0039-Small-fixes-in-comments-describing-function-paramete.patch + 0040-Fix-a-bidirectional-UDS-connect-check-typo.patch + 0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch + 0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch + 0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch + 0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch + +Set 3: from 3.19 to 4.0 + + 0045-smack-miscellaneous-small-fixes-in-function-comments.patch + 0046-smack-fix-logic-in-smack_inode_init_security-functio.patch + 0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch + 0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch + 0049-Smack-Rework-file-hooks.patch + 0050-Smack-secmark-support-for-netfilter.patch + 0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch + 0052-smack-fix-possible-use-after-frees-in-task_security-.patch + 0053-Smack-Repair-netfilter-dependency.patch + 0054-Smack-secmark-connections.patch + +Some rewritting occured to avoid to take the commits below that are +affecting smack codes without being important for smack. + + f589594 KEYS: Move the flags representing required permission to linux/key.h + 41c3bd2 netlabel: fix a problem when setting bits below the previously lowest bit + 4b8feff netlabel: fix the horribly broken catmap functions + 4fbe63d netlabel: shorter names for the NetLabel catmap funcs/structs + e0b93ed security: make security_file_set_fowner, f_setown and __f_setown void return + a455589 assorted conversions to %p[dD] + +Some caution has to be taken about evolution of netlabel that is not +integrated. + +Here is the short log of the commit integrated (not the one prefixed +with sharp). + + c673944 Smack: Local IPv6 port based controls + 2f823ff Smack: Improve access check performance + e830b39 Smack: Add smkfstransmute mount option + 8cd77a0 Smack: Fix possible NULL pointer dereference at smk_netlbl_mls() + 0fcfee6 Smack: Fix the bug smackcipso can't set CIPSO correctly + 746df9b Security: Add Hook to test if the particular xattr is part of a MAC model. + 9548906 xattr: Constify ->name member of "struct xattr". + 470043b security: smack: fix memleak in smk_write_rules_list() + 4d7cf4a security: smack: add a hash table to quicken smk_find_entry() + 677264e Smack: network label match fix + 6ea0624 Smack: IPv6 casting error fix for 3.11 + 10289b0 Smack: parse multiple rules per write to load2, up to PAGE_SIZE-1 bytes + c0ab6e5 Smack: Implement lock security mode + b5dfd80 Smack: Ptrace access check mode + 398ce07 smack: fix: allow either entry be missing on access/access2 check (v2) + 19760ad Smack: Prevent the * and @ labels from being used in SMACK64EXEC + 00f84f3 Smack: Make the syslog control configurable + 4afde48 Smack: change rule cap check + 24ea1b6 Smack: Rationalize mount restrictions + 4482a44 Smack: File receive audit correction + 4eb0f4a smack: call WARN_ONCE() instead of calling audit_log_start() + # f589594 KEYS: Move the flags representing required permission to linux/key.h + fffea21 smack: fix key permission verifgit checkout ication + 55dfc5d Minor improvement of 'smack_sb_kern_mount' + 959e6c7 Smack: fix the subject/object order in smack_ptrace_traceme() + 5663884 Smack: unify all ptrace accesses in the smack + 6686781 Smack: adds smackfs/ptrace interface + 5e9ab59 bugfix patch for SMACK + 9598f4c SMACK: Fix handling value==NULL in post setxattr + f59bdfb Smack: Correctly remove SMACK64TRANSMUTE attribute + 54e70ec Smack: bidirectional UDS connect check + a6834c0 Smack: Verify read access on file open - v3 + 36ea735 Smack: Label cgroup files for systemd + ec554fa Warning in scanf string typing + # 41c3bd2 netlabel: fix a problem when setting bits below the previously lowest bit + # 4b8feff netlabel: fix the horribly broken catmap functions + # 4fbe63d netlabel: shorter names for the NetLabel catmap funcs/structs + fd5c9d2 Smack: fix behavior of smack_inode_listsecurity + b862e56 Smack: handle zero-length security labels without panic + da1b635 Smack: remove unneeded NULL-termination from securtity label + d83d2c2 Smack: Fix setting label on successful file open + d166c80 Smack: Bring-up access mode + e95ef49 Small fixes in comments describing function parameters + d0175790 Fix a bidirectional UDS connect check typo + 21c7eae Make Smack operate on smack_known struct where it still used char* + # e0b93ed security: make security_file_set_fowner, f_setown and __f_setown void return + 6c892df Smack: Lock mode for the floor and hat labels + 1a5b472 Security: smack: replace kzalloc with kmem_cache for inode_smack + # a455589 assorted conversions to %p[dD] + 5c1b662 security: smack: fix out-of-bounds access in smk_parse_smack() + 1a28979 smack: miscellaneous small fixes in function comments + 68390cc smack: fix logic in smack_inode_init_security function + 1d8c232 smack: introduce a special case for tmpfs in smack_d_instantiate() + 96be7b5 smack: Fix a bidirectional UDS connect check typo + 5e7270a Smack: Rework file hooks + 69f287a Smack: secmark support for netfilter + 138a868 smack: Add missing logging in bidirectional UDS connect check + 6d1cff2 smack: fix possible use after frees in task_security() callers + 82b0b2c Smack: Repair netfilter dependency + 7f368ad Smack: secmark connections + # 8802565 Smack: Use d_is_positive() rather than testing dentry->d_inode + + diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas_3.10.bb b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas_3.10.bb index b287f3f..db606e3 100644 --- a/meta-rcar-gen2/recipes-kernel/linux/linux-renesas_3.10.bb +++ b/meta-rcar-gen2/recipes-kernel/linux/linux-renesas_3.10.bb @@ -71,6 +71,75 @@ SRC_URI_append_silk = " \ file://0021-drm-rcar-du-r8a7794-disable-interlace-mode.patch \ " +# smack patches are applied if DISTRO_FEATURES has "smack" +# smack patches from 3.10-rc1 to 3.14 +SRC_URI_append_smack = " \ + file://smack/0001-Smack-Local-IPv6-port-based-controls.patch \ + file://smack/0002-Smack-Improve-access-check-performance.patch \ + file://smack/0003-Smack-Add-smkfstransmute-mount-option.patch \ + file://smack/0004-Smack-Fix-possible-NULL-pointer-dereference-at-smk_n.patch \ + file://smack/0005-Smack-Fix-the-bug-smackcipso-can-t-set-CIPSO-correct.patch \ + file://smack/0006-Security-Add-Hook-to-test-if-the-particular-xattr-is.patch \ + file://smack/0007-xattr-Constify-name-member-of-struct-xattr.patch \ + file://smack/0008-security-smack-fix-memleak-in-smk_write_rules_list.patch \ + file://smack/0009-security-smack-add-a-hash-table-to-quicken-smk_find_.patch \ + file://smack/0010-Smack-network-label-match-fix.patch \ + file://smack/0011-Smack-IPv6-casting-error-fix-for-3.11.patch \ + file://smack/0012-Smack-parse-multiple-rules-per-write-to-load2-up-to-.patch \ + file://smack/0013-Smack-Implement-lock-security-mode.patch \ + file://smack/0014-Smack-Ptrace-access-check-mode.patch \ + file://smack/0015-smack-fix-allow-either-entry-be-missing-on-access-ac.patch \ + file://smack/0016-Smack-Prevent-the-and-labels-from-being-used-in-SMAC.patch \ + file://smack/0017-Smack-Make-the-syslog-control-configurable.patch \ + file://smack/0018-Smack-change-rule-cap-check.patch \ + file://smack/0019-Smack-Rationalize-mount-restrictions.patch \ + file://smack/0020-Smack-File-receive-audit-correction.patch \ + file://smack/0021-smack-call-WARN_ONCE-instead-of-calling-audit_log_st.patch \ +" + +# smack patches are applied if DISTRO_FEATURES has "smack" +# smack patches from 3.14 to 3.19 +SRC_URI_append_smack = " \ + file://smack/0022-smack-fix-key-permission-verification.patch \ + file://smack/0023-Minor-improvement-of-smack_sb_kern_mount.patch \ + file://smack/0024-Smack-fix-the-subject-object-order-in-smack_ptrace_t.patch \ + file://smack/0025-Smack-unify-all-ptrace-accesses-in-the-smack.patch \ + file://smack/0026-Smack-adds-smackfs-ptrace-interface.patch \ + file://smack/0027-bugfix-patch-for-SMACK.patch \ + file://smack/0028-SMACK-Fix-handling-value-NULL-in-post-setxattr.patch \ + file://smack/0029-Smack-Correctly-remove-SMACK64TRANSMUTE-attribute.patch \ + file://smack/0030-Smack-bidirectional-UDS-connect-check.patch \ + file://smack/0031-Smack-Verify-read-access-on-file-open-v3.patch \ + file://smack/0032-Smack-Label-cgroup-files-for-systemd.patch \ + file://smack/0033-Warning-in-scanf-string-typing.patch \ + file://smack/0034-Smack-fix-behavior-of-smack_inode_listsecurity.patch \ + file://smack/0035-Smack-handle-zero-length-security-labels-without-pan.patch \ + file://smack/0036-Smack-remove-unneeded-NULL-termination-from-securtit.patch \ + file://smack/0037-Smack-Fix-setting-label-on-successful-file-open.patch \ + file://smack/0038-Smack-Bring-up-access-mode.patch \ + file://smack/0039-Small-fixes-in-comments-describing-function-paramete.patch \ + file://smack/0040-Fix-a-bidirectional-UDS-connect-check-typo.patch \ + file://smack/0041-Make-Smack-operate-on-smack_known-struct-where-it-st.patch \ + file://smack/0042-Smack-Lock-mode-for-the-floor-and-hat-labels.patch \ + file://smack/0043-Security-smack-replace-kzalloc-with-kmem_cache-for-i.patch \ + file://smack/0044-security-smack-fix-out-of-bounds-access-in-smk_parse.patch \ +" + +# smack patches are applied if DISTRO_FEATURES has "smack" +# smack patches from 3.19 to 4.0 +SRC_URI_append_smack = " \ + file://smack/0045-smack-miscellaneous-small-fixes-in-function-comments.patch \ + file://smack/0046-smack-fix-logic-in-smack_inode_init_security-functio.patch \ + file://smack/0047-smack-introduce-a-special-case-for-tmpfs-in-smack_d_.patch \ + file://smack/0048-smack-Fix-a-bidirectional-UDS-connect-check-typo.patch \ + file://smack/0049-Smack-Rework-file-hooks.patch \ + file://smack/0050-Smack-secmark-support-for-netfilter.patch \ + file://smack/0051-smack-Add-missing-logging-in-bidirectional-UDS-conne.patch \ + file://smack/0052-smack-fix-possible-use-after-frees-in-task_security-.patch \ + file://smack/0053-Smack-Repair-netfilter-dependency.patch \ + file://smack/0054-Smack-secmark-connections.patch \ +" + S = "${WORKDIR}/git" KERNEL_DEFCONFIG = "shmobile_defconfig" diff --git a/meta-rcar-gen2/recipes-kernel/linux/linux.inc b/meta-rcar-gen2/recipes-kernel/linux/linux.inc index 68ab620..b4b8598 100644 --- a/meta-rcar-gen2/recipes-kernel/linux/linux.inc +++ b/meta-rcar-gen2/recipes-kernel/linux/linux.inc @@ -166,6 +166,22 @@ do_configure_append_porter() { yes '' | oe_runmake oldconfig } +do_configure_append_smack() { + # Enable Smack + kernel_configure_variable IP_NF_SECURITY m + kernel_configure_variable IP6_NF_SECURITY m + kernel_configure_variable EXT2_FS_SECURITY y + kernel_configure_variable EXT3_FS_SECURITY y + kernel_configure_variable EXT4_FS_SECURITY y + kernel_configure_variable SECURITY y + kernel_configure_variable SECURITY_SMACK y + kernel_configure_variable TMPFS_XATTR y + + kernel_configure_variable DEFAULT_SECURITY "smack" + kernel_configure_variable DEFAULT_SECURITY_SMACK y + yes '' | oe_runmake oldconfig +} + # Automatically depend on lzop-native if CONFIG_KERNEL_LZO is enabled python () { try: -- cgit 1.2.3-korg