Patchwork [v2] Don't double free cfg struct if netlink_init fails

login
register
mail settings
Submitter Pontus Fuchs
Date Nov. 21, 2012, 12:46 p.m.
Message ID <1353501983-25035-1-git-send-email-pontus.fuchs@gmail.com>
Download mbox | patch
Permalink /patch/200679/
State Accepted
Commit fb660a9431f881ea6dbba2967094605ad64398ee
Headers show

Comments

Pontus Fuchs - Nov. 21, 2012, 12:46 p.m.
If netlink_init fails on socket create or bind the cfg struct
provided as parameter is freed by netlink_init. Callers of
netlink_init also frees this struct on their error paths leading
to double free.

Signed-hostap: Pontus Fuchs <pontus.fuchs@gmail.com>
---
V2 - Fix typo in signoff.

 src/drivers/netlink.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Jouni Malinen - Nov. 24, 2012, 2:50 p.m.
On Wed, Nov 21, 2012 at 01:46:23PM +0100, Pontus Fuchs wrote:
> If netlink_init fails on socket create or bind the cfg struct
> provided as parameter is freed by netlink_init. Callers of
> netlink_init also frees this struct on their error paths leading
> to double free.

Thanks! Applied.

> diff --git a/src/drivers/netlink.c b/src/drivers/netlink.c
> @@ -118,6 +117,7 @@ struct netlink_data * netlink_init(struct netlink_config *cfg)
> +	netlink->cfg = cfg;
>  	eloop_register_read_sock(netlink->sock, netlink_receive, netlink,
>  				 NULL);

Though, I reordered these operations since that
eloop_register_read_sock() could actually fail in theory and should that
ever be addressed by returning error here, it is better to avoid hitting
the same double free on the error path case accidentally at that point.

Patch

diff --git a/src/drivers/netlink.c b/src/drivers/netlink.c
index dd662f3..76b3f30 100644
--- a/src/drivers/netlink.c
+++ b/src/drivers/netlink.c
@@ -97,7 +97,6 @@  struct netlink_data * netlink_init(struct netlink_config *cfg)
 	if (netlink == NULL)
 		return NULL;
 
-	netlink->cfg = cfg;
 
 	netlink->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 	if (netlink->sock < 0) {
@@ -118,6 +117,7 @@  struct netlink_data * netlink_init(struct netlink_config *cfg)
 		return NULL;
 	}
 
+	netlink->cfg = cfg;
 	eloop_register_read_sock(netlink->sock, netlink_receive, netlink,
 				 NULL);