diff mbox series

[net,1/3] dpll: fix pin dump crash after module unbind

Message ID 20231108103226.1168500-2-arkadiusz.kubalewski@intel.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series dpll: fix unordered unbind/bind registerer issues | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1314 this patch: 1314
netdev/cc_maintainers fail 1 blamed authors not CCed: davem@davemloft.net; 1 maintainers not CCed: davem@davemloft.net
netdev/build_clang success Errors and warnings before: 1341 this patch: 1341
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1342 this patch: 1342
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 13 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Kubalewski, Arkadiusz Nov. 8, 2023, 10:32 a.m. UTC
Disallow dump of unregistered parent pins, it is possible when parent
pin and dpll device registerer kernel module instance unbinds, and
other kernel module instances of the same dpll device have pins
registered with the parent pin. The user can invoke a pin-dump but as
the parent was unregistered, thus shall not be accessed by the
userspace, prevent that by checking if parent pin is still registered.

Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
---
 drivers/dpll/dpll_netlink.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Przemek Kitszel Nov. 8, 2023, 11:36 a.m. UTC | #1
On 11/8/23 11:32, Arkadiusz Kubalewski wrote:
> Disallow dump of unregistered parent pins, it is possible when parent
> pin and dpll device registerer kernel module instance unbinds, and
> other kernel module instances of the same dpll device have pins
> registered with the parent pin. The user can invoke a pin-dump but as
> the parent was unregistered, thus shall not be accessed by the
> userspace, prevent that by checking if parent pin is still registered.
> 
> Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
> Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> ---
>   drivers/dpll/dpll_netlink.c | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
> index a6dc3997bf5c..93fc6c4b8a78 100644
> --- a/drivers/dpll/dpll_netlink.c
> +++ b/drivers/dpll/dpll_netlink.c
> @@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
>   		void *parent_priv;
>   
>   		ppin = ref->pin;
> +		/*
> +		 * dump parent only if it is registered, thus prevent crash on
> +		 * pin dump called when driver which registered the pin unbinds
> +		 * and different instance registered pin on that parent pin
> +		 */
> +		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
> +			continue;

What if unregister/unbind would happen right [here]?
[here]

