linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] net: atlantic: Avoid out-of-bounds indexing
@ 2022-03-04  5:08 Kai-Heng Feng
  2022-03-05  5:24 ` Jakub Kicinski
  0 siblings, 1 reply; 4+ messages in thread
From: Kai-Heng Feng @ 2022-03-04  5:08 UTC (permalink / raw)
  To: irusskikh, davem, kuba
  Cc: Kai-Heng Feng, Mario Limonciello, netdev, linux-kernel

UBSAN warnings are observed on atlantic driver:
[ 294.432996] UBSAN: array-index-out-of-bounds in /build/linux-Qow4fL/linux-5.15.0/drivers/net/ethernet/aquantia/atlantic/aq_nic.c:484:48
[ 294.433695] index 8 is out of range for type 'aq_vec_s *[8]'

The index is assigned right before breaking out the loop, so there's no actual
deferencing happening.

So only use the index inside the loop to fix the issue.

BugLink: https://bugs.launchpad.net/bugs/1958770
Tested-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 .../net/ethernet/aquantia/atlantic/aq_vec.c   | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
index f4774cf051c97..6ab1f3212d246 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
@@ -43,8 +43,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
 	if (!self) {
 		err = -EINVAL;
 	} else {
-		for (i = 0U, ring = self->ring[0];
-			self->tx_rings > i; ++i, ring = self->ring[i]) {
+		for (i = 0U; self->tx_rings > i; ++i) {
+			ring = self->ring[i];
 			u64_stats_update_begin(&ring[AQ_VEC_RX_ID].stats.rx.syncp);
 			ring[AQ_VEC_RX_ID].stats.rx.polls++;
 			u64_stats_update_end(&ring[AQ_VEC_RX_ID].stats.rx.syncp);
@@ -182,8 +182,8 @@ int aq_vec_init(struct aq_vec_s *self, const struct aq_hw_ops *aq_hw_ops,
 	self->aq_hw_ops = aq_hw_ops;
 	self->aq_hw = aq_hw;
 
-	for (i = 0U, ring = self->ring[0];
-		self->tx_rings > i; ++i, ring = self->ring[i]) {
+	for (i = 0U; self->tx_rings > i; ++i) {
+		ring = self->ring[i];
 		err = aq_ring_init(&ring[AQ_VEC_TX_ID], ATL_RING_TX);
 		if (err < 0)
 			goto err_exit;
@@ -224,8 +224,8 @@ int aq_vec_start(struct aq_vec_s *self)
 	unsigned int i = 0U;
 	int err = 0;
 
-	for (i = 0U, ring = self->ring[0];
-		self->tx_rings > i; ++i, ring = self->ring[i]) {
+	for (i = 0U; self->tx_rings > i; ++i) {
+		ring = self->ring[i];
 		err = self->aq_hw_ops->hw_ring_tx_start(self->aq_hw,
 							&ring[AQ_VEC_TX_ID]);
 		if (err < 0)
@@ -248,8 +248,8 @@ void aq_vec_stop(struct aq_vec_s *self)
 	struct aq_ring_s *ring = NULL;
 	unsigned int i = 0U;
 
-	for (i = 0U, ring = self->ring[0];
-		self->tx_rings > i; ++i, ring = self->ring[i]) {
+	for (i = 0U; self->tx_rings > i; ++i) {
+		ring = self->ring[i];
 		self->aq_hw_ops->hw_ring_tx_stop(self->aq_hw,
 						 &ring[AQ_VEC_TX_ID]);
 
@@ -268,8 +268,8 @@ void aq_vec_deinit(struct aq_vec_s *self)
 	if (!self)
 		goto err_exit;
 
-	for (i = 0U, ring = self->ring[0];
-		self->tx_rings > i; ++i, ring = self->ring[i]) {
+	for (i = 0U; self->tx_rings > i; ++i) {
+		ring = self->ring[i];
 		aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]);
 		aq_ring_rx_deinit(&ring[AQ_VEC_RX_ID]);
 	}
@@ -297,8 +297,8 @@ void aq_vec_ring_free(struct aq_vec_s *self)
 	if (!self)
 		goto err_exit;
 
-	for (i = 0U, ring = self->ring[0];
-		self->tx_rings > i; ++i, ring = self->ring[i]) {
+	for (i = 0U; self->tx_rings > i; ++i) {
+		ring = self->ring[i];
 		aq_ring_free(&ring[AQ_VEC_TX_ID]);
 		if (i < self->rx_rings)
 			aq_ring_free(&ring[AQ_VEC_RX_ID]);
-- 
2.34.1


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

* Re: [PATCH] net: atlantic: Avoid out-of-bounds indexing
  2022-03-04  5:08 [PATCH] net: atlantic: Avoid out-of-bounds indexing Kai-Heng Feng
@ 2022-03-05  5:24 ` Jakub Kicinski
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2022-03-05  5:24 UTC (permalink / raw)
  To: Kai-Heng Feng; +Cc: irusskikh, davem, Mario Limonciello, netdev, linux-kernel

