All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] pci: Add checks to prevent config space overflow
@ 2022-07-03 10:48 Pali Rohár
  2022-07-04  6:00 ` Stefan Roese
  2022-08-27 12:06 ` Tom Rini
  0 siblings, 2 replies; 4+ messages in thread
From: Pali Rohár @ 2022-07-03 10:48 UTC (permalink / raw)
  To: Stefan Roese, Bin Meng, Simon Glass; +Cc: u-boot

PCIe config space has address range 0-4095. So do not allow reading from
addresses outside of this range. Lot of U-Boot drivers do not expect that
passed value is not in this range. PCI DM read function is exetended to
fill read value to all ones or zeros when it fails as U-Boot callers
ignores return value.

Calling U-Boot command 'pci display.b 0.0.0 0 0x2000' now stops printing
config space at the end (before 0x1000 address).

Signed-off-by: Pali Rohár <pali@kernel.org>
---
 cmd/pci.c                | 16 ++++++++++++++--
 drivers/pci/pci-uclass.c | 10 +++++++++-
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/cmd/pci.c b/cmd/pci.c
index a99e8f8ad6e0..6258699fec81 100644
--- a/cmd/pci.c
+++ b/cmd/pci.c
@@ -358,6 +358,9 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
 	if (length == 0)
 		length = 0x40 / byte_size; /* Standard PCI config space */
 
+	if (addr >= 4096)
+		return 1;
+
 	/* Print the lines.
 	 * once, and all accesses are with the specified bus width.
 	 */
@@ -378,7 +381,10 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
 			rc = 1;
 			break;
 		}
-	} while (nbytes > 0);
+	} while (nbytes > 0 && addr < 4096);
+
+	if (rc == 0 && nbytes > 0)
+		return 1;
 
 	return (rc);
 }
@@ -390,6 +396,9 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
 	int	nbytes;
 	ulong val;
 
+	if (addr >= 4096)
+		return 1;
+
 	/* Print the address, followed by value.  Then accept input for
 	 * the next value.  A non-converted value exits.
 	 */
@@ -427,7 +436,10 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
 					addr += size;
 			}
 		}
-	} while (nbytes);
+	} while (nbytes && addr < 4096);
+
+	if (nbytes)
+		return 1;
 
 	return 0;
 }
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 89245a271e16..7402079471c8 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -288,6 +288,8 @@ int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
 	ops = pci_get_ops(bus);
 	if (!ops->write_config)
 		return -ENOSYS;
+	if (offset < 0 || offset >= 4096)
+		return -EINVAL;
 	return ops->write_config(bus, bdf, offset, value, size);
 }
 
@@ -366,8 +368,14 @@ int pci_bus_read_config(const struct udevice *bus, pci_dev_t bdf, int offset,
 	struct dm_pci_ops *ops;
 
 	ops = pci_get_ops(bus);
-	if (!ops->read_config)
+	if (!ops->read_config) {
+		*valuep = pci_conv_32_to_size(~0, offset, size);
 		return -ENOSYS;
+	}
+	if (offset < 0 || offset >= 4096) {
+		*valuep = pci_conv_32_to_size(0, offset, size);
+		return -EINVAL;
+	}
 	return ops->read_config(bus, bdf, offset, valuep, size);
 }
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] pci: Add checks to prevent config space overflow
  2022-07-03 10:48 [PATCH] pci: Add checks to prevent config space overflow Pali Rohár
