|
23 | 23 | #include <linux/sysctl.h> |
24 | 24 | #include <linux/audit.h> |
25 | 25 | #include <linux/user_namespace.h> |
| 26 | +#include <linux/netfilter_ipv4.h> |
| 27 | +#include <linux/netfilter_ipv6.h> |
26 | 28 | #include <net/sock.h> |
27 | 29 |
|
28 | 30 | #include "include/apparmor.h" |
@@ -1030,7 +1032,13 @@ static int apparmor_socket_shutdown(struct socket *sock, int how) |
1030 | 1032 | */ |
1031 | 1033 | static 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 | 1134 | ctx->label = aa_get_current_label(); |
1127 | 1135 | } |
1128 | 1136 |
|
| 1137 | +static 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 | + |
1129 | 1149 | static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { |
1130 | 1150 | LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), |
1131 | 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 | 1203 | LSM_HOOK_INIT(socket_getpeersec_dgram, |
1184 | 1204 | apparmor_socket_getpeersec_dgram), |
1185 | 1205 | LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), |
| 1206 | + LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request), |
1186 | 1207 |
|
1187 | 1208 | LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), |
1188 | 1209 | LSM_HOOK_INIT(cred_free, apparmor_cred_free), |
@@ -1538,6 +1559,95 @@ static inline int apparmor_init_sysctl(void) |
1538 | 1559 | } |
1539 | 1560 | #endif /* CONFIG_SYSCTL */ |
1540 | 1561 |
|
| 1562 | +static 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 | + |
| 1585 | +static 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 | + |
| 1592 | +static 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 | + |
| 1599 | +static 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 | + |
| 1616 | +static 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 | + |
| 1625 | +static 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 | + |
| 1631 | +static struct pernet_operations apparmor_net_ops = { |
| 1632 | + .init = apparmor_nf_register, |
| 1633 | + .exit = apparmor_nf_unregister, |
| 1634 | +}; |
| 1635 | + |
| 1636 | +static 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 | + |
1541 | 1651 | static int __init apparmor_init(void) |
1542 | 1652 | { |
1543 | 1653 | int error; |
|
0 commit comments