From: Jacek Anaszewski <jacek.anaszewski@gmail.com>
To: Mukesh Ojha <quic_mojha@quicinc.com>, Pavel Machek <pavel@ucw.cz>,
Lee Jones <lee@kernel.org>
Cc: linux-leds@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] leds: class: Protect brightness_show() with led_cdev->led_access mutex
Date: Sun, 27 Oct 2024 15:20:19 +0100 [thread overview]
Message-ID: <62b09eee-553a-a3d1-e2e0-59dee7289019@gmail.com> (raw)
In-Reply-To: <20241025171128.1226045-1-quic_mojha@quicinc.com>
Hi Mukesh,
On 10/25/24 19:11, Mukesh Ojha wrote:
> There is NULL pointer issue observed if from Process A where hid device
> being added which results in adding a led_cdev addition and later a
> another call to access of led_cdev attribute from Process B can result
> in NULL pointer issue.
>
> Use mutex led_cdev->led_access to protect access to led->cdev and its
> attribute inside brightness_show() and max_brightness_show() and also
> update the comment for mutex that it should be used to protect the led
> class device fields.
>
> Process A Process B
>
> kthread+0x114
> worker_thread+0x244
> process_scheduled_works+0x248
> uhid_device_add_worker+0x24
> hid_add_device+0x120
> device_add+0x268
> bus_probe_device+0x94
> device_initial_probe+0x14
> __device_attach+0xfc
> bus_for_each_drv+0x10c
> __device_attach_driver+0x14c
> driver_probe_device+0x3c
> __driver_probe_device+0xa0
> really_probe+0x190
> hid_device_probe+0x130
> ps_probe+0x990
> ps_led_register+0x94
> devm_led_classdev_register_ext+0x58
> led_classdev_register_ext+0x1f8
> device_create_with_groups+0x48
> device_create_groups_vargs+0xc8
> device_add+0x244
> kobject_uevent+0x14
> kobject_uevent_env[jt]+0x224
> mutex_unlock[jt]+0xc4
> __mutex_unlock_slowpath+0xd4
> wake_up_q+0x70
> try_to_wake_up[jt]+0x48c
> preempt_schedule_common+0x28
> __schedule+0x628
> __switch_to+0x174
> el0t_64_sync+0x1a8/0x1ac
> el0t_64_sync_handler+0x68/0xbc
> el0_svc+0x38/0x68
> do_el0_svc+0x1c/0x28
> el0_svc_common+0x80/0xe0
> invoke_syscall+0x58/0x114
> __arm64_sys_read+0x1c/0x2c
> ksys_read+0x78/0xe8
> vfs_read+0x1e0/0x2c8
> kernfs_fop_read_iter+0x68/0x1b4
> seq_read_iter+0x158/0x4ec
> kernfs_seq_show+0x44/0x54
> sysfs_kf_seq_show+0xb4/0x130
> dev_attr_show+0x38/0x74
> brightness_show+0x20/0x4c
> dualshock4_led_get_brightness+0xc/0x74
>
> [ 3313.874295][ T4013] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060
> [ 3313.874301][ T4013] Mem abort info:
> [ 3313.874303][ T4013] ESR = 0x0000000096000006
> [ 3313.874305][ T4013] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 3313.874307][ T4013] SET = 0, FnV = 0
> [ 3313.874309][ T4013] EA = 0, S1PTW = 0
> [ 3313.874311][ T4013] FSC = 0x06: level 2 translation fault
> [ 3313.874313][ T4013] Data abort info:
> [ 3313.874314][ T4013] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> [ 3313.874316][ T4013] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [ 3313.874318][ T4013] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [ 3313.874320][ T4013] user pgtable: 4k pages, 39-bit VAs, pgdp=00000008f2b0a000
> ..
>
> [ 3313.874332][ T4013] Dumping ftrace buffer:
> [ 3313.874334][ T4013] (ftrace buffer empty)
> ..
> ..
> [ dd3313.874639][ T4013] CPU: 6 PID: 4013 Comm: InputReader
> [ 3313.874648][ T4013] pc : dualshock4_led_get_brightness+0xc/0x74
> [ 3313.874653][ T4013] lr : led_update_brightness+0x38/0x60
> [ 3313.874656][ T4013] sp : ffffffc0b910bbd0
> ..
> ..
> [ 3313.874685][ T4013] Call trace:
> [ 3313.874687][ T4013] dualshock4_led_get_brightness+0xc/0x74
> [ 3313.874690][ T4013] brightness_show+0x20/0x4c
> [ 3313.874692][ T4013] dev_attr_show+0x38/0x74
> [ 3313.874696][ T4013] sysfs_kf_seq_show+0xb4/0x130
> [ 3313.874700][ T4013] kernfs_seq_show+0x44/0x54
> [ 3313.874703][ T4013] seq_read_iter+0x158/0x4ec
> [ 3313.874705][ T4013] kernfs_fop_read_iter+0x68/0x1b4
> [ 3313.874708][ T4013] vfs_read+0x1e0/0x2c8
> [ 3313.874711][ T4013] ksys_read+0x78/0xe8
> [ 3313.874714][ T4013] __arm64_sys_read+0x1c/0x2c
> [ 3313.874718][ T4013] invoke_syscall+0x58/0x114
> [ 3313.874721][ T4013] el0_svc_common+0x80/0xe0
> [ 3313.874724][ T4013] do_el0_svc+0x1c/0x28
> [ 3313.874727][ T4013] el0_svc+0x38/0x68
> [ 3313.874730][ T4013] el0t_64_sync_handler+0x68/0xbc
> [ 3313.874732][ T4013] el0t_64_sync+0x1a8/0x1ac
>
> Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
> ---
> Changes in v2:
> - Updated the comment for led_access mutex lock.
> - Also added mutex protection for max_brightness_show().
>
> drivers/leds/led-class.c | 14 +++++++++++---
> include/linux/leds.h | 2 +-
> 2 files changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> index 06b97fd49ad9..f69f4e928d61 100644
> --- a/drivers/leds/led-class.c
> +++ b/drivers/leds/led-class.c
> @@ -29,11 +29,14 @@ static ssize_t brightness_show(struct device *dev,
> struct device_attribute *attr, char *buf)
> {
> struct led_classdev *led_cdev = dev_get_drvdata(dev);
> + unsigned int brightness;
>
> - /* no lock needed for this */
> + mutex_lock(&led_cdev->led_access);
> led_update_brightness(led_cdev);
> + brightness = led_cdev->brightness;
> + mutex_unlock(&led_cdev->led_access);
>
> - return sprintf(buf, "%u\n", led_cdev->brightness);
> + return sprintf(buf, "%u\n", brightness);
> }
>
> static ssize_t brightness_store(struct device *dev,
> @@ -70,8 +73,13 @@ static ssize_t max_brightness_show(struct device *dev,
> struct device_attribute *attr, char *buf)
> {
> struct led_classdev *led_cdev = dev_get_drvdata(dev);
> + unsigned int max_brightness;
> +
> + mutex_lock(&led_cdev->led_access);
> + max_brightness = led_cdev->max_brightness;
> + mutex_unlock(&led_cdev->led_access);
>
> - return sprintf(buf, "%u\n", led_cdev->max_brightness);
> + return sprintf(buf, "%u\n", max_brightness);
> }
> static DEVICE_ATTR_RO(max_brightness);
>
> diff --git a/include/linux/leds.h b/include/linux/leds.h
> index e5968c3ed4ae..3524634fcc47 100644
> --- a/include/linux/leds.h
> +++ b/include/linux/leds.h
> @@ -238,7 +238,7 @@ struct led_classdev {
> struct kernfs_node *brightness_hw_changed_kn;
> #endif
>
> - /* Ensures consistent access to the LED Flash Class device */
> + /* Ensures consistent access to the LED Class device */
Nit: It was improper in the original comment as well:
s/Class/class/
> struct mutex led_access;
> };
>
Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
--
Best regards,
Jacek Anaszewski
next prev parent reply other threads:[~2024-10-27 14:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-25 17:11 [PATCH v2] leds: class: Protect brightness_show() with led_cdev->led_access mutex Mukesh Ojha
2024-10-25 17:33 ` anish kumar
2024-10-27 14:20 ` Jacek Anaszewski [this message]
2024-11-01 17:08 ` Lee Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=62b09eee-553a-a3d1-e2e0-59dee7289019@gmail.com \
--to=jacek.anaszewski@gmail.com \
--cc=lee@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=quic_mojha@quicinc.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.