aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/apparmor/lsm.c112
-rw-r--r--security/apparmor/net.c66
2 files changed, 177 insertions, 1 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index f09fea0b4db7..2c842f24821b 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -23,6 +23,8 @@
23#include <linux/sysctl.h> 23#include <linux/sysctl.h>
24#include <linux/audit.h> 24#include <linux/audit.h>
25#include <linux/user_namespace.h> 25#include <linux/user_namespace.h>
26#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h>
26#include <net/sock.h> 28#include <net/sock.h>
27 29
28#include "include/apparmor.h" 30#include "include/apparmor.h"
@@ -1030,7 +1032,13 @@ static int apparmor_socket_shutdown(struct socket *sock, int how)
1030 */ 1032 */
1031static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 1033static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
1032{ 1034{
1033 return 0; 1035 struct aa_sk_ctx *ctx = SK_CTX(sk);
1036
1037 if (!skb->secmark)
1038 return 0;
1039
1040 return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE,
1041 skb->secmark, sk);
1034} 1042}
1035 1043
1036 1044
@@ -1126,6 +1134,18 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent)
1126 ctx->label = aa_get_current_label(); 1134 ctx->label = aa_get_current_label();
1127} 1135}
1128 1136
1137static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb,
1138 struct request_sock *req)
1139{
1140 struct aa_sk_ctx *ctx = SK_CTX(sk);
1141
1142 if (!skb->secmark)
1143 return 0;
1144
1145 return apparmor_secmark_check(ctx->label, OP_CONNECT, AA_MAY_CONNECT,
1146 skb->secmark, sk);
1147}
1148
1129static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { 1149static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1130 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), 1150 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check),
1131 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), 1151 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme),
@@ -1183,6 +1203,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
1183 LSM_HOOK_INIT(socket_getpeersec_dgram, 1203 LSM_HOOK_INIT(socket_getpeersec_dgram,
1184 apparmor_socket_getpeersec_dgram), 1204 apparmor_socket_getpeersec_dgram),
1185 LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), 1205 LSM_HOOK_INIT(sock_graft, apparmor_sock_graft),
1206 LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request),
1186 1207
1187 LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), 1208 LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank),
1188 LSM_HOOK_INIT(cred_free, apparmor_cred_free), 1209 LSM_HOOK_INIT(cred_free, apparmor_cred_free),
@@ -1538,6 +1559,95 @@ static inline int apparmor_init_sysctl(void)
1538} 1559}
1539#endif /* CONFIG_SYSCTL */ 1560#endif /* CONFIG_SYSCTL */
1540 1561
1562static unsigned int apparmor_ip_postroute(void *priv,
1563 struct sk_buff *skb,
1564 const struct nf_hook_state *state)
1565{
1566 struct aa_sk_ctx *ctx;
1567 struct sock *sk;
1568
1569 if (!skb->secmark)
1570 return NF_ACCEPT;
1571
1572 sk = skb_to_full_sk(skb);
1573 if (sk == NULL)
1574 return NF_ACCEPT;
1575
1576 ctx = SK_CTX(sk);
1577 if (!apparmor_secmark_check(ctx->label, OP_SENDMSG, AA_MAY_SEND,
1578 skb->secmark, sk))
1579 return NF_ACCEPT;
1580
1581 return NF_DROP_ERR(-ECONNREFUSED);
1582
1583}
1584
1585static unsigned int apparmor_ipv4_postroute(void *priv,
1586 struct sk_buff *skb,
1587 const struct nf_hook_state *state)
1588{
1589 return apparmor_ip_postroute(priv, skb, state);
1590}
1591
1592static unsigned int apparmor_ipv6_postroute(void *priv,
1593 struct sk_buff *skb,
1594 const struct nf_hook_state *state)
1595{
1596 return apparmor_ip_postroute(priv, skb, state);
1597}
1598
1599static const struct nf_hook_ops apparmor_nf_ops[] = {
1600 {
1601 .hook = apparmor_ipv4_postroute,
1602 .pf = NFPROTO_IPV4,
1603 .hooknum = NF_INET_POST_ROUTING,
1604 .priority = NF_IP_PRI_SELINUX_FIRST,
1605 },
1606#if IS_ENABLED(CONFIG_IPV6)
1607 {
1608 .hook = apparmor_ipv6_postroute,
1609 .pf = NFPROTO_IPV6,
1610 .hooknum = NF_INET_POST_ROUTING,
1611 .priority = NF_IP6_PRI_SELINUX_FIRST,
1612 },
1613#endif
1614};
1615
1616static int __net_init apparmor_nf_register(struct net *net)
1617{
1618 int ret;
1619
1620 ret = nf_register_net_hooks(net, apparmor_nf_ops,
1621 ARRAY_SIZE(apparmor_nf_ops));
1622 return ret;
1623}
1624
1625static void __net_exit apparmor_nf_unregister(struct net *net)
1626{
1627 nf_unregister_net_hooks(net, apparmor_nf_ops,
1628 ARRAY_SIZE(apparmor_nf_ops));
1629}
1630
1631static struct pernet_operations apparmor_net_ops = {
1632 .init = apparmor_nf_register,
1633 .exit = apparmor_nf_unregister,
1634};
1635
1636static int __init apparmor_nf_ip_init(void)
1637{
1638 int err;
1639
1640 if (!apparmor_enabled)
1641 return 0;
1642
1643 err = register_pernet_subsys(&apparmor_net_ops);
1644 if (err)
1645 panic("Apparmor: register_pernet_subsys: error %d\n", err);
1646
1647 return 0;
1648}
1649__initcall(apparmor_nf_ip_init);
1650
1541static int __init apparmor_init(void) 1651static int __init apparmor_init(void)
1542{ 1652{
1543 int error; 1653 int error;
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index d5d72dd1ca1f..f9a678ce994f 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -18,6 +18,7 @@
18#include "include/label.h" 18#include "include/label.h"
19#include "include/net.h" 19#include "include/net.h"
20#include "include/policy.h" 20#include "include/policy.h"
21#include "include/secid.h"
21 22
22#include "net_names.h" 23#include "net_names.h"
23 24
@@ -188,3 +189,68 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
188 189
189 return aa_label_sk_perm(label, op, request, sock->sk); 190 return aa_label_sk_perm(label, op, request, sock->sk);
190} 191}
192
193static int apparmor_secmark_init(struct aa_secmark *secmark)
194{
195 struct aa_label *label;
196
197 if (secmark->label[0] == '*') {
198 secmark->secid = AA_SECID_WILDCARD;
199 return 0;
200 }
201
202 label = aa_label_strn_parse(&root_ns->unconfined->label,
203 secmark->label, strlen(secmark->label),
204 GFP_ATOMIC, false, false);
205
206 if (IS_ERR(label))
207 return PTR_ERR(label);
208
209 secmark->secid = label->secid;
210
211 return 0;
212}
213
214static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
215 struct common_audit_data *sa, struct sock *sk)
216{
217 int i, ret;
218 struct aa_perms perms = { };
219
220 if (profile->secmark_count == 0)
221 return 0;
222
223 for (i = 0; i < profile->secmark_count; i++) {
224 if (!profile->secmark[i].secid) {
225 ret = apparmor_secmark_init(&profile->secmark[i]);
226 if (ret)
227 return ret;
228 }
229
230 if (profile->secmark[i].secid == secid ||
231 profile->secmark[i].secid == AA_SECID_WILDCARD) {
232 if (profile->