* [PATCH resend] airo: Fix read overflow in mpi_send_packet() [not found] <EED43E20-9B88-42EC-80B0-0245F0FAF980@gmail.com> @ 2020-05-27 13:36 ` Dan Carpenter 2020-05-27 16:52 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Dan Carpenter @ 2020-05-27 13:36 UTC (permalink / raw) To: Kalle Valo, Hu Jiahui; +Cc: security, linux-wireless, Jakub Kicinski The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from skb->data even when skb->len is less than ETH_ZLEN so it leads to a read overflow. The fix for is to pad skb->data with zeroes so that it's never less than ETH_ZLEN bytes. c: <stable@vger.kernel.org> Reported-by: Hu Jiahui <kirin.say@gmail.com> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> --- Resending to the public lists so that it can go through the normal review process. My other concern with this driver is why is the ->max_mtu 2400 when it looks like we are allocating PKTSIZE (1840) byte buffers to hold it in mpi_map_card()? I don't fully understand the code but that seems like it could be a buffer overflow as well. I'm not sure what the appropriate fix is for that. drivers/net/wireless/cisco/airo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 8363f91df7ea7..7c5634f72cc72 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -1925,6 +1925,11 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!",__func__); return NETDEV_TX_OK; } + if (skb->len < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + return NETDEV_TX_OK; + } + npacks = skb_queue_len (&ai->txq); if (npacks >= MAXTXQ - 1) { @@ -1975,8 +1980,7 @@ static int mpi_send_packet (struct net_device *dev) return 0; } - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + len = skb->len; buffer = skb->data; ai->txfids[0].tx_desc.offset = 0; -- 2.26.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH resend] airo: Fix read overflow in mpi_send_packet() 2020-05-27 13:36 ` [PATCH resend] airo: Fix read overflow in mpi_send_packet() Dan Carpenter @ 2020-05-27 16:52 ` Eric Dumazet 2020-05-27 17:58 ` [PATCH v2] airo: Fix read overflows sending packets Dan Carpenter 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2020-05-27 16:52 UTC (permalink / raw) To: Dan Carpenter Cc: Kalle Valo, Hu Jiahui, Security Officers, linux-wireless, Jakub Kicinski On Wed, May 27, 2020 at 6:37 AM Dan Carpenter <dan.carpenter@oracle.com> wrote: > > The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from > skb->data even when skb->len is less than ETH_ZLEN so it leads to a read > overflow. > > The fix for is to pad skb->data with zeroes so that it's never less than > ETH_ZLEN bytes. > > c: <stable@vger.kernel.org> > Reported-by: Hu Jiahui <kirin.say@gmail.com> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> > --- > Resending to the public lists so that it can go through the normal > review process. > > My other concern with this driver is why is the ->max_mtu 2400 when it > looks like we are allocating PKTSIZE (1840) byte buffers to hold it in > mpi_map_card()? I don't fully understand the code but that seems like > it could be a buffer overflow as well. I'm not sure what the > appropriate fix is for that. > > drivers/net/wireless/cisco/airo.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c > index 8363f91df7ea7..7c5634f72cc72 100644 > --- a/drivers/net/wireless/cisco/airo.c > +++ b/drivers/net/wireless/cisco/airo.c > @@ -1925,6 +1925,11 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, > airo_print_err(dev->name, "%s: skb == NULL!",__func__); > return NETDEV_TX_OK; > } > + if (skb->len < ETH_ZLEN) { No need to duplicate the test. Just use if (skb_padto(skb, ETH_ZLEN)) { dev->stats.tx_dropped++; return NETDEV_TX_OK; } > + if (skb_padto(skb, ETH_ZLEN)) > + return NETDEV_TX_OK; > + } > + > npacks = skb_queue_len (&ai->txq); > > if (npacks >= MAXTXQ - 1) { > @@ -1975,8 +1980,7 @@ static int mpi_send_packet (struct net_device *dev) > return 0; > } > > - /* check min length*/ > - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; > + len = skb->len; > buffer = skb->data; > > ai->txfids[0].tx_desc.offset = 0; > -- > 2.26.2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] airo: Fix read overflows sending packets 2020-05-27 16:52 ` Eric Dumazet @ 2020-05-27 17:58 ` Dan Carpenter 2020-05-27 18:08 ` Eric Dumazet 0 siblings, 1 reply; 8+ messages in thread From: Dan Carpenter @ 2020-05-27 17:58 UTC (permalink / raw) To: Kalle Valo, Hu Jiahui, Eric Dumazet Cc: security, linux-wireless, Jakub Kicinski The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from skb->data even when skb->len is less than ETH_ZLEN so it leads to a read overflow. The fix is to pad skb->data with zeroes so that it's never less than ETH_ZLEN bytes. Cc: <stable@vger.kernel.org> Reported-by: Hu Jiahui <kirin.say@gmail.com> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> --- v2: remove an unnecessary if statement increment the ->tx_dropped count on failure fix found two more instances of the same bug. fix typo in the "Cc: <stable@vger.kernel.org>" tag drivers/net/wireless/cisco/airo.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 8363f91df7ea..c80712e61ccf 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -1925,6 +1925,11 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!",__func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } + npacks = skb_queue_len (&ai->txq); if (npacks >= MAXTXQ - 1) { @@ -1975,8 +1980,7 @@ static int mpi_send_packet (struct net_device *dev) return 0; } - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + len = skb->len; buffer = skb->data; ai->txfids[0].tx_desc.offset = 0; @@ -2118,7 +2122,6 @@ static void airo_end_xmit(struct net_device *dev) { static netdev_tx_t airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { - s16 len; int i, j; struct airo_info *priv = dev->ml_priv; u32 *fids = priv->fids; @@ -2127,6 +2130,10 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); @@ -2140,10 +2147,8 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, return NETDEV_TX_BUSY; } } - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* Mark fid as used & save length for later */ - fids[i] |= (len << 16); + fids[i] |= (skb->len << 16); priv->xmit.skb = skb; priv->xmit.fid = i; if (down_trylock(&priv->sem) != 0) { @@ -2185,7 +2190,6 @@ static void airo_end_xmit11(struct net_device *dev) { static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { - s16 len; int i, j; struct airo_info *priv = dev->ml_priv; u32 *fids = priv->fids; @@ -2201,6 +2205,10 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); @@ -2214,10 +2222,8 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, return NETDEV_TX_BUSY; } } - /* check min length*/ - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; /* Mark fid as used & save length for later */ - fids[i] |= (len << 16); + fids[i] |= (skb->len << 16); priv->xmit11.skb = skb; priv->xmit11.fid = i; if (down_trylock(&priv->sem) != 0) { -- 2.11.0 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] airo: Fix read overflows sending packets 2020-05-27 17:58 ` [PATCH v2] airo: Fix read overflows sending packets Dan Carpenter @ 2020-05-27 18:08 ` Eric Dumazet 2020-05-27 18:48 ` [PATCH v3] " Dan Carpenter 0 siblings, 1 reply; 8+ messages in thread From: Eric Dumazet @ 2020-05-27 18:08 UTC (permalink / raw) To: Dan Carpenter Cc: Kalle Valo, Hu Jiahui, Security Officers, linux-wireless, Jakub Kicinski On Wed, May 27, 2020 at 10:58 AM Dan Carpenter <dan.carpenter@oracle.com> wrote: > > The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from > skb->data even when skb->len is less than ETH_ZLEN so it leads to a read > overflow. > > The fix is to pad skb->data with zeroes so that it's never less than > ETH_ZLEN bytes. > > Cc: <stable@vger.kernel.org> > Reported-by: Hu Jiahui <kirin.say@gmail.com> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> > --- > v2: remove an unnecessary if statement > increment the ->tx_dropped count on failure > fix found two more instances of the same bug. > fix typo in the "Cc: <stable@vger.kernel.org>" tag > > drivers/net/wireless/cisco/airo.c | 26 ++++++++++++++++---------- > 1 file changed, 16 insertions(+), 10 deletions(-) > > diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c > index 8363f91df7ea..c80712e61ccf 100644 > --- a/drivers/net/wireless/cisco/airo.c > +++ b/drivers/net/wireless/cisco/airo.c > @@ -1925,6 +1925,11 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, > airo_print_err(dev->name, "%s: skb == NULL!",__func__); > return NETDEV_TX_OK; > } > + if (skb_padto(skb, ETH_ZLEN)) { > + dev->stats.tx_dropped++; > + return NETDEV_TX_OK; > + } > + > npacks = skb_queue_len (&ai->txq); > > if (npacks >= MAXTXQ - 1) { > @@ -1975,8 +1980,7 @@ static int mpi_send_packet (struct net_device *dev) > return 0; > } > > - /* check min length*/ > - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; Note that skb_padto() does not change skb->len So this patch could trigger a hardware bug. > + len = skb->len; > buffer = skb->data; > > ai->txfids[0].tx_desc.offset = 0; > @@ -2118,7 +2122,6 @@ static void airo_end_xmit(struct net_device *dev) { > static netdev_tx_t airo_start_xmit(struct sk_buff *skb, > struct net_device *dev) > { > - s16 len; > int i, j; > struct airo_info *priv = dev->ml_priv; > u32 *fids = priv->fids; > @@ -2127,6 +2130,10 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, > airo_print_err(dev->name, "%s: skb == NULL!", __func__); > return NETDEV_TX_OK; > } > + if (skb_padto(skb, ETH_ZLEN)) { > + dev->stats.tx_dropped++; > + return NETDEV_TX_OK; > + } > > /* Find a vacant FID */ > for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); > @@ -2140,10 +2147,8 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, > return NETDEV_TX_BUSY; > } > } > - /* check min length*/ > - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; > /* Mark fid as used & save length for later */ > - fids[i] |= (len << 16); > + fids[i] |= (skb->len << 16); > priv->xmit.skb = skb; > priv->xmit.fid = i; > if (down_trylock(&priv->sem) != 0) { > @@ -2185,7 +2190,6 @@ static void airo_end_xmit11(struct net_device *dev) { > static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, > struct net_device *dev) > { > - s16 len; > int i, j; > struct airo_info *priv = dev->ml_priv; > u32 *fids = priv->fids; > @@ -2201,6 +2205,10 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, > airo_print_err(dev->name, "%s: skb == NULL!", __func__); > return NETDEV_TX_OK; > } > + if (skb_padto(skb, ETH_ZLEN)) { > + dev->stats.tx_dropped++; > + return NETDEV_TX_OK; > + } > > /* Find a vacant FID */ > for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); > @@ -2214,10 +2222,8 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, > return NETDEV_TX_BUSY; > } > } > - /* check min length*/ > - len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; > /* Mark fid as used & save length for later */ > - fids[i] |= (len << 16); > + fids[i] |= (skb->len << 16); > priv->xmit11.skb = skb; > priv->xmit11.fid = i; > if (down_trylock(&priv->sem) != 0) { > -- > 2.11.0 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3] airo: Fix read overflows sending packets 2020-05-27 18:08 ` Eric Dumazet @ 2020-05-27 18:48 ` Dan Carpenter 2020-05-28 14:41 ` Sasha Levin ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Dan Carpenter @ 2020-05-27 18:48 UTC (permalink / raw) To: Kalle Valo, Hu Jiahui, Eric Dumazet Cc: security, linux-wireless, Jakub Kicinski The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from skb->data even when skb->len is less than ETH_ZLEN so it leads to a read overflow. The fix is to pad skb->data to at least ETH_ZLEN bytes. Cc: <stable@vger.kernel.org> Reported-by: Hu Jiahui <kirin.say@gmail.com> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> --- v2: remove an unnecessary if statement increment the ->tx_dropped count on failure fix found two more instances of the same bug. fix typo in the "Cc: <stable@vger.kernel.org>" tag v3: I had thought that skb_padto() updated skb->len so that it would always be more than ETH_ZLEN meaning that we could delete the checks for smaller values: "len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;" But I was wrong and those are still required. drivers/net/wireless/cisco/airo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c index 8363f91df7ea7..827bb6d74815a 100644 --- a/drivers/net/wireless/cisco/airo.c +++ b/drivers/net/wireless/cisco/airo.c @@ -1925,6 +1925,10 @@ static netdev_tx_t mpi_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!",__func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } npacks = skb_queue_len (&ai->txq); if (npacks >= MAXTXQ - 1) { @@ -2127,6 +2131,10 @@ static netdev_tx_t airo_start_xmit(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); @@ -2201,6 +2209,10 @@ static netdev_tx_t airo_start_xmit11(struct sk_buff *skb, airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); -- 2.26.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3] airo: Fix read overflows sending packets 2020-05-27 18:48 ` [PATCH v3] " Dan Carpenter @ 2020-05-28 14:41 ` Sasha Levin 2020-05-28 15:55 ` Eric Dumazet 2020-05-29 17:40 ` Kalle Valo 2 siblings, 0 replies; 8+ messages in thread From: Sasha Levin @ 2020-05-28 14:41 UTC (permalink / raw) To: Sasha Levin, Dan Carpenter, Kalle Valo, Hu Jiahui Cc: security, linux-wireless, stable, stable Hi [This is an automated email] This commit has been processed because it contains a -stable tag. The stable tag indicates that it's relevant for the following trees: all The bot has tested the following trees: v5.6.14, v5.4.42, v4.19.124, v4.14.181, v4.9.224, v4.4.224. v5.6.14: Build OK! v5.4.42: Build OK! v4.19.124: Build OK! v4.14.181: Build OK! v4.9.224: Build OK! v4.4.224: Failed to apply! Possible dependencies: Unable to calculate NOTE: The patch will not be queued to stable trees until it is upstream. How should we proceed with this patch? -- Thanks Sasha ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] airo: Fix read overflows sending packets 2020-05-27 18:48 ` [PATCH v3] " Dan Carpenter 2020-05-28 14:41 ` Sasha Levin @ 2020-05-28 15:55 ` Eric Dumazet 2020-05-29 17:40 ` Kalle Valo 2 siblings, 0 replies; 8+ messages in thread From: Eric Dumazet @ 2020-05-28 15:55 UTC (permalink / raw) To: Dan Carpenter Cc: Kalle Valo, Hu Jiahui, Security Officers, linux-wireless, Jakub Kicinski On Wed, May 27, 2020 at 11:48 AM Dan Carpenter <dan.carpenter@oracle.com> wrote: > > The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from > skb->data even when skb->len is less than ETH_ZLEN so it leads to a read > overflow. > > The fix is to pad skb->data to at least ETH_ZLEN bytes. > > Cc: <stable@vger.kernel.org> > Reported-by: Hu Jiahui <kirin.say@gmail.com> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> > --- > v2: remove an unnecessary if statement > increment the ->tx_dropped count on failure > fix found two more instances of the same bug. > fix typo in the "Cc: <stable@vger.kernel.org>" tag > v3: I had thought that skb_padto() updated skb->len so that it would > always be more than ETH_ZLEN meaning that we could delete the checks > for smaller values: "len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;" > But I was wrong and those are still required. > > drivers/net/wireless/cisco/airo.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > Reviewed-by: Eric Dumazet <edumazet@google.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3] airo: Fix read overflows sending packets 2020-05-27 18:48 ` [PATCH v3] " Dan Carpenter 2020-05-28 14:41 ` Sasha Levin 2020-05-28 15:55 ` Eric Dumazet @ 2020-05-29 17:40 ` Kalle Valo 2 siblings, 0 replies; 8+ messages in thread From: Kalle Valo @ 2020-05-29 17:40 UTC (permalink / raw) To: Dan Carpenter Cc: Hu Jiahui, Eric Dumazet, security, linux-wireless, Jakub Kicinski Dan Carpenter <dan.carpenter@oracle.com> wrote: > The problem is that we always copy a minimum of ETH_ZLEN (60) bytes from > skb->data even when skb->len is less than ETH_ZLEN so it leads to a read > overflow. > > The fix is to pad skb->data to at least ETH_ZLEN bytes. > > Cc: <stable@vger.kernel.org> > Reported-by: Hu Jiahui <kirin.say@gmail.com> > Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> > Reviewed-by: Eric Dumazet <edumazet@google.com> Patch applied to wireless-drivers-next.git, thanks. 11e7a91994c2 airo: Fix read overflows sending packets -- https://patchwork.kernel.org/patch/11573765/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-05-29 17:40 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <EED43E20-9B88-42EC-80B0-0245F0FAF980@gmail.com> 2020-05-27 13:36 ` [PATCH resend] airo: Fix read overflow in mpi_send_packet() Dan Carpenter 2020-05-27 16:52 ` Eric Dumazet 2020-05-27 17:58 ` [PATCH v2] airo: Fix read overflows sending packets Dan Carpenter 2020-05-27 18:08 ` Eric Dumazet 2020-05-27 18:48 ` [PATCH v3] " Dan Carpenter 2020-05-28 14:41 ` Sasha Levin 2020-05-28 15:55 ` Eric Dumazet 2020-05-29 17:40 ` Kalle Valo
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.