mbox series

[0/4] net: caif: fix 2 memory leaks

Message ID cover.1622737854.git.paskripkin@gmail.com
Headers show
Series net: caif: fix 2 memory leaks | expand

Message

Pavel Skripkin June 3, 2021, 4:37 p.m. UTC
This patch series fix 2 memory leaks in caif
interface.

Syzbot reported memory leak in cfserl_create().
The problem was in cfcnfg_add_phy_layer() function.
This function accepts struct cflayer *link_support and
assign it to corresponting structures, but it can fail
in some cases.

These cases must be handled to prevent leaking allocated
struct cflayer *link_support pointer, because if error accured
before assigning link_support pointer to somewhere, this pointer
must be freed.

Fail log:

[   49.051872][ T7010] caif:cfcnfg_add_phy_layer(): Too many CAIF Link Layers (max 6)
[   49.110236][ T7042] caif:cfcnfg_add_phy_layer(): Too many CAIF Link Layers (max 6)
[   49.134936][ T7045] caif:cfcnfg_add_phy_layer(): Too many CAIF Link Layers (max 6)
[   49.163083][ T7043] caif:cfcnfg_add_phy_layer(): Too many CAIF Link Layers (max 6)
[   55.248950][ T6994] kmemleak: 4 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

int cfcnfg_add_phy_layer(..., struct cflayer *link_support, ...)
{
...
	/* CAIF protocol allow maximum 6 link-layers */
	for (i = 0; i < 7; i++) {
		phyid = (dev->ifindex + i) & 0x7;
		if (phyid == 0)
			continue;
		if (cfcnfg_get_phyinfo_rcu(cnfg, phyid) == NULL)
			goto got_phyid;
	}
	pr_warn("Too many CAIF Link Layers (max 6)\n");
	goto out;
...
	if (link_support != NULL) {
		link_support->id = phyid;
		layer_set_dn(frml, link_support);
		layer_set_up(link_support, frml);
		layer_set_dn(link_support, phy_layer);
		layer_set_up(phy_layer, link_support);
	}
...
}

As you can see, if cfcnfg_add_phy_layer fails before layer_set_*,
link_support becomes leaked.

So, in this series, I made cfcnfg_add_phy_layer() 
return an int and added error handling code to prevent
leaking link_support pointer in caif_device_notify()
and cfusbl_device_notify() functions.

NOTE: this series was tested by syzbot
https://syzkaller.appspot.com/bug?id=62bc71b5fa73349e2e6b6280eca9c9615ddeb585)

Pavel Skripkin (4):
  net: caif: added cfserl_release function
  net: caif: add proper error handling
  net: caif: fix memory leak in caif_device_notify
  net: caif: fix memory leak in cfusbl_device_notify

 include/net/caif/caif_dev.h |  2 +-
 include/net/caif/cfcnfg.h   |  2 +-
 include/net/caif/cfserl.h   |  1 +
 net/caif/caif_dev.c         | 13 +++++++++----
 net/caif/caif_usb.c         | 14 +++++++++++++-
 net/caif/cfcnfg.c           | 16 +++++++++++-----
 net/caif/cfserl.c           |  5 +++++
 7 files changed, 41 insertions(+), 12 deletions(-)

Comments

Pavel Skripkin June 3, 2021, 4:42 p.m. UTC | #1
On Thu,  3 Jun 2021 19:39:11 +0300
Pavel Skripkin <paskripkin@gmail.com> wrote:

> In case of caif_enroll_dev() fail, allocated
> link_support won't be assigned to the corresponding
> structure. So simply free allocated pointer in case
> of error
> 
> Fixes: 7c18d2205ea7 ("caif: Restructure how link caif link layer
> enroll") Cc: stable@vger.kernel.org
> Reported-and-tested-by:
> syzbot+7ec324747ce876a29db6@syzkaller.appspotmail.com Signed-off-by:
> Pavel Skripkin <paskripkin@gmail.com> ---
>  net/caif/caif_dev.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
> index fffbe41440b3..440139706130 100644
> --- a/net/caif/caif_dev.c
> +++ b/net/caif/caif_dev.c
> @@ -370,6 +370,7 @@ static int caif_device_notify(struct
> notifier_block *me, unsigned long what, struct cflayer *layer,
> *link_support; int head_room = 0;
>  	struct caif_device_entry_list *caifdevs;
> +	int res;
>  
>  	cfg = get_cfcnfg(dev_net(dev));
>  	caifdevs = caif_device_list(dev_net(dev));
> @@ -395,8 +396,10 @@ static int caif_device_notify(struct
> notifier_block *me, unsigned long what, break;
>  			}
>  		}
> -		caif_enroll_dev(dev, caifdev, link_support,
> head_room,
> +		res = caif_enroll_dev(dev, caifdev, link_support,
> head_room, &layer, NULL);
> +		if (res)
> +			cfserl_release(link_support);
>  		caifdev->flowctrl = dev_flowctrl;
>  		break;
>  

One thing Im wondering about is should I return this error
from caif_device_notify()? I look forward to hearing your perspective on
this question and patch series :)



With regards,
Pavel Skripkin
patchwork-bot+netdevbpf@kernel.org June 3, 2021, 10:20 p.m. UTC | #2
Hello:

This series was applied to netdev/net.git (refs/heads/master):

On Thu,  3 Jun 2021 19:37:27 +0300 you wrote:
> This patch series fix 2 memory leaks in caif
> interface.
> 
> Syzbot reported memory leak in cfserl_create().
> The problem was in cfcnfg_add_phy_layer() function.
> This function accepts struct cflayer *link_support and
> assign it to corresponting structures, but it can fail
> in some cases.
> 
> [...]

Here is the summary with links:
  - [1/4] net: caif: added cfserl_release function
    https://git.kernel.org/netdev/net/c/bce130e7f392
  - [2/4] net: caif: add proper error handling
    https://git.kernel.org/netdev/net/c/a2805dca5107
  - [3/4] net: caif: fix memory leak in caif_device_notify
    https://git.kernel.org/netdev/net/c/b53558a950a8
  - [4/4] net: caif: fix memory leak in cfusbl_device_notify
    https://git.kernel.org/netdev/net/c/7f5d86669fa4

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html