Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753125AbcKIMQb (ORCPT ); Wed, 9 Nov 2016 07:16:31 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:56460 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750938AbcKIMQ2 (ORCPT ); Wed, 9 Nov 2016 07:16:28 -0500 X-AuditID: cbfee61b-f796f6d000004092-a1-582313762c5d From: Jacek Anaszewski To: linux-leds@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Jacek Anaszewski , Hans de Goede , Sakari Ailus , Pavel Machek , Andrew Lunn Subject: [PATCH v2] leds: Add mutex protection in brightness_show() Date: Wed, 09 Nov 2016 13:15:25 +0100 Message-id: <1478693725-29893-1-git-send-email-j.anaszewski@samsung.com> X-Mailer: git-send-email 1.9.1 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrJLMWRmVeSWpSXmKPExsVy+t9jAd0yYeUIg13zjSzO3z3EbPHm+HQm i96rzxktLu+aw2ax9c06Rou7p46yWXza8o3Jgd1j3slAj507PjN5vN93lc2jb8sqRo8Vq7+z e3zeJBfAFuVmk5GamJJapJCal5yfkpmXbqsUGuKma6GkkJeYm2qrFKHrGxKkpFCWmFMK5BkZ oAEH5wD3YCV9uwS3jHkX7rIVzOKt+PZ5LlsDYxN3FyMnh4SAicTj3jnsELaYxIV769m6GLk4 hASWMkoseb2KEcL5ySixvBnE4eRgEzCU+PniNVMXIweHiICcxM4zlSA1zAIPGCWurV8JNklY wFniW98xNhCbRUBVoqP/IZjNK+Ah0b/8JyPENjmJk8cms05g5F7AyLCKUSK1ILmgOCk91ygv tVyvODG3uDQvXS85P3cTIzhYn0nvYDy8y/0QowAHoxIPb8ZDxQgh1sSy4srcQ4wSHMxKIrwf BJUjhHhTEiurUovy44tKc1KLDzGaAh0wkVlKNDkfGEl5JfGGJuYm5sYGFuaWliZGSuK8jbOf hQsJpCeWpGanphakFsH0MXFwSjUwCi9xODKFiY3x+JSCnddetHDu8Oqd1BK1YVvoZnmVwFpT f4X1P01r+Es/nd34v3aHfSjX/728W1411y9PKmB0irsySW/CpCS+b23SZ1ZzbBT+cfuiAa9S cYRatMK94mcPQuvO3evdXifKlLa54VzPUY6DFxfvy7p9Mm3eUf1yzukH6yf89bKIUmIpzkg0 1GIuKk4EAETHtoJsAgAA X-MTR: 20000000000000000@CPGS Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1633 Lines: 55 Initially the claim about no need for lock in brightness_show() was valid as the function was just returning unchanged LED brightness. After the addition of led_update_brightness() this is no longer true, as the function can change the brightness if a LED class driver implements brightness_get op. It can lead to races between led_update_brightness() and led_set_brightness(). Signed-off-by: Jacek Anaszewski Cc: Hans de Goede Cc: Sakari Ailus Cc: Pavel Machek Cc: Andrew Lunn --- Changes since v1: - added led_sysfs_is_disabled() check - moved sprintf under mutex protection drivers/leds/led-class.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index b12f861..e472407 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -29,11 +29,23 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + int ret; - /* no lock needed for this */ - led_update_brightness(led_cdev); + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } + + ret = led_update_brightness(led_cdev); + if (ret < 0) + goto unlock; - return sprintf(buf, "%u\n", led_cdev->brightness); + ret = sprintf(buf, "%u\n", led_cdev->brightness); +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } static ssize_t brightness_store(struct device *dev, -- 1.9.1