@ 2022-07-04  6:00 ` Stefan Roese
  2022-08-17 21:09   ` Pali Rohár
  2022-08-27 12:06 ` Tom Rini
  1 sibling, 1 reply; 4+ messages in thread
From: Stefan Roese @ 2022-07-04  6:00 UTC (permalink / raw)
  To: Pali Rohár, Bin Meng, Simon Glass; +Cc: u-boot

On 03.07.22 12:48, Pali Rohár wrote:
> PCIe config space has address range 0-4095. So do not allow reading from
> addresses outside of this range. Lot of U-Boot drivers do not expect that
> passed value is not in this range. PCI DM read function is exetended to

s/exetended/extended

> fill read value to all ones or zeros when it fails as U-Boot callers
> ignores return value.
> 
> Calling U-Boot command 'pci display.b 0.0.0 0 0x2000' now stops printing
> config space at the end (before 0x1000 address).
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
>   cmd/pci.c                | 16 ++++++++++++++--
>   drivers/pci/pci-uclass.c | 10 +++++++++-
>   2 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/cmd/pci.c b/cmd/pci.c
> index a99e8f8ad6e0..6258699fec81 100644
> --- a/cmd/pci.c
> +++ b/cmd/pci.c
> @@ -358,6 +358,9 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
>   	if (length == 0)
>   		length = 0x40 / byte_size; /* Standard PCI config space */
>   
> +	if (addr >= 4096)
> +		return 1;
> +
>   	/* Print the lines.
>   	 * once, and all accesses are with the specified bus width.
>   	 */
> @@ -378,7 +381,10 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
>   			rc = 1;
>   			break;
>   		}
> -	} while (nbytes > 0);
> +	} while (nbytes > 0 && addr < 4096);
> +
> +	if (rc == 0 && nbytes > 0)
> +		return 1;
>   
>   	return (rc);
>   }
> @@ -390,6 +396,9 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
>   	int	nbytes;
>   	ulong val;
>   
> +	if (addr >= 4096)
> +		return 1;
> +
>   	/* Print the address, followed by value.  Then accept input for
>   	 * the next value.  A non-converted value exits.
>   	 */
> @@ -427,7 +436,10 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
>   					addr += size;
>   			}
>   		}
> -	} while (nbytes);
> +	} while (nbytes && addr < 4096);
> +
> +	if (nbytes)
> +		return 1;
>   
>   	return 0;
>   }
> diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> index 89245a271e16..7402079471c8 100644
> --- a/drivers/pci/pci-uclass.c
> +++ b/drivers/pci/pci-uclass.c
> @@ -288,6 +288,8 @@ int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
>   	ops = pci_get_ops(bus);
>   	if (!ops->write_config)
>   		return -ENOSYS;
> +	if (offset < 0 || offset >= 4096)
> +		return -EINVAL;
>   	return ops->write_config(bus, bdf, offset, value, size);
>   }
>   
> @@ -366,8 +368,14 @@ int pci_bus_read_config(const struct udevice *bus, pci_dev_t bdf, int offset,
>   	struct dm_pci_ops *ops;
>   
>   	ops = pci_get_ops(bus);
> -	if (!ops->read_config)
> +	if (!ops->read_config) {
> +		*valuep = pci_conv_32_to_size(~0, offset, size);
>   		return -ENOSYS;
> +	}
> +	if (offset < 0 || offset >= 4096) {
> +		*valuep = pci_conv_32_to_size(0, offset, size);
> +		return -EINVAL;
> +	}

How about introducing a macro for this 4096 max value instead?

Other than this:

Reviewed-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pci: Add checks to prevent config space overflow
  2022-07-04  6:00 ` Stefan Roese
