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
| ||
|
Message-ID: <b44c4a7d-4f86-4d53-8f11-ffeef91e1407@embeddedor.com> Date: Tue, 21 Nov 2023 09:53:56 -0600 From: "Gustavo A. R. Silva" <gustavo@...eddedor.com> To: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>, Thierry Reding <thierry.reding@...il.com>, Kees Cook <keescook@...omium.org> Cc: "Gustavo A. R. Silva" <gustavoars@...nel.org>, linux-pwm@...r.kernel.org, kernel@...gutronix.de, linux-hardening@...r.kernel.org Subject: Re: [PATCH v3 105/108] pwm: Ensure a struct pwm has the same lifetime as its pwm_chip On 11/21/23 07:50, Uwe Kleine-König wrote: > It's required to not free the memory underlying a requested PWM > while a consumer still has a reference to it. While currently a pwm_chip > doesn't life long enough in all cases, linking the struct pwm to the > pwm_chip results in the right lifetime as soon as the pwmchip is living > long enough. This happens with the following commits. > > Note this is a breaking change for all pwm drivers that don't use > pwmchip_alloc(). > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de> Reviewed-by: Gustavo A. R. Silva <gustavoars@...nel.org> # for struct_size() and __counted_by() Thanks for including __counted_by(). :) -- Gustavo > --- > drivers/pwm/core.c | 26 ++++++++++---------------- > include/linux/pwm.h | 2 +- > 2 files changed, 11 insertions(+), 17 deletions(-) > > diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c > index 15942210aa08..029aa1c69591 100644 > --- a/drivers/pwm/core.c > +++ b/drivers/pwm/core.c > @@ -198,7 +198,7 @@ static bool pwm_ops_check(const struct pwm_chip *chip) > > void *pwmchip_priv(struct pwm_chip *chip) > { > - return (void *)chip + sizeof(*chip); > + return (void *)chip + struct_size(chip, pwms, chip->npwm); > } > EXPORT_SYMBOL_GPL(pwmchip_priv); > > @@ -206,8 +206,9 @@ struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, si > { > struct pwm_chip *chip; > size_t alloc_size; > + unsigned int i; > > - alloc_size = size_add(sizeof(*chip), sizeof_priv); > + alloc_size = size_add(struct_size(chip, pwms, npwm), sizeof_priv); > > chip = devm_kzalloc(parent, alloc_size, GFP_KERNEL); > if (!chip) > @@ -217,6 +218,13 @@ struct pwm_chip *devm_pwmchip_alloc(struct device *parent, unsigned int npwm, si > chip->npwm = npwm; > chip->uses_pwmchip_alloc = true; > > + for (i = 0; i < chip->npwm; i++) { > + struct pwm_device *pwm = &chip->pwms[i]; > + > + pwm->chip = chip; > + pwm->hwpwm = i; > + } > + > return chip; > } > EXPORT_SYMBOL_GPL(devm_pwmchip_alloc); > @@ -234,7 +242,6 @@ EXPORT_SYMBOL_GPL(devm_pwmchip_alloc); > int __pwmchip_add(struct pwm_chip *chip, struct module *owner) > { > int ret; > - unsigned i; > > if (!chip || !chip->dev || !chip->ops || !chip->npwm) > return -EINVAL; > @@ -253,26 +260,15 @@ int __pwmchip_add(struct pwm_chip *chip, struct module *owner) > > chip->owner = owner; > > - chip->pwms = kcalloc(chip->npwm, sizeof(*chip->pwms), GFP_KERNEL); > - if (!chip->pwms) > - return -ENOMEM; > - > mutex_lock(&pwm_lock); > > ret = idr_alloc(&pwmchip_idr, chip, 0, 0, GFP_KERNEL); > if (ret < 0) { > mutex_unlock(&pwm_lock); > - kfree(chip->pwms); > return ret; > } > > chip->id = ret; > - for (i = 0; i < chip->npwm; i++) { > - struct pwm_device *pwm = &chip->pwms[i]; > - > - pwm->chip = chip; > - pwm->hwpwm = i; > - } > > mutex_unlock(&pwm_lock); > > @@ -303,8 +299,6 @@ void pwmchip_remove(struct pwm_chip *chip) > idr_remove(&pwmchip_idr, chip->id); > > mutex_unlock(&pwm_lock); > - > - kfree(chip->pwms); > } > EXPORT_SYMBOL_GPL(pwmchip_remove); > > diff --git a/include/linux/pwm.h b/include/linux/pwm.h > index b8e70ee01d31..a7294ef1495d 100644 > --- a/include/linux/pwm.h > +++ b/include/linux/pwm.h > @@ -302,7 +302,7 @@ struct pwm_chip { > > /* only used internally by the PWM framework */ > bool uses_pwmchip_alloc; > - struct pwm_device *pwms; > + struct pwm_device pwms[] __counted_by(npwm); > }; > > static inline struct device *pwmchip_parent(struct pwm_chip *chip)
Powered by blists - more mailing lists