Message ID | 61a0fa74461c15edfae76222522fa445c28bec34.1731502431.git.leon@kernel.org (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | [v2] PCI/sysfs: Change read permissions for VPD attributes | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
Hi Leon, On Wed, 13 Nov 2024 14:59:58 +0200, Leon Romanovsky wrote: > --- a/drivers/pci/vpd.c > +++ b/drivers/pci/vpd.c > @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, > if (!pdev->vpd.cap) > return 0; > > + /* > + * Mellanox devices have implementation that allows VPD read by > + * unprivileged users, so just add needed bits to allow read. > + */ > + WARN_ON_ONCE(a->attr.mode != 0600); > + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) > + return a->attr.mode + 0044; When manipulating bitfields, | is preferred. This would make the operation safe regardless of the initial value, so you can even get rid of the WARN_ON_ONCE() above. > + > return a->attr.mode; > } >
On Thu, Nov 21, 2024 at 01:01:27PM +0100, Jean Delvare wrote: > Hi Leon, > > On Wed, 13 Nov 2024 14:59:58 +0200, Leon Romanovsky wrote: > > --- a/drivers/pci/vpd.c > > +++ b/drivers/pci/vpd.c > > @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, > > if (!pdev->vpd.cap) > > return 0; > > > > + /* > > + * Mellanox devices have implementation that allows VPD read by > > + * unprivileged users, so just add needed bits to allow read. > > + */ > > + WARN_ON_ONCE(a->attr.mode != 0600); > > + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) > > + return a->attr.mode + 0044; > > When manipulating bitfields, | is preferred. This would make the > operation safe regardless of the initial value, so you can even get rid > of the WARN_ON_ONCE() above. The WARN_ON_ONCE() is intended to catch future changes in VPD sysfs attributes. My intention is that once that WARN will trigger, the author will be forced to reevaluate the latter if ( ... PCI_VENDOR_ID_MELLANOX) condition and maybe we won't need it anymore. Without WARN_ON_ONCE, it is easy to miss that code. I still didn't lost hope that at some point VPD will be open for read to all kernel devices. Bjorn, are you ok with this patch? If yes, I'll resend the patch with the suggested change after the merge window. Thanks > > > + > > return a->attr.mode; > > } > > > > -- > Jean Delvare > SUSE L3 Support >
On Thu, 21 Nov 2024 14:13:01 +0200, Leon Romanovsky wrote: > On Thu, Nov 21, 2024 at 01:01:27PM +0100, Jean Delvare wrote: > > On Wed, 13 Nov 2024 14:59:58 +0200, Leon Romanovsky wrote: > > > --- a/drivers/pci/vpd.c > > > +++ b/drivers/pci/vpd.c > > > @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, > > > if (!pdev->vpd.cap) > > > return 0; > > > > > > + /* > > > + * Mellanox devices have implementation that allows VPD read by > > > + * unprivileged users, so just add needed bits to allow read. > > > + */ > > > + WARN_ON_ONCE(a->attr.mode != 0600); > > > + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) > > > + return a->attr.mode + 0044; > > > > When manipulating bitfields, | is preferred. This would make the > > operation safe regardless of the initial value, so you can even get rid > > of the WARN_ON_ONCE() above. > > The WARN_ON_ONCE() is intended to catch future changes in VPD sysfs > attributes. My intention is that once that WARN will trigger, the > author will be forced to reevaluate the latter if ( ... PCI_VENDOR_ID_MELLANOX) > condition and maybe we won't need it anymore. Without WARN_ON_ONCE, it > is easy to miss that code. The default permissions are 10 lines above in the same file. Doesn't seem that easy to miss to me. In my opinion, WARN_ON should be limited to cases where something really bad has happened. It's not supposed to be a reminder for developers to perform some code clean-up. Remember that WARN_ON has a run-time cost and it could be evaluated for a possibly large number of PCI devices (although admittedly VPD support seems to be present only in a limited number of PCI device). Assuming you properly use | instead of +, then nothing bad will happen if the default permissions change, the code will simply become a no-op, until someone notices and deletes it. No harm done. I'm not maintaining this part of the kernel so I can't speak or decide on behalf of the maintainers, but in my opinion, if you really want to leave a note for future developers, then a comment in the source code is a better way, as it has no run-time cost, and will also be found earlier by the developers (no need for run-time testing). Thanks,
On Thu, Nov 21, 2024 at 03:11:16PM +0100, Jean Delvare wrote: > On Thu, 21 Nov 2024 14:13:01 +0200, Leon Romanovsky wrote: > > On Thu, Nov 21, 2024 at 01:01:27PM +0100, Jean Delvare wrote: > > > On Wed, 13 Nov 2024 14:59:58 +0200, Leon Romanovsky wrote: > > > > --- a/drivers/pci/vpd.c > > > > +++ b/drivers/pci/vpd.c > > > > @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, > > > > if (!pdev->vpd.cap) > > > > return 0; > > > > > > > > + /* > > > > + * Mellanox devices have implementation that allows VPD read by > > > > + * unprivileged users, so just add needed bits to allow read. > > > > + */ > > > > + WARN_ON_ONCE(a->attr.mode != 0600); > > > > + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) > > > > + return a->attr.mode + 0044; > > > > > > When manipulating bitfields, | is preferred. This would make the > > > operation safe regardless of the initial value, so you can even get rid > > > of the WARN_ON_ONCE() above. > > > > The WARN_ON_ONCE() is intended to catch future changes in VPD sysfs > > attributes. My intention is that once that WARN will trigger, the > > author will be forced to reevaluate the latter if ( ... PCI_VENDOR_ID_MELLANOX) > > condition and maybe we won't need it anymore. Without WARN_ON_ONCE, it > > is easy to miss that code. > > The default permissions are 10 lines above in the same file. Doesn't > seem that easy to miss to me. > > In my opinion, WARN_ON should be limited to cases where something really > bad has happened. It's not supposed to be a reminder for developers to > perform some code clean-up. Remember that WARN_ON has a run-time cost > and it could be evaluated for a possibly large number of PCI devices > (although admittedly VPD support seems to be present only in a limited > number of PCI device). Sorry about which run-time cost are you referring? This is slow path and extra if() inside WARN_ON which has unlikely keyword, makes no difference when accessing HW. In addition, this check is for devices which already known to have VPD (see pdev->vpd.cap check above). > > Assuming you properly use | instead of +, then nothing bad will happen > if the default permissions change, the code will simply become a no-op, > until someone notices and deletes it. No harm done. > > I'm not maintaining this part of the kernel so I can't speak or decide > on behalf of the maintainers, but in my opinion, if you really want to > leave a note for future developers, then a comment in the source code > is a better way, as it has no run-time cost, and will also be found > earlier by the developers (no need for run-time testing). I don't have any strong feelings about this WARN_ON_ONCE, will remove. Thanks > > Thanks, > -- > Jean Delvare > SUSE L3 Support
On Thu, Nov 21, 2024 at 02:13:01PM +0200, Leon Romanovsky wrote: > On Thu, Nov 21, 2024 at 01:01:27PM +0100, Jean Delvare wrote: > > On Wed, 13 Nov 2024 14:59:58 +0200, Leon Romanovsky wrote: > > > --- a/drivers/pci/vpd.c > > > +++ b/drivers/pci/vpd.c > > > @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, > > > if (!pdev->vpd.cap) > > > return 0; > > > > > > + /* > > > + * Mellanox devices have implementation that allows VPD read by > > > + * unprivileged users, so just add needed bits to allow read. > > > + */ > > > + WARN_ON_ONCE(a->attr.mode != 0600); > > > + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) > > > + return a->attr.mode + 0044; > ... > I still didn't lost hope that at some point VPD will be open for read to > all kernel devices. > > Bjorn, are you ok with this patch? If yes, I'll resend the patch with > the suggested change after the merge window. Reading VPD is a fairly complicated dance that only works if the VPD data is well-formatted, and the benefit of unprivileged access seems pretty small, so the risk/reward tradeoff for making it unprivileged for all devices doesn't seem favorable in my mind. This quirk seems like the least bad option, so I guess I'm ok with it. Bjorn
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index e4300f5f304f..9d5a35737abf 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -332,6 +332,14 @@ static umode_t vpd_attr_is_visible(struct kobject *kobj, if (!pdev->vpd.cap) return 0; + /* + * Mellanox devices have implementation that allows VPD read by + * unprivileged users, so just add needed bits to allow read. + */ + WARN_ON_ONCE(a->attr.mode != 0600); + if (unlikely(pdev->vendor == PCI_VENDOR_ID_MELLANOX)) + return a->attr.mode + 0044; + return a->attr.mode; }