Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

calipso: fix memory leak in netlbl_calipso_add_pass()

If IPv6 support is disabled at boot (ipv6.disable=1),
the calipso_init() -> netlbl_calipso_ops_register() function isn't called,
and the netlbl_calipso_ops_get() function always returns NULL.
In this case, the netlbl_calipso_add_pass() function allocates memory
for the doi_def variable but doesn't free it with the calipso_doi_free().

BUG: memory leak
unreferenced object 0xffff888011d68180 (size 64):
comm "syz-executor.1", pid 10746, jiffies 4295410986 (age 17.928s)
hex dump (first 32 bytes):
00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<...>] kmalloc include/linux/slab.h:552 [inline]
[<...>] netlbl_calipso_add_pass net/netlabel/netlabel_calipso.c:76 [inline]
[<...>] netlbl_calipso_add+0x22e/0x4f0 net/netlabel/netlabel_calipso.c:111
[<...>] genl_family_rcv_msg_doit+0x22f/0x330 net/netlink/genetlink.c:739
[<...>] genl_family_rcv_msg net/netlink/genetlink.c:783 [inline]
[<...>] genl_rcv_msg+0x341/0x5a0 net/netlink/genetlink.c:800
[<...>] netlink_rcv_skb+0x14d/0x440 net/netlink/af_netlink.c:2515
[<...>] genl_rcv+0x29/0x40 net/netlink/genetlink.c:811
[<...>] netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline]
[<...>] netlink_unicast+0x54b/0x800 net/netlink/af_netlink.c:1339
[<...>] netlink_sendmsg+0x90a/0xdf0 net/netlink/af_netlink.c:1934
[<...>] sock_sendmsg_nosec net/socket.c:651 [inline]
[<...>] sock_sendmsg+0x157/0x190 net/socket.c:671
[<...>] ____sys_sendmsg+0x712/0x870 net/socket.c:2342
[<...>] ___sys_sendmsg+0xf8/0x170 net/socket.c:2396
[<...>] __sys_sendmsg+0xea/0x1b0 net/socket.c:2429
[<...>] do_syscall_64+0x30/0x40 arch/x86/entry/common.c:46
[<...>] entry_SYSCALL_64_after_hwframe+0x61/0xc6

Found by InfoTeCS on behalf of Linux Verification Center
(linuxtesting.org) with Syzkaller

Fixes: cb72d38211ea ("netlabel: Initial support for the CALIPSO netlink protocol.")
Signed-off-by: Gavrilov Ilia <Ilia.Gavrilov@infotecs.ru>
[PM: merged via the LSM tree at Jakub Kicinski request]
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Gavrilov Ilia and committed by
Paul Moore
ec4e9d63 80b4ff1d

+26 -23
+26 -23
net/netlabel/netlabel_calipso.c
··· 54 54 [NLBL_CALIPSO_A_MTYPE] = { .type = NLA_U32 }, 55 55 }; 56 56 57 + static const struct netlbl_calipso_ops *calipso_ops; 58 + 59 + /** 60 + * netlbl_calipso_ops_register - Register the CALIPSO operations 61 + * @ops: ops to register 62 + * 63 + * Description: 64 + * Register the CALIPSO packet engine operations. 65 + * 66 + */ 67 + const struct netlbl_calipso_ops * 68 + netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) 69 + { 70 + return xchg(&calipso_ops, ops); 71 + } 72 + EXPORT_SYMBOL(netlbl_calipso_ops_register); 73 + 74 + static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) 75 + { 76 + return READ_ONCE(calipso_ops); 77 + } 78 + 57 79 /* NetLabel Command Handlers 58 80 */ 59 81 /** ··· 118 96 * 119 97 */ 120 98 static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info) 121 - 122 99 { 123 100 int ret_val = -EINVAL; 124 101 struct netlbl_audit audit_info; 102 + const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get(); 125 103 126 104 if (!info->attrs[NLBL_CALIPSO_A_DOI] || 127 105 !info->attrs[NLBL_CALIPSO_A_MTYPE]) 128 106 return -EINVAL; 107 + 108 + if (!ops) 109 + return -EOPNOTSUPP; 129 110 130 111 netlbl_netlink_auditinfo(&audit_info); 131 112 switch (nla_get_u32(info->attrs[NLBL_CALIPSO_A_MTYPE])) { ··· 386 361 int __init netlbl_calipso_genl_init(void) 387 362 { 388 363 return genl_register_family(&netlbl_calipso_gnl_family); 389 - } 390 - 391 - static const struct netlbl_calipso_ops *calipso_ops; 392 - 393 - /** 394 - * netlbl_calipso_ops_register - Register the CALIPSO operations 395 - * @ops: ops to register 396 - * 397 - * Description: 398 - * Register the CALIPSO packet engine operations. 399 - * 400 - */ 401 - const struct netlbl_calipso_ops * 402 - netlbl_calipso_ops_register(const struct netlbl_calipso_ops *ops) 403 - { 404 - return xchg(&calipso_ops, ops); 405 - } 406 - EXPORT_SYMBOL(netlbl_calipso_ops_register); 407 - 408 - static const struct netlbl_calipso_ops *netlbl_calipso_ops_get(void) 409 - { 410 - return READ_ONCE(calipso_ops); 411 364 } 412 365 413 366 /**