lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  8 Feb 2016 21:12:58 +0000
From:	Daniel Stone <daniels@...labora.com>
To:	linux-kernel@...r.kernel.org
Cc:	Russell King <rmk+kernel@....linux.org.uk>,
	Thierry Reding <treding@...dia.com>,
	Laurent Pinchart <laurent.pinchart@...asonboard.com>
Subject: [PATCH] component: remove device from master match list on failed add

Calling component_add() may result in the completion of a set of
devices, which will try to bring up a master. In bringing the master
up, we populate its match array with the current set of children.

If binding any of the devices fails, component_add() itself will fail,
free the struct component entry, and return to the caller. The
now-freed entry is never removed from the master's match array, and
will later be used in a futile attempt to bind to freed memory.

Bring component_add's behaviour on failure to bring up a master into
line with component_del by removing the (to-be-freed) component from
the master's match array.

The specific case which broke was:
  - rockchip_drm_drv adds a component master
  - dwhdmi_rockchip adds a child component in probe (master incomplete)
  - rockchip_drm_vop adds two children in probe, which completes the
    set
  - inside component_add, we try to bring up the master, having
    populated the master's match array, and fail with EPROBE_DEFER from
    dwhdmi_rockchip; we delete the putative component
  - rockchip_drm_vop's probe fails and returns EPROBE_DEFER
  - we later re-probe rockchip_drm_vop and add the component; the
    master is complete, so we attempt to bring it up again
  - walking the match array, we find the previous child, whose master
    pointer doesn't match (as it has been freed in the meantime)
  - rockchip_drm_vop probe fails, and will never be attempted again

Fixes: ffc30b74fd6d01588bd3fdebc3b1acc0857e6fc8
Signed-off-by: Daniel Stone <daniels@...labora.com>
Cc: Russell King <rmk+kernel@....linux.org.uk>
Cc: Thierry Reding <treding@...dia.com>
Cc: Laurent Pinchart <laurent.pinchart@...asonboard.com>
---
 drivers/base/component.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/base/component.c b/drivers/base/component.c
index 2738039..04a1582 100644
--- a/drivers/base/component.c
+++ b/drivers/base/component.c
@@ -491,6 +491,8 @@ int component_add(struct device *dev, const struct component_ops *ops)
 
 	ret = try_to_bring_up_masters(component);
 	if (ret < 0) {
+		if (component->master)
+			remove_component(component->master, component);
 		list_del(&component->node);
 
 		kfree(component);
-- 
2.5.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