@ 2022-08-17 21:09   ` Pali Rohár
  0 siblings, 0 replies; 4+ messages in thread
From: Pali Rohár @ 2022-08-17 21:09 UTC (permalink / raw)
  To: Stefan Roese; +Cc: Bin Meng, Simon Glass, u-boot

On Monday 04 July 2022 08:00:23 Stefan Roese wrote:
> On 03.07.22 12:48, Pali Rohár wrote:
> > PCIe config space has address range 0-4095. So do not allow reading from
> > addresses outside of this range. Lot of U-Boot drivers do not expect that
> > passed value is not in this range. PCI DM read function is exetended to
> 
> s/exetended/extended

Should I send a new patch version?

> > fill read value to all ones or zeros when it fails as U-Boot callers
> > ignores return value.
> > 
> > Calling U-Boot command 'pci display.b 0.0.0 0 0x2000' now stops printing
> > config space at the end (before 0x1000 address).
> > 
> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > ---
> >   cmd/pci.c                | 16 ++++++++++++++--
> >   drivers/pci/pci-uclass.c | 10 +++++++++-
> >   2 files changed, 23 insertions(+), 3 deletions(-)
> > 
> > diff --git a/cmd/pci.c b/cmd/pci.c
> > index a99e8f8ad6e0..6258699fec81 100644
> > --- a/cmd/pci.c
> > +++ b/cmd/pci.c
> > @@ -358,6 +358,9 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
> >   	if (length == 0)
> >   		length = 0x40 / byte_size; /* Standard PCI config space */
> > +	if (addr >= 4096)
> > +		return 1;
> > +
> >   	/* Print the lines.
> >   	 * once, and all accesses are with the specified bus width.
> >   	 */
> > @@ -378,7 +381,10 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
> >   			rc = 1;
> >   			break;
> >   		}
> > -	} while (nbytes > 0);
> > +	} while (nbytes > 0 && addr < 4096);
> > +
> > +	if (rc == 0 && nbytes > 0)
> > +		return 1;
> >   	return (rc);
> >   }
> > @@ -390,6 +396,9 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
> >   	int	nbytes;
> >   	ulong val;
> > +	if (addr >= 4096)
> > +		return 1;
> > +
> >   	/* Print the address, followed by value.  Then accept input for
> >   	 * the next value.  A non-converted value exits.
> >   	 */
> > @@ -427,7 +436,10 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
> >   					addr += size;
> >   			}
> >   		}
> > -	} while (nbytes);
> > +	} while (nbytes && addr < 4096);
> > +
> > +	if (nbytes)
> > +		return 1;
> >   	return 0;
> >   }
> > diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> > index 89245a271e16..7402079471c8 100644
> > --- a/drivers/pci/pci-uclass.c
> > +++ b/drivers/pci/pci-uclass.c
> > @@ -288,6 +288,8 @@ int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
> >   	ops = pci_get_ops(bus);
> >   	if (!ops->write_config)
> >   		return -ENOSYS;
> > +	if (offset < 0 || offset >= 4096)
> > +		return -EINVAL;
> >   	return ops->write_config(bus, bdf, offset, value, size);
> >   }
> > @@ -366,8 +368,14 @@ int pci_bus_read_config(const struct udevice *bus, pci_dev_t bdf, int offset,
> >   	struct dm_pci_ops *ops;
> >   	ops = pci_get_ops(bus);
> > -	if (!ops->read_config)
> > +	if (!ops->read_config) {
> > +		*valuep = pci_conv_32_to_size(~0, offset, size);
> >   		return -ENOSYS;
> > +	}
> > +	if (offset < 0 || offset >= 4096) {
> > +		*valuep = pci_conv_32_to_size(0, offset, size);
> > +		return -EINVAL;
> > +	}
> 
> How about introducing a macro for this 4096 max value instead?
> 
> Other than this:
> 
> Reviewed-by: Stefan Roese <sr@denx.de>
> 
> Thanks,
> Stefan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] pci: Add checks to prevent config space overflow
  2022-07-03 10:48 [PATCH] pci: Add checks to prevent config space overflow Pali Rohár
  2022-07-04  6:00 ` Stefan Roese
@ 2022-08-27 12:06 ` Tom Rini
  1 sibling, 0 replies; 4+ messages in thread
From: Tom Rini @ 2022-08-27 12:06 UTC (permalink / raw)
  To: Pali Rohár; +Cc: Stefan Roese, Bin Meng, Simon Glass, u-boot

[-- Attachment #1: Type: text/plain, Size: 661 bytes --]

On Sun, Jul 03, 2022 at 12:48:06PM +0200, Pali Rohár wrote:

> PCIe config space has address range 0-4095. So do not allow reading from
> addresses outside of this range. Lot of U-Boot drivers do not expect that
> passed value is not in this range. PCI DM read function is extended to
> fill read value to all ones or zeros when it fails as U-Boot callers
> ignores return value.
> 
> Calling U-Boot command 'pci display.b 0.0.0 0 0x2000' now stops printing
> config space at the end (before 0x1000 address).
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Reviewed-by: Stefan Roese <sr@denx.de>

Applied to u-boot/master, thanks!

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-08-27 12:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-03 10:48 [PATCH] pci: Add checks to prevent config space overflow Pali Rohár
2022-07-04  6:00 ` Stefan Roese
2022-08-17 21:09   ` Pali Rohár
2022-08-27 12:06 ` Tom Rini

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.