>   		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
>   		ret = ops->state_on_pin_get(pin,
>   					    dpll_pin_on_pin_priv(ppin, pin),
Kubalewski, Arkadiusz Nov. 8, 2023, 12:08 p.m. UTC | #2
>From: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>
>Sent: Wednesday, November 8, 2023 12:36 PM
>
>On 11/8/23 11:32, Arkadiusz Kubalewski wrote:
>> Disallow dump of unregistered parent pins, it is possible when parent
>> pin and dpll device registerer kernel module instance unbinds, and
>> other kernel module instances of the same dpll device have pins
>> registered with the parent pin. The user can invoke a pin-dump but as
>> the parent was unregistered, thus shall not be accessed by the
>> userspace, prevent that by checking if parent pin is still registered.
>>
>> Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
>> Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>> ---
>>   drivers/dpll/dpll_netlink.c | 7 +++++++
>>   1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>> index a6dc3997bf5c..93fc6c4b8a78 100644
>> --- a/drivers/dpll/dpll_netlink.c
>> +++ b/drivers/dpll/dpll_netlink.c
>> @@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct
>dpll_pin *pin,
>>   		void *parent_priv;
>>
>>   		ppin = ref->pin;
>> +		/*
>> +		 * dump parent only if it is registered, thus prevent crash on
>> +		 * pin dump called when driver which registered the pin unbinds
>> +		 * and different instance registered pin on that parent pin
>> +		 */
>> +		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
>> +			continue;
>
>What if unregister/unbind would happen right [here]?
>[here]

There is a "global" mutex lock which guards the pin/dpll registration and all
netlink requests. For netlink requests in this case it is acquired in the
dpll_pin_pre_doit(..), while all the dpll subsystem interaction from kernel
modules are guarded in dpll_core.c api functions with the same lock.

So after all this use case is protected, just "higher" in the stack.

Thank you!
Arkadiusz

>
>>   		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
>>   		ret = ops->state_on_pin_get(pin,
>>   					    dpll_pin_on_pin_priv(ppin, pin),
Jiri Pirko Nov. 8, 2023, 3:08 p.m. UTC | #3
Wed, Nov 08, 2023 at 11:32:24AM CET, arkadiusz.kubalewski@intel.com wrote:
>Disallow dump of unregistered parent pins, it is possible when parent
>pin and dpll device registerer kernel module instance unbinds, and
>other kernel module instances of the same dpll device have pins
>registered with the parent pin. The user can invoke a pin-dump but as
>the parent was unregistered, thus shall not be accessed by the
>userspace, prevent that by checking if parent pin is still registered.
>
>Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
>Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>---
> drivers/dpll/dpll_netlink.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
>diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>index a6dc3997bf5c..93fc6c4b8a78 100644
>--- a/drivers/dpll/dpll_netlink.c
>+++ b/drivers/dpll/dpll_netlink.c
>@@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
> 		void *parent_priv;
> 
> 		ppin = ref->pin;
>+		/*
>+		 * dump parent only if it is registered, thus prevent crash on
>+		 * pin dump called when driver which registered the pin unbinds
>+		 * and different instance registered pin on that parent pin

Read this sentence like 10 times, still don't get what you mean.
Shouldn't comments be easy to understand?


>+		 */
>+		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
>+			continue;
> 		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
> 		ret = ops->state_on_pin_get(pin,
> 					    dpll_pin_on_pin_priv(ppin, pin),
>-- 
>2.38.1
>
Kubalewski, Arkadiusz Nov. 9, 2023, 9:49 a.m. UTC | #4
>From: Jiri Pirko <jiri@resnulli.us>
>Sent: Wednesday, November 8, 2023 4:09 PM
>
>Wed, Nov 08, 2023 at 11:32:24AM CET, arkadiusz.kubalewski@intel.com wrote:
>>Disallow dump of unregistered parent pins, it is possible when parent
>>pin and dpll device registerer kernel module instance unbinds, and
>>other kernel module instances of the same dpll device have pins
>>registered with the parent pin. The user can invoke a pin-dump but as
>>the parent was unregistered, thus shall not be accessed by the
>>userspace, prevent that by checking if parent pin is still registered.
>>
>>Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
>>Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>>---
>> drivers/dpll/dpll_netlink.c | 7 +++++++
>> 1 file changed, 7 insertions(+)
>>
>>diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>>index a6dc3997bf5c..93fc6c4b8a78 100644
>>--- a/drivers/dpll/dpll_netlink.c
>>+++ b/drivers/dpll/dpll_netlink.c
>>@@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct
>dpll_pin *pin,
>> 		void *parent_priv;
>>
>> 		ppin = ref->pin;
>>+		/*
>>+		 * dump parent only if it is registered, thus prevent crash on
>>+		 * pin dump called when driver which registered the pin unbinds
>>+		 * and different instance registered pin on that parent pin
>
>Read this sentence like 10 times, still don't get what you mean.
>Shouldn't comments be easy to understand?
>

Hi,

Hmm, wondering isn't it better to remove this comment at all?
If you think it is needed I will rephrase it somehow..

Thank you!
Arkadiusz

>
>>+		 */
>>+		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
>>+			continue;
>> 		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
>> 		ret = ops->state_on_pin_get(pin,
>> 					    dpll_pin_on_pin_priv(ppin, pin),
>>--
>>2.38.1
>>
Jiri Pirko Nov. 9, 2023, 1:18 p.m. UTC | #5
Thu, Nov 09, 2023 at 10:49:49AM CET, arkadiusz.kubalewski@intel.com wrote:
>>From: Jiri Pirko <jiri@resnulli.us>
>>Sent: Wednesday, November 8, 2023 4:09 PM
>>
>>Wed, Nov 08, 2023 at 11:32:24AM CET, arkadiusz.kubalewski@intel.com wrote:
>>>Disallow dump of unregistered parent pins, it is possible when parent
>>>pin and dpll device registerer kernel module instance unbinds, and
>>>other kernel module instances of the same dpll device have pins
>>>registered with the parent pin. The user can invoke a pin-dump but as
>>>the parent was unregistered, thus shall not be accessed by the
>>>userspace, prevent that by checking if parent pin is still registered.
>>>
>>>Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
>>>Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>>>---
>>> drivers/dpll/dpll_netlink.c | 7 +++++++
>>> 1 file changed, 7 insertions(+)
>>>
>>>diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>>>index a6dc3997bf5c..93fc6c4b8a78 100644
>>>--- a/drivers/dpll/dpll_netlink.c
>>>+++ b/drivers/dpll/dpll_netlink.c
>>>@@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg, struct
>>dpll_pin *pin,
>>> 		void *parent_priv;
>>>
>>> 		ppin = ref->pin;
>>>+		/*
>>>+		 * dump parent only if it is registered, thus prevent crash on
>>>+		 * pin dump called when driver which registered the pin unbinds
>>>+		 * and different instance registered pin on that parent pin
>>
>>Read this sentence like 10 times, still don't get what you mean.
>>Shouldn't comments be easy to understand?
>>
>
>Hi,
>
>Hmm, wondering isn't it better to remove this comment at all?
>If you think it is needed I will rephrase it somehow..

I don't know if it is needed as I don't understand it :)
Just remove it.


>
>Thank you!
>Arkadiusz
>
>>
>>>+		 */
>>>+		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
>>>+			continue;
>>> 		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
>>> 		ret = ops->state_on_pin_get(pin,
>>> 					    dpll_pin_on_pin_priv(ppin, pin),
>>>--
>>>2.38.1
>>>
>
Kubalewski, Arkadiusz Nov. 9, 2023, 4:33 p.m. UTC | #6
>From: Jiri Pirko <jiri@resnulli.us>
>Sent: Thursday, November 9, 2023 2:18 PM
>
>Thu, Nov 09, 2023 at 10:49:49AM CET, arkadiusz.kubalewski@intel.com wrote:
>>>From: Jiri Pirko <jiri@resnulli.us>
>>>Sent: Wednesday, November 8, 2023 4:09 PM
>>>
>>>Wed, Nov 08, 2023 at 11:32:24AM CET, arkadiusz.kubalewski@intel.com
>>>wrote:
>>>>Disallow dump of unregistered parent pins, it is possible when parent
>>>>pin and dpll device registerer kernel module instance unbinds, and
>>>>other kernel module instances of the same dpll device have pins
>>>>registered with the parent pin. The user can invoke a pin-dump but as
>>>>the parent was unregistered, thus shall not be accessed by the
>>>>userspace, prevent that by checking if parent pin is still registered.
>>>>
>>>>Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
>>>>Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
>>>>---
>>>> drivers/dpll/dpll_netlink.c | 7 +++++++
>>>> 1 file changed, 7 insertions(+)
>>>>
>>>>diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
>>>>index a6dc3997bf5c..93fc6c4b8a78 100644
>>>>--- a/drivers/dpll/dpll_netlink.c
>>>>+++ b/drivers/dpll/dpll_netlink.c
>>>>@@ -328,6 +328,13 @@ dpll_msg_add_pin_parents(struct sk_buff *msg,
>>>>        struct dpll_pin *pin,
>>>> 		void *parent_priv;
>>>>
>>>> 		ppin = ref->pin;
>>>>+		/*
>>>>+		 * dump parent only if it is registered, thus prevent crash on
>>>>+		 * pin dump called when driver which registered the pin unbinds
>>>>+		 * and different instance registered pin on that parent pin
>>>
>>>Read this sentence like 10 times, still don't get what you mean.
>>>Shouldn't comments be easy to understand?
>>>
>>
>>Hi,
>>
>>Hmm, wondering isn't it better to remove this comment at all?
>>If you think it is needed I will rephrase it somehow..
>
>I don't know if it is needed as I don't understand it :)
>Just remove it.
>

Sure, will do.

Thank you!
Arkadiusz

>
>>
>>Thank you!
>>Arkadiusz
>>
>>>
>>>>+		 */
>>>>+		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
>>>>+			continue;
>>>> 		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
>>>> 		ret = ops->state_on_pin_get(pin,
>>>> 					    dpll_pin_on_pin_priv(ppin, pin),
>>>>--
>>>>2.38.1
>>>>
>>
diff mbox series

Patch

diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index a6dc3997bf5c..93fc6c4b8a78 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -328,6 +328,13 @@  dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
 		void *parent_priv;
 
 		ppin = ref->pin;
+		/*
+		 * dump parent only if it is registered, thus prevent crash on
+		 * pin dump called when driver which registered the pin unbinds
+		 * and different instance registered pin on that parent pin
+		 */
+		if (!xa_get_mark(&dpll_pin_xa, ppin->id, DPLL_REGISTERED))
+			continue;
 		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
 		ret = ops->state_on_pin_get(pin,
 					    dpll_pin_on_pin_priv(ppin, pin),