1 | Vulnerability Description: | 1 | When calling netlbl_conn_setattr(), addr->sa_family is used |
---|---|---|---|
2 | to determine the function behavior. If sk is an IPv4 socket, | ||
3 | but the connect function is called with an IPv6 address, | ||
4 | the function calipso_sock_setattr() is triggered. | ||
5 | Inside this function, the following code is executed: | ||
2 | 6 | ||
3 | From Linux Kernel v4.0 to the latest version, | 7 | sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL; |
4 | a type confusion issue exists in the `netlbl_conn_setattr` | ||
5 | function (`net/netlabel/netlabel_kapi.c`) within SELinux, | ||
6 | which can lead to a local DoS attack. | ||
7 | 8 | ||
8 | When calling `netlbl_conn_setattr`, | 9 | Since sk is an IPv4 socket, pinet6 is NULL, leading to a |
9 | `addr->sa_family` is used to determine the function behavior. | 10 | null pointer dereference. |
10 | If `sk` is an IPv4 socket, | ||
11 | but the `connect` function is called with an IPv6 address, | ||
12 | the function `calipso_sock_setattr()` is triggered. | ||
13 | Inside this function, the following code is executed: | ||
14 | 11 | ||
15 | sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL; | 12 | This patch fixes the issue by checking if inet6_sk(sk) |
13 | returns a NULL pointer before accessing pinet6. | ||
16 | 14 | ||
17 | Since `sk` is an IPv4 socket, `pinet6` is `NULL`, | 15 | Fixes: ceba1832b1b2("calipso: Set the calipso socket label to match the secattr.") |
18 | leading to a null pointer dereference and triggering a DoS attack. | ||
19 | |||
20 | <TASK> | ||
21 | calipso_sock_setattr+0x4f/0x80 net/netlabel/netlabel_calipso.c:557 | ||
22 | netlbl_conn_setattr+0x12a/0x390 net/netlabel/netlabel_kapi.c:1152 | ||
23 | selinux_netlbl_socket_connect_helper | ||
24 | selinux_netlbl_socket_connect_locked+0xf5/0x1d0 | ||
25 | selinux_netlbl_socket_connect+0x22/0x40 security/selinux/netlabel.c:611 | ||
26 | selinux_socket_connect+0x60/0x80 security/selinux/hooks.c:4923 | ||
27 | security_socket_connect+0x71/0xb0 security/security.c:2260 | ||
28 | __sys_connect_file+0xa4/0x190 net/socket.c:2007 | ||
29 | __sys_connect+0x145/0x170 net/socket.c:2028 | ||
30 | __do_sys_connect net/socket.c:2038 [inline] | ||
31 | __se_sys_connect net/socket.c:2035 [inline] | ||
32 | __x64_sys_connect+0x6e/0xb0 net/socket.c:2035 | ||
33 | do_syscall_x64 arch/x86/entry/common.c:51 | ||
34 | |||
35 | Affected Versions: | ||
36 | |||
37 | - Linux 4.0 - Latest Linux Kernel version | ||
38 | |||
39 | Reproduction Steps: | ||
40 | |||
41 | Use the `netlabelctl` tool and | ||
42 | run the following commands to trigger the vulnerability: | ||
43 | |||
44 | netlabelctl map del default | ||
45 | netlabelctl cipsov4 add pass doi:8 tags:1 | ||
46 | netlabelctl map add default address:192.168.1.0/24 protocol:cipsov4,8 | ||
47 | netlabelctl calipso add pass doi:7 | ||
48 | netlabelctl map add default address:2001:db8::1/32 protocol:calipso,7 | ||
49 | |||
50 | Then, execute the following PoC code: | ||
51 | |||
52 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); | ||
53 | |||
54 | struct sockaddr_in6 server_addr = {0}; | ||
55 | server_addr.sin6_family = AF_INET6; | ||
56 | server_addr.sin6_port = htons(8080); | ||
57 | |||
58 | const char *ipv6_str = "2001:db8::1"; | ||
59 | inet_pton(AF_INET6, ipv6_str, &server_addr.sin6_addr); | ||
60 | |||
61 | connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)); | ||
62 | |||
63 | Suggested Fix: | ||
64 | |||
65 | When using an IPv4 address on an IPv6 UDP/datagram socket, | ||
66 | the operation will invoke the IPv4 datagram code through | ||
67 | the IPv6 datagram code and execute successfully. | ||
68 | It is necessary to check whether the `pinet6` pointer | ||
69 | returned by `inet6_sk()` is NULL; otherwise, | ||
70 | unexpected issues may occur. | ||
71 | |||
72 | Signed-off-by: Debin Zhu <mowenroot@163.com> | 16 | Signed-off-by: Debin Zhu <mowenroot@163.com> |
73 | Signed-off-by: Bitao Ouyang <1985755126@qq.com> | 17 | Signed-off-by: Bitao Ouyang <1985755126@qq.com> |
18 | Acked-by: Paul Moore <paul@paul-moore.com> | ||
19 | |||
74 | --- | 20 | --- |
75 | net/ipv6/calipso.c | 23 +++++++++++++++++++---- | 21 | net/ipv6/calipso.c | 23 +++++++++++++++++++---- |
76 | 1 file changed, 19 insertions(+), 4 deletions(-) | 22 | 1 file changed, 19 insertions(+), 4 deletions(-) |
77 | 23 | ||
78 | diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c | 24 | diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c |
... | ... | ||
124 | + txopts = txopt_get(pinfo); | 70 | + txopts = txopt_get(pinfo); |
125 | if (!txopts || !txopts->hopopt) | 71 | if (!txopts || !txopts->hopopt) |
126 | goto done; | 72 | goto done; |
127 | 73 | ||
128 | -- | 74 | -- |
129 | mowenroot@163.com | 75 | 2.34.1 | diff view generated by jsdifflib |