On Fri,  4 Mar 2022 13:08:12 +0800 Kai-Heng Feng wrote:
> UBSAN warnings are observed on atlantic driver:
> [ 294.432996] UBSAN: array-index-out-of-bounds in /build/linux-Qow4fL/linux-5.15.0/drivers/net/ethernet/aquantia/atlantic/aq_nic.c:484:48
> [ 294.433695] index 8 is out of range for type 'aq_vec_s *[8]'
> 
> The index is assigned right before breaking out the loop, so there's no actual
> deferencing happening.

I think you're underselling it. This codes does not compute the address
of the ring, it reads the ring pointer from an array. The description
reads like it was doing:

	ring = &self->ring[i];

which would indeed be valid. What the code actually does is not.

Please repost with the commit message improved and a Fixes: tag(s)
pointing to commit(s) where the buggy code was introduced.

> So only use the index inside the loop to fix the issue.
> 
> BugLink: https://bugs.launchpad.net/bugs/1958770
> Tested-by: Mario Limonciello <mario.limonciello@amd.com>
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> ---
>  .../net/ethernet/aquantia/atlantic/aq_vec.c   | 24 +++++++++----------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
> index f4774cf051c97..6ab1f3212d246 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c
> @@ -43,8 +43,8 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
>  	if (!self) {
>  		err = -EINVAL;
>  	} else {
> -		for (i = 0U, ring = self->ring[0];
> -			self->tx_rings > i; ++i, ring = self->ring[i]) {
> +		for (i = 0U; self->tx_rings > i; ++i) {
> +			ring = self->ring[i];
>  			u64_stats_update_begin(&ring[AQ_VEC_RX_ID].stats.rx.syncp);
>  			ring[AQ_VEC_RX_ID].stats.rx.polls++;
>  			u64_stats_update_end(&ring[AQ_VEC_RX_ID].stats.rx.syncp);

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

* Re: [PATCH] net: atlantic: Avoid out-of-bounds indexing
  2022-05-19  1:09 Nikolaus Vladutescu-Zopp
@ 2022-05-20  0:51 ` Jakub Kicinski
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Kicinski @ 2022-05-20  0:51 UTC (permalink / raw)
  To: Nikolaus Vladutescu-Zopp
  Cc: irusskikh, davem, edumazet, pabeni, netdev, linux-kernel,
	blairuk, kai.heng.feng

On Thu, 19 May 2022 03:09:50 +0200 Nikolaus Vladutescu-Zopp wrote:
> A UBSAN warning is observed on atlantic driver:
> 
> [ 16.257086] UBSAN: array-index-out-of-bounds in 
> drivers/net/ethernet/aquantia/atlantic/aq_nic.c:1268:48
> [ 16.257090] index 8 is out of range for type 'aq_vec_s *[8]'
> 
> The index is assigned right before breaking out the loop, so there's no
> actual deferencing happening.
> So only use the index inside the loop to fix the issue.
> 
> Same issue was observed and corrected in two other places.
> 
> BugLink: https://bugs.launchpad.net/bugs/1958770
> Suggested-by: bsdz <blairuk@gmail.com>
> Suggested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Tested-by: Nikolaus Vladutescu-Zopp <nikolaus@vladutescu-zopp.com>
> Signed-off-by: Nikolaus Vladutescu-Zopp <nikolaus@vladutescu-zopp.com>

The patch does not apply, please rebase on net/master:

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/

and repost. Please use [PATCH net] as the subject prefix. Please add 
a Fixes tag, if possible. Please replace "bsdz" with the person's name
or remove that tag.

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

* [PATCH] net: atlantic: Avoid out-of-bounds indexing
@ 2022-05-19  1:09 Nikolaus Vladutescu-Zopp
  2022-05-20  0:51 ` Jakub Kicinski
  0 siblings, 1 reply; 4+ messages in thread
From: Nikolaus Vladutescu-Zopp @ 2022-05-19  1:09 UTC (permalink / raw)
  To: irusskikh, davem, edumazet, kuba, pabeni, netdev, linux-kernel
  Cc: Nikolaus Vladutescu-Zopp, blairuk, kai.heng.feng

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

A UBSAN warning is observed on atlantic driver:

[ 16.257086] UBSAN: array-index-out-of-bounds in 
drivers/net/ethernet/aquantia/atlantic/aq_nic.c:1268:48
[ 16.257090] index 8 is out of range for type 'aq_vec_s *[8]'

The index is assigned right before breaking out the loop, so there's no
actual deferencing happening.
So only use the index inside the loop to fix the issue.

Same issue was observed and corrected in two other places.

BugLink: https://bugs.launchpad.net/bugs/1958770
Suggested-by: bsdz <blairuk@gmail.com>
Suggested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Tested-by: Nikolaus Vladutescu-Zopp <nikolaus@vladutescu-zopp.com>
Signed-off-by: Nikolaus Vladutescu-Zopp <nikolaus@vladutescu-zopp.com>

---
   drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 17 ++++++++++-------
   1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 24d715c28a35..f49645d243ba 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -268,9 +268,10 @@ static void aq_nic_polling_timer_cb(struct
timer_list *t)
   	struct aq_vec_s *aq_vec = NULL;
   	unsigned int i = 0U;

-	for (i = 0U, aq_vec = self->aq_vec[0];
-		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
+	for (i = 0U; self->aq_vecs > i; ++i) {
+		aq_vec = self->aq_vec[i];
   		aq_vec_isr(i, (void *)aq_vec);
+	}

   	mod_timer(&self->polling_timer, jiffies +
   		  AQ_CFG_POLLING_TIMER_INTERVAL);
@@ -928,9 +929,10 @@ u64 *aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
   	data += i;

   	for (tc = 0U; tc < self->aq_nic_cfg.tcs; tc++) {
-		for (i = 0U, aq_vec = self->aq_vec[0];
-		     aq_vec && self->aq_vecs > i;
-		     ++i, aq_vec = self->aq_vec[i]) {
+		for (i = 0U; self->aq_vecs > i; ++i) {
+			aq_vec = self->aq_vec[i];
+			if (!aq_vec)
+				break;
   			data += count;
   			count = aq_vec_get_sw_stats(aq_vec, tc, data);
   		}
@@ -1264,9 +1266,10 @@ int aq_nic_stop(struct aq_nic_s *self)

   	aq_ptp_irq_free(self);

-	for (i = 0U, aq_vec = self->aq_vec[0];
-		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
+	for (i = 0U; self->aq_vecs > i; ++i) {
+		aq_vec = self->aq_vec[i];
   		aq_vec_stop(aq_vec);
+	}

   	aq_ptp_ring_stop(self);

-- 
2.34.1

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4508 bytes --]

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

end of thread, other threads:[~2022-05-20  0:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-04  5:08 [PATCH] net: atlantic: Avoid out-of-bounds indexing Kai-Heng Feng
2022-03-05  5:24 ` Jakub Kicinski
2022-05-19  1:09 Nikolaus Vladutescu-Zopp
2022-05-20  0:51 ` Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).