Messages in this thread Patch in this message | | | From | YueHaibing <> | Subject | [PATCH] net: genetlink: Fix memleak in genl_family_rcv_msg_dumpit() | Date | Tue, 2 Jun 2020 14:45:45 +0800 |
| |
dumpit info is freed by cb->done now (genl_lock_done()/ genl_parallel_done()), however if any error occurs before cb->done is called, info and attrs will leak.
unreferenced object 0xffff888119904840 (size 32): comm "syz-executor.0", pid 857, jiffies 4295306979 (age 18.692s) hex dump (first 32 bytes): 60 2d 5a af ff ff ff ff c0 d6 a5 ae ff ff ff ff `-Z............. 00 00 00 00 00 00 00 00 60 b4 25 ac ff ff ff ff ........`.%..... backtrace: [<0000000048573ee1>] kmalloc include/linux/slab.h:555 [inline] [<0000000048573ee1>] genl_dumpit_info_alloc net/netlink/genetlink.c:463 [inline] [<0000000048573ee1>] genl_family_rcv_msg_dumpit net/netlink/genetlink.c:598 [inline] [<0000000048573ee1>] genl_family_rcv_msg net/netlink/genetlink.c:715 [inline] [<0000000048573ee1>] genl_rcv_msg+0x7b7/0xce0 net/netlink/genetlink.c:735 [<000000006d27610a>] netlink_rcv_skb+0x139/0x390 net/netlink/af_netlink.c:2469 [<00000000d643c808>] genl_rcv+0x24/0x40 net/netlink/genetlink.c:746 [<00000000fdec3fc5>] netlink_unicast_kernel net/netlink/af_netlink.c:1303 [inline] [<00000000fdec3fc5>] netlink_unicast+0x4a0/0x6a0 net/netlink/af_netlink.c:1329 [<0000000027eb500d>] netlink_sendmsg+0x793/0xc80 net/netlink/af_netlink.c:1918 [<000000006e6952a8>] sock_sendmsg_nosec net/socket.c:652 [inline] [<000000006e6952a8>] sock_sendmsg+0x139/0x170 net/socket.c:672
Fixes: 1927f41a22a0 ("net: genetlink: introduce dump info struct to be available during dumpit op") Signed-off-by: YueHaibing <yuehaibing@huawei.com> --- net/netlink/genetlink.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 9f357aa22b94..cd719aecb0e2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -548,8 +548,6 @@ static int genl_lock_done(struct netlink_callback *cb) rc = ops->done(cb); genl_unlock(); } - genl_family_rcv_msg_attrs_free(info->family, info->attrs, true); - genl_dumpit_info_free(info); return rc; } @@ -561,8 +559,6 @@ static int genl_parallel_done(struct netlink_callback *cb) if (ops->done) rc = ops->done(cb); - genl_family_rcv_msg_attrs_free(info->family, info->attrs, true); - genl_dumpit_info_free(info); return rc; } @@ -594,7 +590,6 @@ static int genl_family_rcv_msg_dumpit(const struct genl_family *family, return PTR_ERR(attrs); no_attrs: - /* Allocate dumpit info. It is going to be freed by done() callback. */ info = genl_dumpit_info_alloc(); if (!info) { genl_family_rcv_msg_attrs_free(family, attrs, true); @@ -630,6 +625,9 @@ static int genl_family_rcv_msg_dumpit(const struct genl_family *family, err = __netlink_dump_start(net->genl_sock, skb, nlh, &c); } + genl_family_rcv_msg_attrs_free(info->family, info->attrs, true); + genl_dumpit_info_free(info); + return err; } -- 2.20.1
| |