Re: [PATCH] net: bonding: fix error return code of bond_neigh_init()

2021-03-10 Thread Jia-Ju Bai




On 2021/3/10 17:24, Roi Dayan wrote:



On 2021-03-08 5:11 AM, Jia-Ju Bai wrote:

When slave is NULL or slave_ops->ndo_neigh_setup is NULL, no error
return code of bond_neigh_init() is assigned.
To fix this bug, ret is assigned with -EINVAL in these cases.

Fixes: 9e99bfefdbce ("bonding: fix bond_neigh_init()")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
  drivers/net/bonding/bond_main.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c 
b/drivers/net/bonding/bond_main.c

index 74cbbb22470b..456315bef3a8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3978,11 +3978,15 @@ static int bond_neigh_init(struct neighbour *n)
    rcu_read_lock();
  slave = bond_first_slave_rcu(bond);
-    if (!slave)
+    if (!slave) {
+    ret = -EINVAL;
  goto out;
+    }
  slave_ops = slave->dev->netdev_ops;
-    if (!slave_ops->ndo_neigh_setup)
+    if (!slave_ops->ndo_neigh_setup) {
+    ret = -EINVAL;
  goto out;
+    }
    /* TODO: find another way [1] to implement this.
   * Passing a zeroed structure is fragile,




Hi,

This breaks basic functionally that always worked. A slave doesn't need
to exists nor to implement ndo_neigh_setup.
Now trying to add a neigh entry because of that fails.
This commit needs to be reverted.



Okay, thanks for the explanation, and I am sorry for this false report...


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: bridge: fix error return code of do_update_counters()

2021-03-09 Thread Jia-Ju Bai




On 2021/3/9 19:01, Florian Westphal wrote:

Jia-Ju Bai  wrote:

When find_table_lock() returns NULL to t, no error return code of
do_update_counters() is assigned.

Its -ENOENT.


t = find_table_lock(net, name, &ret, &ebt_mutex);

^

ret is passed to find_table_lock, which passes it to
find_inlist_lock_noload() which will set *ret = -ENOENT
for NULL case.


Thanks for the reply!
I did not notice "&ret" in find_table_lock()...
I am sorry for the false positive.


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: netlink: fix error return code of netlink_proto_init()

2021-03-09 Thread Jia-Ju Bai




On 2021/3/9 16:47, Heiner Kallweit wrote:

On 09.03.2021 09:33, Jia-Ju Bai wrote:

When kcalloc() returns NULL to nl_table, no error return code of
netlink_proto_init() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.


Didn't we talk enough about your incorrect patches yesterday?
This one is incorrect again. panic() never returns.
Stop sending patches until you understand the code you're changing!


Ah, sorry, I was too confident about this bug report...
Thanks for your reply.
Following your advice, now I am sending the patches only for the bug 
reports that I am confident about after careful code review.
Some of the patches have been applied, but some of them are still wrong, 
like this patch...

I am sorry for the false positives...


Best wishes,
Jia-Ju Bai


[PATCH] net: netlink: fix error return code of netlink_proto_init()

2021-03-09 Thread Jia-Ju Bai
When kcalloc() returns NULL to nl_table, no error return code of
netlink_proto_init() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.

Fixes: fab2caf62ed0 ("[NETLINK]: Call panic if nl_table allocation fails")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/netlink/af_netlink.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index dd488938447f..9ab66cfb1037 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2880,8 +2880,10 @@ static int __init netlink_proto_init(void)
BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof_field(struct 
sk_buff, cb));
 
nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
-   if (!nl_table)
+   if (!nl_table) {
+   err = -ENOMEM;
goto panic;
+   }
 
for (i = 0; i < MAX_LINKS; i++) {
if (rhashtable_init(&nl_table[i].hash,
-- 
2.17.1



Re: [PATCH] net: mellanox: mlx5: fix error return code of mlx5e_stats_flower()

2021-03-09 Thread Jia-Ju Bai




On 2021/3/9 16:24, Roi Dayan wrote:



On 2021-03-09 10:20 AM, Roi Dayan wrote:



On 2021-03-06 3:47 PM, Jia-Ju Bai wrote:

When mlx5e_tc_get_counter() returns NULL to counter or
mlx5_devcom_get_peer_data() returns NULL to peer_esw, no error return
code of mlx5e_stats_flower() is assigned.
To fix this bug, err is assigned with -EINVAL in these cases.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
  drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

index 0da69b98f38f..1f2c9da7bd35 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -4380,8 +4380,10 @@ int mlx5e_stats_flower(struct net_device 
*dev, struct mlx5e_priv *priv,

  if (mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, CT)) {
  counter = mlx5e_tc_get_counter(flow);
-    if (!counter)
+    if (!counter) {
+    err = -EINVAL;
  goto errout;
+    }
  mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
  }
@@ -4390,8 +4392,10 @@ int mlx5e_stats_flower(struct net_device 
*dev, struct mlx5e_priv *priv,

   * un-offloaded while the other rule is offloaded.
   */
  peer_esw = mlx5_devcom_get_peer_data(devcom, 
MLX5_DEVCOM_ESW_OFFLOADS);

-    if (!peer_esw)
+    if (!peer_esw) {
+    err = -EINVAL;


note here it's not an error. it could be there is no peer esw
so just continue with the stats update.


  goto out;
+    }
  if (flow_flag_test(flow, DUP) &&
  flow_flag_test(flow->peer_flow, OFFLOADED)) {
@@ -4400,8 +4404,10 @@ int mlx5e_stats_flower(struct net_device 
*dev, struct mlx5e_priv *priv,

  u64 lastuse2;
  counter = mlx5e_tc_get_counter(flow->peer_flow);
-    if (!counter)
+    if (!counter) {
+    err = -EINVAL;


this change is problematic. the current goto is to do stats update with
the first counter stats we got but if you now want to return an error
then you probably should not do any update at all.


Thanks for your reply :)
I am not sure whether an error code should be returned here?
If so, flow_stats_update(...) should not be called here?


Best wishes,
Jia-Ju Bai




  goto no_peer_counter;
+    }
  mlx5_fc_query_cached(counter, &bytes2, &packets2, &lastuse2);
  bytes += bytes2;








[PATCH] net: bridge: fix error return code of do_update_counters()

2021-03-08 Thread Jia-Ju Bai
When find_table_lock() returns NULL to t, no error return code of
do_update_counters() is assigned.
To fix this bug, ret is assigned with -ENOENT in this case.

Fixes: 49facff9f925 ("netfilter: ebtables: split update_counters into two 
functions")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/bridge/netfilter/ebtables.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index ebe33b60efd6..66c9e4077985 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1256,8 +1256,10 @@ static int do_update_counters(struct net *net, const 
char *name,
return -ENOMEM;
 
t = find_table_lock(net, name, &ret, &ebt_mutex);
-   if (!t)
+   if (!t) {
+   ret = -ENOENT;
goto free_tmp;
+   }
 
if (num_counters != t->private->nentries) {
ret = -EINVAL;
-- 
2.17.1



Re: [PATCH] net: ieee802154: fix error return code of dgram_sendmsg()

2021-03-08 Thread Jia-Ju Bai




On 2021/3/8 21:33, Heiner Kallweit wrote:

On 08.03.2021 13:18, Jia-Ju Bai wrote:


On 2021/3/8 18:19, Heiner Kallweit wrote:

On 08.03.2021 10:31, Jia-Ju Bai wrote:

When sock_alloc_send_skb() returns NULL to skb, no error return code of
dgram_sendmsg() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.


Please stop sending such nonsense. Basically all such patches you
sent so far are false positives. You have to start thinking,
don't blindly trust your robot.
In the case here the err variable is populated by sock_alloc_send_skb().

Ah, sorry, it is my fault :(
I did not notice that the err variable is populated by sock_alloc_send_skb().
I will think more carefully before sending patches.

By the way, I wonder how to report and discuss possible bugs that I am not 
quite sure of?
Some people told me that sending patches is better than reporting bugs via 
Bugzilla, so I write the patches of these possible bugs...
Do you have any advice?


If you're quite sure that something is a bug then sending a patch is fine.
Your submissions more or less all being false positives shows that this
takes more than just forwarding bot findings, especially if you have no
idea yet regarding the quality of the bot.
Alternatively you can contact the maintainer and respective mailing list.
But again, maintainers typically are very busy and you should have done
all you can to analyze the suspected bug.

What I'd do being in your shoes:
Take the first 10 findings of a new bot and analyze in detail whether
findings are correct or false positives. Of course this means you
need to get familiar with the affected code in the respective driver.
If false positive ratio is > 5% I wouldn't send out patches w/o more
detailed analysis per finding.

Worst case a maintainer is busy and can't review your submission in time,
and the incorrect fix is applied and breaks the driver.
Typically this shouldn't happen however because Dave/Jakub won't apply
a patch w/o Ack from the respective maintainer.

Disclaimer:
I can only speak for myself. Other maintainers may see this differently.


Okay, thanks a lot for the very helpful advice :)
I will carefully check the bug report and try my best to write correct 
patches.



Best wishes,
Jia-Ju Bai


Re: [PATCH] net: ieee802154: fix error return code of dgram_sendmsg()

2021-03-08 Thread Jia-Ju Bai




On 2021/3/8 18:19, Heiner Kallweit wrote:

On 08.03.2021 10:31, Jia-Ju Bai wrote:

When sock_alloc_send_skb() returns NULL to skb, no error return code of
dgram_sendmsg() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.


Please stop sending such nonsense. Basically all such patches you
sent so far are false positives. You have to start thinking,
don't blindly trust your robot.
In the case here the err variable is populated by sock_alloc_send_skb().


Ah, sorry, it is my fault :(
I did not notice that the err variable is populated by 
sock_alloc_send_skb().

I will think more carefully before sending patches.

By the way, I wonder how to report and discuss possible bugs that I am 
not quite sure of?
Some people told me that sending patches is better than reporting bugs 
via Bugzilla, so I write the patches of these possible bugs...

Do you have any advice?

Thanks a lot!


Best wishes,
Jia-Ju Bai



Fixes: 78f821b64826 ("ieee802154: socket: put handling into one file")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
  net/ieee802154/socket.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index a45a0401adc5..a750b37c7e73 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -642,8 +642,10 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr 
*msg, size_t size)
skb = sock_alloc_send_skb(sk, hlen + tlen + size,
  msg->msg_flags & MSG_DONTWAIT,
  &err);
-   if (!skb)
+   if (!skb) {
+   err = -ENOMEM;
goto out_dev;
+   }
  
  	skb_reserve(skb, hlen);
  





[PATCH] net: ieee802154: fix error return code of dgram_sendmsg()

2021-03-08 Thread Jia-Ju Bai
When sock_alloc_send_skb() returns NULL to skb, no error return code of
dgram_sendmsg() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.

Fixes: 78f821b64826 ("ieee802154: socket: put handling into one file")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/ieee802154/socket.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index a45a0401adc5..a750b37c7e73 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -642,8 +642,10 @@ static int dgram_sendmsg(struct sock *sk, struct msghdr 
*msg, size_t size)
skb = sock_alloc_send_skb(sk, hlen + tlen + size,
  msg->msg_flags & MSG_DONTWAIT,
  &err);
-   if (!skb)
+   if (!skb) {
+   err = -ENOMEM;
goto out_dev;
+   }
 
skb_reserve(skb, hlen);
 
-- 
2.17.1



[PATCH] net: ieee802154: fix error return code of raw_sendmsg()

2021-03-08 Thread Jia-Ju Bai
When sock_alloc_send_skb() returns NULL to skb, no error return code of
raw_sendmsg() is assigned.
To fix this bug, err is assigned with -ENOMEM in this case.

Fixes: 78f821b64826 ("ieee802154: socket: put handling into one file")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/ieee802154/socket.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index a45a0401adc5..3d76b207385e 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -277,8 +277,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr 
*msg, size_t size)
tlen = dev->needed_tailroom;
skb = sock_alloc_send_skb(sk, hlen + tlen + size,
  msg->msg_flags & MSG_DONTWAIT, &err);
-   if (!skb)
+   if (!skb) {
+   err = -ENOMEM;
goto out_dev;
+   }
 
skb_reserve(skb, hlen);
 
-- 
2.17.1



[PATCH] net: qrtr: fix error return code of qrtr_sendmsg()

2021-03-08 Thread Jia-Ju Bai
When sock_alloc_send_skb() returns NULL to skb, no error return code of
qrtr_sendmsg() is assigned.
To fix this bug, rc is assigned with -ENOMEM in this case.

Fixes: 194ccc88297a ("net: qrtr: Support decoding incoming v2 packets")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/qrtr/qrtr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index b34358282f37..ac2a4a7711da 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -958,8 +958,10 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr 
*msg, size_t len)
plen = (len + 3) & ~3;
skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE,
  msg->msg_flags & MSG_DONTWAIT, &rc);
-   if (!skb)
+   if (!skb) {
+   rc = -ENOMEM;
goto out_node;
+   }
 
skb_reserve(skb, QRTR_HDR_MAX_SIZE);
 
-- 
2.17.1



[PATCH] net: bonding: fix error return code of bond_neigh_init()

2021-03-07 Thread Jia-Ju Bai
When slave is NULL or slave_ops->ndo_neigh_setup is NULL, no error
return code of bond_neigh_init() is assigned.
To fix this bug, ret is assigned with -EINVAL in these cases.

Fixes: 9e99bfefdbce ("bonding: fix bond_neigh_init()")
Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/bonding/bond_main.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 74cbbb22470b..456315bef3a8 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3978,11 +3978,15 @@ static int bond_neigh_init(struct neighbour *n)
 
rcu_read_lock();
slave = bond_first_slave_rcu(bond);
-   if (!slave)
+   if (!slave) {
+   ret = -EINVAL;
goto out;
+   }
slave_ops = slave->dev->netdev_ops;
-   if (!slave_ops->ndo_neigh_setup)
+   if (!slave_ops->ndo_neigh_setup) {
+   ret = -EINVAL;
goto out;
+   }
 
/* TODO: find another way [1] to implement this.
 * Passing a zeroed structure is fragile,
-- 
2.17.1



Re: [PATCH] ath: ath6kl: fix error return code of ath6kl_htc_rx_bundle()

2021-03-07 Thread Jia-Ju Bai

Hi Leon,

I am quite sorry for my incorrect patches...
My static analysis tool reports some possible bugs about error handling 
code, and thus I write some patches for the bugs that seem to be true in 
my opinion.
Because I am not familiar with many device drivers, some of my reported 
bugs can be false positives...



Best wishes,
Jia-Ju Bai

On 2021/3/7 17:18, Leon Romanovsky wrote:

On Sun, Mar 07, 2021 at 01:07:57AM -0800, Jia-Ju Bai wrote:

When hif_scatter_req_get() returns NULL to scat_req, no error return
code of ath6kl_htc_rx_bundle() is assigned.
To fix this bug, status is assigned with -EINVAL in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
  drivers/net/wireless/ath/ath6kl/htc_mbox.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c 
b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 998947ef63b6..3f8857d19a0c 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -1944,8 +1944,10 @@ static int ath6kl_htc_rx_bundle(struct htc_target 
*target,

scat_req = hif_scatter_req_get(target->dev->ar);

-   if (scat_req == NULL)
+   if (scat_req == NULL) {
+   status = -EINVAL;

I'm not sure about it.

David. Jakub,
Please be warned that patches from this guy are not so great.
I looked on 4 patches and 3 of them were wrong (2 in RDMA and 1 for mlx5)
plus this patch most likely is incorrect too.



[PATCH] net: wan: fix error return code of uhdlc_init()

2021-03-07 Thread Jia-Ju Bai
When priv->rx_skbuff or priv->tx_skbuff is NULL, no error return code of
uhdlc_init() is assigned.
To fix this bug, ret is assigned with -ENOMEM in these cases.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wan/fsl_ucc_hdlc.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c
index dca97cd7c4e7..7eac6a3e1cde 100644
--- a/drivers/net/wan/fsl_ucc_hdlc.c
+++ b/drivers/net/wan/fsl_ucc_hdlc.c
@@ -204,14 +204,18 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
priv->rx_skbuff = kcalloc(priv->rx_ring_size,
  sizeof(*priv->rx_skbuff),
  GFP_KERNEL);
-   if (!priv->rx_skbuff)
+   if (!priv->rx_skbuff) {
+   ret = -ENOMEM;
goto free_ucc_pram;
+   }
 
priv->tx_skbuff = kcalloc(priv->tx_ring_size,
  sizeof(*priv->tx_skbuff),
  GFP_KERNEL);
-   if (!priv->tx_skbuff)
+   if (!priv->tx_skbuff) {
+   ret = -ENOMEM;
goto free_rx_skbuff;
+   }
 
priv->skb_curtx = 0;
priv->skb_dirtytx = 0;
-- 
2.17.1



[PATCH] ath: ath6kl: fix error return code of ath6kl_htc_rx_bundle()

2021-03-07 Thread Jia-Ju Bai
When hif_scatter_req_get() returns NULL to scat_req, no error return
code of ath6kl_htc_rx_bundle() is assigned.
To fix this bug, status is assigned with -EINVAL in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/ath/ath6kl/htc_mbox.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c 
b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
index 998947ef63b6..3f8857d19a0c 100644
--- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c
+++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c
@@ -1944,8 +1944,10 @@ static int ath6kl_htc_rx_bundle(struct htc_target 
*target,
 
scat_req = hif_scatter_req_get(target->dev->ar);
 
-   if (scat_req == NULL)
+   if (scat_req == NULL) {
+   status = -EINVAL;
goto fail_rx_pkt;
+   }
 
for (i = 0; i < n_scat_pkt; i++) {
int pad_len;
-- 
2.17.1



[PATCH] net: hisilicon: hns: fix error return code of hns_nic_clear_all_rx_fetch()

2021-03-07 Thread Jia-Ju Bai
When hns_assemble_skb() returns NULL to skb, no error return code of
hns_nic_clear_all_rx_fetch() is assigned.
To fix this bug, ret is assigned with -ENOMEM in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 5d7824d2b4d4..c66a7a51198e 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -1663,8 +1663,10 @@ static int hns_nic_clear_all_rx_fetch(struct net_device 
*ndev)
for (j = 0; j < fetch_num; j++) {
/* alloc one skb and init */
skb = hns_assemble_skb(ndev);
-   if (!skb)
+   if (!skb) {
+   ret = -ENOMEM;
goto out;
+   }
rd = &tx_ring_data(priv, skb->queue_mapping);
hns_nic_net_xmit_hw(ndev, skb, rd);
 
-- 
2.17.1



[PATCH] rsi: fix error return code of rsi_load_9116_firmware()

2021-03-07 Thread Jia-Ju Bai
When kmemdup() returns NULL to ta_firmware, no error return code of
rsi_load_9116_firmware() is assigned.
To fix this bug, status is assigned with -ENOMEM in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/rsi/rsi_91x_hal.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c 
b/drivers/net/wireless/rsi/rsi_91x_hal.c
index ce9892152f4d..32ecb8b3d6c5 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -1038,8 +1038,10 @@ static int rsi_load_9116_firmware(struct rsi_hw *adapter)
}
 
ta_firmware = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
-   if (!ta_firmware)
+   if (!ta_firmware) {
+   status = -ENOMEM;
goto fail_release_fw;
+   }
fw_p = ta_firmware;
instructions_sz = fw_entry->size;
rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", instructions_sz);
-- 
2.17.1



[PATCH] ti: wlcore: fix error return code of wl1271_cmd_build_ps_poll()

2021-03-07 Thread Jia-Ju Bai
When ieee80211_pspoll_get() returns NULL to skb, no error return code of
wl1271_cmd_build_ps_poll() is assigned.
To fix this bug, ret is assigned with -ENOMEM in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/ti/wlcore/cmd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c 
b/drivers/net/wireless/ti/wlcore/cmd.c
index 32a2e27cc561..7bf8b8201fdd 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1120,8 +1120,10 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct 
wl12xx_vif *wlvif,
int ret = 0;
 
skb = ieee80211_pspoll_get(wl->hw, vif);
-   if (!skb)
+   if (!skb) {
+   ret = -ENOMEM;
goto out;
+   }
 
ret = wl1271_cmd_template_set(wl, wlvif->role_id,
  CMD_TEMPL_PS_POLL, skb->data,
-- 
2.17.1



[PATCH] ti: wlcore: fix error return code of wl1271_suspend()

2021-03-06 Thread Jia-Ju Bai
When wl is NULL, no error return code of wl1271_suspend() is assigned.
To fix this bug, ret is assigned with -EINVAL in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/ti/wlcore/sdio.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ti/wlcore/sdio.c 
b/drivers/net/wireless/ti/wlcore/sdio.c
index 9fd8cf2d270c..a040d595a43a 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -390,6 +390,7 @@ static int wl1271_suspend(struct device *dev)
 
if (!wl) {
dev_err(dev, "no wilink module was probed\n");
+   ret = -EINVAL;
goto out;
}
 
-- 
2.17.1



[PATCH] net: mellanox: mlxsw: fix error return code of mlxsw_sp_router_nve_promote_decap()

2021-03-06 Thread Jia-Ju Bai
When fib_entry is NULL, no error return code of
mlxsw_sp_router_nve_promote_decap() is assigned.
To fix this bug, err is assigned with -EINVAL in this case.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 9ce90841f92d..7b260e25df1b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1981,8 +1981,10 @@ int mlxsw_sp_router_nve_promote_decap(struct mlxsw_sp 
*mlxsw_sp, u32 ul_tb_id,
fib_entry = mlxsw_sp_router_ip2me_fib_entry_find(mlxsw_sp, ul_tb_id,
 ul_proto, ul_sip,
 type);
-   if (!fib_entry)
+   if (!fib_entry) {
+   err = -EINVAL;
goto out;
+   }
 
fib_entry->decap.tunnel_index = tunnel_index;
fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP;
-- 
2.17.1



[PATCH] net: mellanox: mlx5: fix error return code of mlx5e_stats_flower()

2021-03-06 Thread Jia-Ju Bai
When mlx5e_tc_get_counter() returns NULL to counter or
mlx5_devcom_get_peer_data() returns NULL to peer_esw, no error return 
code of mlx5e_stats_flower() is assigned.
To fix this bug, err is assigned with -EINVAL in these cases.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c 
b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 0da69b98f38f..1f2c9da7bd35 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -4380,8 +4380,10 @@ int mlx5e_stats_flower(struct net_device *dev, struct 
mlx5e_priv *priv,
 
if (mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, CT)) {
counter = mlx5e_tc_get_counter(flow);
-   if (!counter)
+   if (!counter) {
+   err = -EINVAL;
goto errout;
+   }
 
mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
}
@@ -4390,8 +4392,10 @@ int mlx5e_stats_flower(struct net_device *dev, struct 
mlx5e_priv *priv,
 * un-offloaded while the other rule is offloaded.
 */
peer_esw = mlx5_devcom_get_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
-   if (!peer_esw)
+   if (!peer_esw) {
+   err = -EINVAL;
goto out;
+   }
 
if (flow_flag_test(flow, DUP) &&
flow_flag_test(flow->peer_flow, OFFLOADED)) {
@@ -4400,8 +4404,10 @@ int mlx5e_stats_flower(struct net_device *dev, struct 
mlx5e_priv *priv,
u64 lastuse2;
 
counter = mlx5e_tc_get_counter(flow->peer_flow);
-   if (!counter)
+   if (!counter) {
+   err = -EINVAL;
goto no_peer_counter;
+   }
mlx5_fc_query_cached(counter, &bytes2, &packets2, &lastuse2);
 
bytes += bytes2;
-- 
2.17.1



[PATCH] net: smc: fix error return code of smc_diag_dump_proto()

2021-03-05 Thread Jia-Ju Bai
When the list of head is empty, no error return code of
smc_diag_dump_proto() is assigned.
To fix this bug, rc is assigned with -ENOENT as error return code.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/smc/smc_diag.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/smc/smc_diag.c b/net/smc/smc_diag.c
index c952986a6aca..a90889482842 100644
--- a/net/smc/smc_diag.c
+++ b/net/smc/smc_diag.c
@@ -201,8 +201,10 @@ static int smc_diag_dump_proto(struct proto *prot, struct 
sk_buff *skb,
 
read_lock(&prot->h.smc_hash->lock);
head = &prot->h.smc_hash->ht;
-   if (hlist_empty(head))
+   if (hlist_empty(head)) {
+   rc = -ENOENT;
goto out;
+   }
 
sk_for_each(sk, head) {
if (!net_eq(sock_net(sk), net))
-- 
2.17.1



[PATCH] net: xdp: fix error return code of xsk_generic_xmit()

2021-03-05 Thread Jia-Ju Bai
When err is zero but xskq_prod_reserve() fails, no error return code of
xsk_generic_xmit() is assigned.
To fix this bug, err is assigned with the return value of
xskq_prod_reserve(), and then err is checked.
The spinlock is only used to protect the call to xskq_prod_reserve().

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 net/xdp/xsk.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 4faabd1ecfd1..f1c1db07dd07 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -484,8 +484,14 @@ static int xsk_generic_xmit(struct sock *sk)
 * if there is space in it. This avoids having to implement
 * any buffering in the Tx path.
 */
+   if (unlikely(err)) {
+   kfree_skb(skb);
+   goto out;
+   }
+
spin_lock_irqsave(&xs->pool->cq_lock, flags);
-   if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) {
+   err = xskq_prod_reserve(xs->pool->cq);
+   if (unlikely(err)) {
spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
kfree_skb(skb);
goto out;
-- 
2.17.1



[PATCH] marvell: libertas_tf: fix error return code of if_usb_prog_firmware()

2021-03-04 Thread Jia-Ju Bai
When check_fwfile_format() fails, no error return code of
if_usb_prog_firmware() is assigned.
To fix this bug, ret is assigned with -EINVAL as error return code.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/marvell/libertas_tf/if_usb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c 
b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
index a92916dc81a9..ceca22da5a29 100644
--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
@@ -825,8 +825,10 @@ static int if_usb_prog_firmware(struct lbtf_private *priv)
}
kernel_param_unlock(THIS_MODULE);
 
-   if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
+   if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) {
+   ret = -EINVAL;
goto release_fw;
+   }
 
 restart:
if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
-- 
2.17.1



[PATCH] net: intel: iavf: fix error return code of iavf_init_get_resources()

2021-03-04 Thread Jia-Ju Bai
When iavf_process_config() fails, no error return code of
iavf_init_get_resources() is assigned.
To fix this bug, err is assigned with the return value of 
iavf_process_config(), and then err is checked.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/intel/iavf/iavf_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c 
b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 0a867d64d467..dc5b3c06d1e0 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -1776,7 +1776,8 @@ static int iavf_init_get_resources(struct iavf_adapter 
*adapter)
goto err_alloc;
}
 
-   if (iavf_process_config(adapter))
+   err = iavf_process_config(adapter);
+   if (err)
goto err_alloc;
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
 
-- 
2.17.1



[PATCH] net: tehuti: fix error return code in bdx_probe()

2021-03-04 Thread Jia-Ju Bai
When bdx_read_mac() fails, no error return code of bdx_probe() 
is assigned.
To fix this bug, err is assigned with -EFAULT as error return code.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/tehuti/tehuti.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/tehuti/tehuti.c 
b/drivers/net/ethernet/tehuti/tehuti.c
index b8f4f419173f..d054c6e83b1c 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -2044,6 +2044,7 @@ bdx_probe(struct pci_dev *pdev, const struct 
pci_device_id *ent)
/*bdx_hw_reset(priv); */
if (bdx_read_mac(priv)) {
pr_err("load MAC address failed\n");
+   err = -EFAULT;
goto err_out_iomap;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
-- 
2.17.1



[PATCH] net: mellanox: mlx5: fix error return code in mlx5_fpga_device_start()

2021-03-04 Thread Jia-Ju Bai
When mlx5_is_fpga_lookaside() returns a non-zero value, no error 
return code is assigned.
To fix this bug, err is assigned with -EINVAL as error return code.

Reported-by: TOTE Robot 
Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c 
b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c
index 2ce4241459ce..c9e6da97126f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c
@@ -198,8 +198,10 @@ int mlx5_fpga_device_start(struct mlx5_core_dev *mdev)
mlx5_fpga_info(fdev, "FPGA card %s:%u\n", mlx5_fpga_name(fpga_id), 
fpga_id);
 
/* No QPs if FPGA does not participate in net processing */
-   if (mlx5_is_fpga_lookaside(fpga_id))
+   if (mlx5_is_fpga_lookaside(fpga_id)) {
+   err = -EINVAL;
goto out;
+   }
 
mlx5_fpga_info(fdev, "%s(%d): image, version %u; SBU %06x:%04x version 
%d\n",
   mlx5_fpga_image_name(fdev->last_oper_image),
-- 
2.17.1



Re: [PATCH v2 1/4] rtlwifi: rtl8188ee: avoid accessing the data mapped to streaming DMA

2020-11-18 Thread Jia-Ju Bai

Thanks for the advice.
I have added the description of the changes and resent the patches.


Best wishes,
Jia-Ju Bai

On 2020/11/19 1:20, Larry Finger wrote:

On 11/17/20 7:53 PM, Jia-Ju Bai wrote:

In rtl88ee_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 677:
   dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 680, skb->data is assigned to hdr after cast:
   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 681:
   __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
  drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)


What changed between v1 and v2?

As outlined in Documentation/process/submitting-patches.rst, you 
should add a '---' marker and descrive what was changed. I usually 
summarize the changes, but it is also possible to provide a diffstat 
of the changes as the above file shows.




[PATCH v2 3/4 resend] rtlwifi: rtl8192de: avoid accessing the data mapped to streaming DMA

2020-11-18 Thread Jia-Ju Bai
In rtl92de_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 667:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 669, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 670:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use "rtlwifi" as subject prefix and have all rtlwifi patches in the
  same pathset.
  Thank Ping and Larry for good advice.

---
 drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
index 8944712274b5..c02813fba934 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
@@ -664,12 +664,14 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
+
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 2/4 resend] rtlwifi: rtl8192ce: avoid accessing the data mapped to streaming DMA

2020-11-18 Thread Jia-Ju Bai
In rtl92ce_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 530:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 533, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 534:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use "rtlwifi" as subject prefix and have all rtlwifi patches in the
  same pathset.
  Thank Ping and Larry for good advice.

---
 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
index c0635309a92d..4165175cf5c0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
@@ -527,12 +527,12 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 4/4 resend] rtlwifi: rtl8723ae: avoid accessing the data mapped to streaming DMA

2020-11-18 Thread Jia-Ju Bai
In rtl8723e_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 531:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 534, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 535:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use "rtlwifi" as subject prefix and have all rtlwifi patches in the
  same pathset.
  Thank Ping and Larry for good advice.

---
 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
index e3ee91b7ea8d..340b3d68a54e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
@@ -528,12 +528,12 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 1/4 resend] rtlwifi: rtl8188ee: avoid accessing the data mapped to streaming DMA

2020-11-18 Thread Jia-Ju Bai
In rtl88ee_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 677:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 680, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 681:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
v2: 
* Use "rtlwifi" as subject prefix and have all rtlwifi patches in the
  same pathset.
  Thank Ping and Larry for good advice.

---
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index b9775eec4c54..c948dafa0c80 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
@@ -674,12 +674,12 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 4/4] rtlwifi: rtl8723ae: avoid accessing the data mapped to streaming DMA

2020-11-17 Thread Jia-Ju Bai
In rtl8723e_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 531:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 534, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 535:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
index e3ee91b7ea8d..340b3d68a54e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
@@ -528,12 +528,12 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



Re: [PATCH] rtl8192ce: avoid accessing the data mapped to streaming DMA

2020-11-17 Thread Jia-Ju Bai




On 2020/11/7 19:44, Kalle Valo wrote:

Jia-Ju Bai  wrote:


In rtl92ce_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 530:
   dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 533, skb->data is assigned to hdr after cast:
   struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 534:
   __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 

Like Ping said, use "rtlwifi:" prefix and have all rtlwifi patches in
the same patchset.

4 patches set to Changes Requested.

11843533 rtl8192ce: avoid accessing the data mapped to streaming DMA
11843541 rtl8192de: avoid accessing the data mapped to streaming DMA
11843553 rtl8723ae: avoid accessing the data mapped to streaming DMA
11843557 rtl8188ee: avoid accessing the data mapped to streaming DMA



Okay, I have sent v2 patches just now.
Please have a look, thank :)


Best wishes,
Jia-Ju Bai


[PATCH v2 3/4] rtlwifi: rtl8192de: avoid accessing the data mapped to streaming DMA

2020-11-17 Thread Jia-Ju Bai
In rtl92de_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 667:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 669, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 670:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
index 8944712274b5..c02813fba934 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
@@ -664,12 +664,14 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
+
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 2/4] rtlwifi: rtl8192ce: avoid accessing the data mapped to streaming DMA

2020-11-17 Thread Jia-Ju Bai
In rtl92ce_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 530:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 533, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 534:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
index c0635309a92d..4165175cf5c0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
@@ -527,12 +527,12 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH v2 1/4] rtlwifi: rtl8188ee: avoid accessing the data mapped to streaming DMA

2020-11-17 Thread Jia-Ju Bai
In rtl88ee_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 677:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 680, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 681:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index b9775eec4c54..c948dafa0c80 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
@@ -674,12 +674,12 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH] rtl8188ee: avoid accessing the data mapped to streaming DMA

2020-10-18 Thread Jia-Ju Bai
In rtl88ee_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 677:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 680, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 681:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index b9775eec4c54..c948dafa0c80 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
@@ -674,12 +674,12 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH] rtl8723ae: avoid accessing the data mapped to streaming DMA

2020-10-18 Thread Jia-Ju Bai
In rtl8723e_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 531:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 534, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 535:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
index e3ee91b7ea8d..340b3d68a54e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
@@ -528,12 +528,12 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH] rtl8192de: avoid accessing the data mapped to streaming DMA

2020-10-18 Thread Jia-Ju Bai
In rtl92de_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 667:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 669, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 670:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
index 8944712274b5..c02813fba934 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c
@@ -664,12 +664,14 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
u8 fw_queue = QSLT_BEACON;
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
+
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
__le32 *pdesc = (__le32 *)pdesc8;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH] rtl8192ce: avoid accessing the data mapped to streaming DMA

2020-10-18 Thread Jia-Ju Bai
In rtl92ce_tx_fill_cmddesc(), skb->data is mapped to streaming DMA on
line 530:
  dma_addr_t mapping = dma_map_single(..., skb->data, ...);

On line 533, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);

Then hdr->frame_control is accessed on line 534:
  __le16 fc = hdr->frame_control;

This DMA access may cause data inconsistency between CPU and hardwre.

To fix this bug, hdr->frame_control is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c 
b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
index c0635309a92d..4165175cf5c0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/trx.c
@@ -527,12 +527,12 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
u8 fw_queue = QSLT_BEACON;
__le32 *pdesc = (__le32 *)pdesc8;
 
-   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
-   skb->len, DMA_TO_DEVICE);
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control;
 
+   dma_addr_t mapping = dma_map_single(&rtlpci->pdev->dev, skb->data,
+   skb->len, DMA_TO_DEVICE);
+
if (dma_mapping_error(&rtlpci->pdev->dev, mapping)) {
rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
"DMA mapping error\n");
-- 
2.17.1



[PATCH] rtl8180: avoid accessing the data mapped to streaming DMA

2020-10-18 Thread Jia-Ju Bai
In rtl8180_tx(), skb->data is mapped to streaming DMA on line 476:
  mapping = dma_map_single(..., skb->data, ...);

On line 459, skb->data is assigned to hdr after cast:
  struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;

Then hdr->seq_ctrl is accessed on lines 540 and 541:
  hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
  hdr->seq_ctrl |= cpu_to_le16(priv->seqno);

These DMA accesses may cause data inconsistency between CPU and hardwre.

To fix this problem, hdr->seq_ctrl is accessed before the DMA mapping.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c 
b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
index 2477e18c7cae..cc73014aa5f3 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c
@@ -473,6 +473,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
prio = skb_get_queue_mapping(skb);
ring = &priv->tx_ring[prio];
 
+   if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+   if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+   priv->seqno += 0x10;
+   hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+   hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
+   }
+
mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
 DMA_TO_DEVICE);
 
@@ -534,13 +541,6 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
 
spin_lock_irqsave(&priv->lock, flags);
 
-   if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-   if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-   priv->seqno += 0x10;
-   hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-   hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
-   }
-
idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
entry = &ring->desc[idx];
 
-- 
2.17.1



Re: [PATCH] net: vmxnet3: avoid accessing the data mapped to streaming DMA

2020-08-03 Thread Jia-Ju Bai




On 2020/8/4 6:59, David Miller wrote:

From: Jia-Ju Bai 
Date: Sun,  2 Aug 2020 21:11:07 +0800


In vmxnet3_probe_device(), "adapter" is mapped to streaming DMA:
   adapter->adapter_pa = dma_map_single(..., adapter, ...);

Then "adapter" is accessed at many places in this function.

Theses accesses may cause data inconsistency between CPU cache and
hardware.

To fix this problem, dma_map_single() is called after these accesses.

Signed-off-by: Jia-Ju Bai 

'adapter' is accessed everywhere, in the entire driver, not just here
in the probe function.


Okay, replacing dma_map_single() with dma_alloc_coherent() may be better.
If you think this solution is okay, I can submit a new patch.


Best wishes,
Jia-Ju Bai



[PATCH] net: sfc: fix possible buffer overflow caused by bad DMA value in efx_siena_sriov_vfdi()

2020-08-02 Thread Jia-Ju Bai
In efx_siena_sriov_vfdi():
  req = vf->buf.addr;

Because "vf->buf.addr" is mapped to coherent DMA (allocated in
efx_nic_alloc_buffer()), "req" is also mapped to DMA.

Then "req->op" is accessed in this function:
  if (req->op < VFDI_OP_LIMIT && vfdi_ops[req->op] != NULL) {
rc = vfdi_ops[req->op](vf);

Because "req" is mapped to DMA, its data can be modified at any time by
malicious or malfunctioning hardware. In this case, the check 
"if (req->op < VFDI_OP_LIMIT)" can be passed, and then "req->op" can be
modified to cause buffer overflow when the driver accesses
"vfdi_ops[req->op]".

To fix this problem, "req->op" is assigned to a local variable, and then
the driver accesses this variable instead of "req->op".

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/sfc/siena_sriov.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/sfc/siena_sriov.c 
b/drivers/net/ethernet/sfc/siena_sriov.c
index 83dcfcae3d4b..21a8482cbb3b 100644
--- a/drivers/net/ethernet/sfc/siena_sriov.c
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -875,6 +875,7 @@ static void efx_siena_sriov_vfdi(struct work_struct *work)
struct vfdi_req *req = vf->buf.addr;
struct efx_memcpy_req copy[2];
int rc;
+   u32 op = req->op;
 
/* Copy this page into the local address space */
memset(copy, '\0', sizeof(copy));
@@ -894,17 +895,17 @@ static void efx_siena_sriov_vfdi(struct work_struct *work)
return;
}
 
-   if (req->op < VFDI_OP_LIMIT && vfdi_ops[req->op] != NULL) {
-   rc = vfdi_ops[req->op](vf);
+   if (op < VFDI_OP_LIMIT && vfdi_ops[op] != NULL) {
+   rc = vfdi_ops[op](vf);
if (rc == 0) {
netif_dbg(efx, hw, efx->net_dev,
  "vfdi request %d from %s ok\n",
- req->op, vf->pci_name);
+ op, vf->pci_name);
}
} else {
netif_dbg(efx, hw, efx->net_dev,
  "ERROR: Unrecognised request %d from VF %s addr "
- "%llx\n", req->op, vf->pci_name,
+ "%llx\n", op, vf->pci_name,
  (unsigned long long)vf->req_addr);
rc = VFDI_RC_EOPNOTSUPP;
}
-- 
2.17.1



[BUG] net: rocker: accessing the data mapped to streaming DMA

2020-08-02 Thread Jia-Ju Bai

In rocker_dma_test_offset(), "buf" is mapped to streaming DMA on line 203:
  dma_handle = pci_map_single(..., buf, ...);

Then, "buf" is accessed on line 229:
  expect[i] = ~buf[i];

This access may cause data inconsistency between CPU cache and hardware.

I am not sure how to properly fix this problem, and thus I only report it.


Best wishes,
Jia-Ju Bai



[PATCH] p54: avoid accessing the data mapped to streaming DMA

2020-08-02 Thread Jia-Ju Bai
In p54p_tx(), skb->data is mapped to streaming DMA on line 337:
  mapping = pci_map_single(..., skb->data, ...);

Then skb->data is accessed on line 349:
  desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;

This access may cause data inconsistency between CPU cache and hardware.

To fix this problem, ((struct p54_hdr *)skb->data)->req_id is stored in
a local variable before DMA mapping, and then the driver accesses this
local variable instead of skb->data.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/intersil/p54/p54pci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intersil/p54/p54pci.c 
b/drivers/net/wireless/intersil/p54/p54pci.c
index 80ad0b7eaef4..f8c6027cab6b 100644
--- a/drivers/net/wireless/intersil/p54/p54pci.c
+++ b/drivers/net/wireless/intersil/p54/p54pci.c
@@ -329,10 +329,12 @@ static void p54p_tx(struct ieee80211_hw *dev, struct 
sk_buff *skb)
struct p54p_desc *desc;
dma_addr_t mapping;
u32 idx, i;
+   __le32 device_addr;
 
spin_lock_irqsave(&priv->lock, flags);
idx = le32_to_cpu(ring_control->host_idx[1]);
i = idx % ARRAY_SIZE(ring_control->tx_data);
+   device_addr = ((struct p54_hdr *)skb->data)->req_id;
 
mapping = pci_map_single(priv->pdev, skb->data, skb->len,
 PCI_DMA_TODEVICE);
@@ -346,7 +348,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct 
sk_buff *skb)
 
desc = &ring_control->tx_data[i];
desc->host_addr = cpu_to_le32(mapping);
-   desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
+   desc->device_addr = device_addr;
desc->len = cpu_to_le16(skb->len);
desc->flags = 0;
 
-- 
2.17.1



[PATCH] net: vmxnet3: avoid accessing the data mapped to streaming DMA

2020-08-02 Thread Jia-Ju Bai
In vmxnet3_probe_device(), "adapter" is mapped to streaming DMA:
  adapter->adapter_pa = dma_map_single(..., adapter, ...);

Then "adapter" is accessed at many places in this function.

Theses accesses may cause data inconsistency between CPU cache and 
hardware.

To fix this problem, dma_map_single() is called after these accesses.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/vmxnet3/vmxnet3_drv.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c 
b/drivers/net/vmxnet3/vmxnet3_drv.c
index ca395f9679d0..96a4c28ba429 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3445,14 +3445,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
}
 
spin_lock_init(&adapter->cmd_lock);
-   adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
-sizeof(struct vmxnet3_adapter),
-PCI_DMA_TODEVICE);
-   if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
-   dev_err(&pdev->dev, "Failed to map dma\n");
-   err = -EFAULT;
-   goto err_set_mask;
-   }
adapter->shared = dma_alloc_coherent(
&adapter->pdev->dev,
sizeof(struct Vmxnet3_DriverShared),
@@ -3628,6 +3620,16 @@ vmxnet3_probe_device(struct pci_dev *pdev,
}
 
vmxnet3_check_link(adapter, false);
+
+   adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
+sizeof(struct vmxnet3_adapter),
+PCI_DMA_TODEVICE);
+   if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
+   dev_err(&pdev->dev, "Failed to map dma\n");
+   err = -EFAULT;
+   goto err_register;
+   }
+
return 0;
 
 err_register:
@@ -3655,8 +3657,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
  sizeof(struct Vmxnet3_DriverShared),
  adapter->shared, adapter->shared_pa);
 err_alloc_shared:
-   dma_unmap_single(&adapter->pdev->dev, adapter->adapter_pa,
-sizeof(struct vmxnet3_adapter), PCI_DMA_TODEVICE);
 err_set_mask:
free_netdev(netdev);
return err;
-- 
2.17.1



[PATCH] atm: idt77252: avoid accessing the data mapped to streaming DMA

2020-08-02 Thread Jia-Ju Bai
In queue_skb(), skb->data is mapped to streaming DMA on line 850:
  dma_map_single(..., skb->data, ...);

Then skb->data is accessed on lines 862 and 863:
  tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
   (skb->data[2] <<  8) | (skb->data[3] <<  0);
and on lines 893 and 894:
  tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
   (skb->data[2] <<  8) | (skb->data[3] <<  0);

These accesses may cause data inconsistency between CPU cache and
hardware.

To fix this problem, the calculation result of skb->data is stored in a
local variable before DMA mapping, and then the driver accesses this
local variable instead of skb->data.

Signed-off-by: Jia-Ju Bai 
---
 drivers/atm/idt77252.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index df51680e8931..65a3886f68c9 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -835,6 +835,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
unsigned long flags;
int error;
int aal;
+   u32 word4;
 
if (skb->len == 0) {
printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
@@ -846,6 +847,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
 
tbd = &IDT77252_PRV_TBD(skb);
vcc = ATM_SKB(skb)->vcc;
+   word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
+   (skb->data[2] <<  8) | (skb->data[3] <<  0);
 
IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
 skb->len, DMA_TO_DEVICE);
@@ -859,8 +862,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x;
-   tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] <<  8) | (skb->data[3] <<  0);
+   tbd->word_4 = word4;
 
if (test_bit(VCF_RSV, &vc->flags))
vc = card->vcs[0];
@@ -890,8 +892,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
 
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
tbd->word_3 = 0x;
-   tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
- (skb->data[2] <<  8) | (skb->data[3] <<  0);
+   tbd->word_4 = word4;
break;
 
case ATM_AAL5:
-- 
2.17.1



[PATCH] atm: eni: avoid accessing the data mapped to streaming DMA

2020-08-02 Thread Jia-Ju Bai
In do_tx(), skb->data is mapped to streaming DMA on line :
  paddr = dma_map_single(...,skb->data,DMA_TO_DEVICE);

Then skb->data is accessed on line 1153:
  (skb->data[3] & 0xf)

This access may cause data inconsistency between CPU cache and hardware.

To fix this problem, skb->data[3] is assigned to a local variable before
DMA mapping, and then the driver accesses this local variable instead of
skb->data[3].

Signed-off-by: Jia-Ju Bai 
---
 drivers/atm/eni.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 17d47ad03ab7..09f4e2f41363 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -1034,6 +1034,7 @@ static enum enq_res do_tx(struct sk_buff *skb)
u32 dma_rd,dma_wr;
u32 size; /* in words */
int aal5,dma_size,i,j;
+   unsigned char skb_data3;
 
DPRINTK(">do_tx\n");
NULLCHECK(skb);
@@ -1108,6 +1109,7 @@ DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
vcc->dev->number);
return enq_jam;
}
+   skb_data3 = skb->data[3];
paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
   DMA_TO_DEVICE);
ENI_PRV_PADDR(skb) = paddr;
@@ -1150,7 +1152,7 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't 
work anyway */
(size/(ATM_CELL_PAYLOAD/4)),tx->send+tx->tx_pos*4);
 /*printk("dsc = 0x%08lx\n",(unsigned long) readl(tx->send+tx->tx_pos*4));*/
writel((vcc->vci << MID_SEG_VCI_SHIFT) |
-(aal5 ? 0 : (skb->data[3] & 0xf)) |
+(aal5 ? 0 : (skb_data3 & 0xf)) |
(ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0),
tx->send+((tx->tx_pos+1) & (tx->words-1))*4);
DPRINTK("size: %d, len:%d\n",size,skb->len);
-- 
2.17.1



Rule about streaming DMA mapping

2020-07-24 Thread Jia-Ju Bai

Hello,

From the book "Linux device drivers" (3rd edition), I find an 
interesting rule for streaming DMA mapping:


Once a buffer has been mapped, it belongs to the device, not the 
processor. Until
the buffer has been unmapped, the driver should not touch its contents 
in any
way. Only after dma_unmap_single has been called is it safe for the 
driver to

access the contents of the buffer (with one exception that we see shortly).
Among other things, this rule implies that a buffer being written to a 
device cannot

be mapped until it contains all the data to write.

I find some violations about this rule, and there are two examples in 
Linux-5.6:


=== EXAMPLE 1 ===
In vmxnet3_probe_device() in drivers/net/vmxnet3/vmxnet3_drv.c:
    adapter->adapter_pa = dma_map_single(&adapter->pdev->dev, adapter,
                     sizeof(struct vmxnet3_adapter),
                     PCI_DMA_TODEVICE);
    if (dma_mapping_error(&adapter->pdev->dev, adapter->adapter_pa)) {
        dev_err(&pdev->dev, "Failed to map dma\n");
        err = -EFAULT;
        goto err_set_mask;
    }
    adapter->shared = dma_alloc_coherent(
                &adapter->pdev->dev,
                sizeof(struct Vmxnet3_DriverShared),
                &adapter->shared_pa, GFP_KERNEL);
    if (!adapter->shared) {
        dev_err(&pdev->dev, "Failed to allocate memory\n");
        err = -ENOMEM;
        goto err_alloc_shared;
    }

    adapter->num_rx_queues = num_rx_queues;
    adapter->num_tx_queues = num_tx_queues;
    adapter->rx_buf_per_pkt = 1;

The variable "adapter" is mapped to streaming DMA, but its fields are 
used before this variable is unmapped.


=== EXAMPLE 2 ===
In queue_skb() in drivers/atm/idt77252.c:
    IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
                         skb->len, DMA_TO_DEVICE);

    error = -EINVAL;

    if (oam) {
        if (skb->len != 52)
            goto errout;

        tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
        tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
        tbd->word_3 = 0x;
        tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
              (skb->data[2] <<  8) | (skb->data[3] <<  0);

The array "skb->data" is mapped to streaming DMA, but its elements are 
used before this array is unmapped.


Because I am not familiar with streaming DMA mapping, I wonder whether 
these violations are real?

If they are real, what problems can they cause?

Thanks a lot :)


Best wishes,
Jia-Ju Bai



[PATCH] net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss()

2020-05-29 Thread Jia-Ju Bai
The value adapter->rss_conf is stored in DMA memory, and it is assigned
to rssConf, so rssConf->indTableSize can be modified at anytime by
malicious hardware. Because rssConf->indTableSize is assigned to n,
buffer overflow may occur when the code "rssConf->indTable[n]" is
executed.

To fix this possible bug, n is checked after being used.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/vmxnet3/vmxnet3_ethtool.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c 
b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 6528940ce5f3..b53bb8bcd47f 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -700,6 +700,8 @@ vmxnet3_get_rss(struct net_device *netdev, u32 *p, u8 *key, 
u8 *hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (!p)
return 0;
+   if (n > UPT1_RSS_MAX_IND_TABLE_SIZE)
+   return 0;
while (n--)
p[n] = rssConf->indTable[n];
return 0;
-- 
2.17.1



[BUG] net: chelsio: Possible buffer overflow caused by DMA failures/attacks

2020-05-05 Thread Jia-Ju Bai

In alloc_rx_resources():
    sge->respQ.entries =
        pci_alloc_consistent(pdev, size, &sge->respQ.dma_addr);

Thus, "sge->respQ.entries" is a DMA value, and it is assigned to
"e" in process_pure_responses():
    struct sge *sge = adapter->sge;
    struct respQ *q = &sge->respQ;
    struct respQ_e *e = &q->entries[q->cidx];

When DMA failures or attacks occur, the data stored in "e" can be
changed at any time. In this case, the value of "e->FreelistQid"
can be a large number to cause buffer overflow when the
following code is executed:
    const struct freelQ *fl = &sge->freelQ[e->FreelistQid];

Similarly, "sge->respQ.entries" is also assigned to "e" in
process_responses():
    struct sge *sge = adapter->sge;
    struct respQ *q = &sge->respQ;
    struct respQ_e *e = &q->entries[q->cidx];

When DMA failures or attacks occur, the data stored in "e" can be
changed at any time. In this case, the value of "e->FreelistQid"
can be a large number to cause buffer overflow when the
following code is executed:
    struct freelQ *fl = &sge->freelQ[e->FreelistQid];

Considering that DMA can fail or be attacked, I think that it is 
dangerous to
use a DMA value (or any value tainted by it) as an array index or a 
control-flow
condition. However, I have found many such dangerous cases in Linux 
device drivers

through my static-analysis tool and code review.
I am not sure whether my opinion is correct, so I want to listen to your 
points of view.

Thanks in advance :)


Best wishes,
Jia-Ju Bai



Re: [BUG] rtlwifi: a crash in error handling code of rtl_pci_probe()

2019-05-14 Thread Jia-Ju Bai




On 2019/5/15 9:08, Larry Finger wrote:

On 5/14/19 8:07 AM, Jia-Ju Bai wrote:
In rtl_pci_probe(), when request_irq() in rtl_pci_intr_mode_legacy() 
in rtl_pci_intr_mode_decide() fails, a crash occurs.

The crash information is as follows:

[  108.271155] kasan: CONFIG_KASAN_INLINE enabled
[  108.271163] kasan: GPF could be caused by NULL-ptr deref or user 
memory access

..
[  108.271193] RIP: 0010:cfg80211_get_drvinfo+0xce/0x3b0 [cfg80211]
..
[  108.271235] Call Trace:
[  108.271245]  ethtool_get_drvinfo+0x110/0x640
[  108.271255]  ? cfg80211_get_chan_state+0x7e0/0x7e0 [cfg80211]
[  108.271261]  ? ethtool_get_settings+0x340/0x340
[  108.271268]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  108.271279]  ? kasan_check_write+0x14/0x20
[  108.271284]  dev_ethtool+0x272d/0x4c20
[  108.271290]  ? unwind_get_return_address+0x66/0xb0
[  108.271299]  ? __save_stack_trace+0x92/0x100
[  108.271307]  ? ethtool_get_rxnfc+0x3f0/0x3f0
[  108.271316]  ? save_stack+0xa3/0xd0
[  108.271323]  ? save_stack+0x43/0xd0
[  108.271331]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271338]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271346]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271354]  ? update_stack_state+0x3b2/0x670
[  108.271361]  ? update_stack_state+0x3b2/0x670
[  108.271370]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  108.271379]  ? unwind_next_frame.part.5+0x19f/0xa60
[  108.271388]  ? bpf_prog_kallsyms_find+0x3e/0x270
[  108.271396]  ? is_bpf_text_address+0x1a/0x30
[  108.271408]  ? kernel_text_address+0x11d/0x130
[  108.271416]  ? __kernel_text_address+0x12/0x40
[  108.271423]  ? unwind_get_return_address+0x66/0xb0
[  108.271431]  ? __save_stack_trace+0x92/0x100
[  108.271440]  ? save_stack+0xa3/0xd0
[  108.271448]  ? udp_ioctl+0x35/0xe0
[  108.271457]  ? inet_ioctl+0x100/0x320
[  108.271466]  ? inet_stream_connect+0xb0/0xb0
[  108.271475]  ? alloc_file+0x60/0x480
[  108.271483]  ? alloc_file_pseudo+0x19d/0x270
[  108.271495]  ? sock_alloc_file+0x51/0x170
[  108.271502]  ? __sys_socket+0x12c/0x1f0
[  108.271510]  ? __x64_sys_socket+0x78/0xb0
[  108.271520]  ? do_syscall_64+0xb1/0x2e0
[  108.271529]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  108.271538]  ? kasan_check_read+0x11/0x20
[  108.271548]  ? mutex_lock+0x8f/0xe0
[  108.271557]  ? __mutex_lock_slowpath+0x20/0x20
[  108.271568]  dev_ioctl+0x1fb/0xae0
[  108.271576]  ? dev_ioctl+0x1fb/0xae0
[  108.271586]  ? _copy_from_user+0x71/0xd0
[  108.271594]  sock_do_ioctl+0x1e2/0x2f0
[  108.271602]  ? kmem_cache_alloc+0xf9/0x250
[  108.271611]  ? ___sys_recvmsg+0x5a0/0x5a0
[  108.271621]  ? apparmor_file_alloc_security+0x128/0x7e0
[  108.271630]  ? kasan_unpoison_shadow+0x35/0x50
[  108.271638]  ? kasan_kmalloc+0xad/0xe0
[  108.271652]  ? apparmor_file_alloc_security+0x128/0x7e0
[  108.271662]  ? apparmor_file_alloc_security+0x269/0x7e0
[  108.271670]  sock_ioctl+0x361/0x590
[  108.271678]  ? sock_ioctl+0x361/0x590
[  108.271686]  ? routing_ioctl+0x470/0x470
[  108.271695]  ? kasan_check_write+0x14/0x20
[  108.271703]  ? __mutex_init+0xba/0x130
[  108.271713]  ? percpu_counter_add_batch+0xc7/0x120
[  108.271722]  ? alloc_empty_file+0xae/0x150
[  108.271729]  ? routing_ioctl+0x470/0x470
[  108.271738]  do_vfs_ioctl+0x1ae/0xfe0
[  108.271745]  ? do_vfs_ioctl+0x1ae/0xfe0
[  108.271754]  ? alloc_file_pseudo+0x1ad/0x270
[  108.271762]  ? ioctl_preallocate+0x1e0/0x1e0
[  108.271770]  ? alloc_file+0x480/0x480
[  108.271778]  ? kasan_check_read+0x11/0x20
[  108.271786]  ? __fget+0x24d/0x320
[  108.271794]  ? iterate_fd+0x180/0x180
[  108.271802]  ? fd_install+0x52/0x60
[  108.271812]  ? security_file_ioctl+0x8c/0xb0
[  108.271820]  ksys_ioctl+0x99/0xb0
[  108.271829]  __x64_sys_ioctl+0x78/0xb0
[  108.271839]  do_syscall_64+0xb1/0x2e0
[  108.271857]  ? prepare_exit_to_usermode+0xc8/0x160
[  108.271871]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
..

I checked the driver source code, but cannot find the reason, so I 
only report the crash...

Can somebody give an explanation about this crash?

This crash is triggered by a runtime fuzzing tool named FIZZER 
written by us.


Your backtrace does not include any references to rtlwifi routines, 
and I have no idea what FIZZER does, thus it is not possible for me to 
debug this. If the error situation that you state happens, the code 
should end up at label "fail3" in routine rtl_pci_probe(). Insert 
printk statements after every line of the following, and report the 
last good point before the error. It is certainly possible that 
something is being torn down that was never erected. The likelihood of 
failure of both MSI and legacy interrupts is not very likely, and we 
probably have never hit those conditions.


fail3:
pci_set_drvdata(pdev, NULL);
rtl_deinit_core(hw);

fail2:
if (rtlpriv->io.pci_mem_start != 0)
pci_iounmap(pdev, (void __iomem 
*)rtlpriv->io.pci_mem_start);


pci_release_regions(pdev);
complete(&rtlpriv->fi

[BUG] rtlwifi: a crash in error handling code of rtl_pci_probe()

2019-05-14 Thread Jia-Ju Bai
In rtl_pci_probe(), when request_irq() in rtl_pci_intr_mode_legacy() in 
rtl_pci_intr_mode_decide() fails, a crash occurs.

The crash information is as follows:

[  108.271155] kasan: CONFIG_KASAN_INLINE enabled
[  108.271163] kasan: GPF could be caused by NULL-ptr deref or user 
memory access

..
[  108.271193] RIP: 0010:cfg80211_get_drvinfo+0xce/0x3b0 [cfg80211]
..
[  108.271235] Call Trace:
[  108.271245]  ethtool_get_drvinfo+0x110/0x640
[  108.271255]  ? cfg80211_get_chan_state+0x7e0/0x7e0 [cfg80211]
[  108.271261]  ? ethtool_get_settings+0x340/0x340
[  108.271268]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  108.271279]  ? kasan_check_write+0x14/0x20
[  108.271284]  dev_ethtool+0x272d/0x4c20
[  108.271290]  ? unwind_get_return_address+0x66/0xb0
[  108.271299]  ? __save_stack_trace+0x92/0x100
[  108.271307]  ? ethtool_get_rxnfc+0x3f0/0x3f0
[  108.271316]  ? save_stack+0xa3/0xd0
[  108.271323]  ? save_stack+0x43/0xd0
[  108.271331]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271338]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271346]  ? ftrace_graph_ret_addr+0x2d/0x170
[  108.271354]  ? update_stack_state+0x3b2/0x670
[  108.271361]  ? update_stack_state+0x3b2/0x670
[  108.271370]  ? __read_once_size_nocheck.constprop.7+0x20/0x20
[  108.271379]  ? unwind_next_frame.part.5+0x19f/0xa60
[  108.271388]  ? bpf_prog_kallsyms_find+0x3e/0x270
[  108.271396]  ? is_bpf_text_address+0x1a/0x30
[  108.271408]  ? kernel_text_address+0x11d/0x130
[  108.271416]  ? __kernel_text_address+0x12/0x40
[  108.271423]  ? unwind_get_return_address+0x66/0xb0
[  108.271431]  ? __save_stack_trace+0x92/0x100
[  108.271440]  ? save_stack+0xa3/0xd0
[  108.271448]  ? udp_ioctl+0x35/0xe0
[  108.271457]  ? inet_ioctl+0x100/0x320
[  108.271466]  ? inet_stream_connect+0xb0/0xb0
[  108.271475]  ? alloc_file+0x60/0x480
[  108.271483]  ? alloc_file_pseudo+0x19d/0x270
[  108.271495]  ? sock_alloc_file+0x51/0x170
[  108.271502]  ? __sys_socket+0x12c/0x1f0
[  108.271510]  ? __x64_sys_socket+0x78/0xb0
[  108.271520]  ? do_syscall_64+0xb1/0x2e0
[  108.271529]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  108.271538]  ? kasan_check_read+0x11/0x20
[  108.271548]  ? mutex_lock+0x8f/0xe0
[  108.271557]  ? __mutex_lock_slowpath+0x20/0x20
[  108.271568]  dev_ioctl+0x1fb/0xae0
[  108.271576]  ? dev_ioctl+0x1fb/0xae0
[  108.271586]  ? _copy_from_user+0x71/0xd0
[  108.271594]  sock_do_ioctl+0x1e2/0x2f0
[  108.271602]  ? kmem_cache_alloc+0xf9/0x250
[  108.271611]  ? ___sys_recvmsg+0x5a0/0x5a0
[  108.271621]  ? apparmor_file_alloc_security+0x128/0x7e0
[  108.271630]  ? kasan_unpoison_shadow+0x35/0x50
[  108.271638]  ? kasan_kmalloc+0xad/0xe0
[  108.271652]  ? apparmor_file_alloc_security+0x128/0x7e0
[  108.271662]  ? apparmor_file_alloc_security+0x269/0x7e0
[  108.271670]  sock_ioctl+0x361/0x590
[  108.271678]  ? sock_ioctl+0x361/0x590
[  108.271686]  ? routing_ioctl+0x470/0x470
[  108.271695]  ? kasan_check_write+0x14/0x20
[  108.271703]  ? __mutex_init+0xba/0x130
[  108.271713]  ? percpu_counter_add_batch+0xc7/0x120
[  108.271722]  ? alloc_empty_file+0xae/0x150
[  108.271729]  ? routing_ioctl+0x470/0x470
[  108.271738]  do_vfs_ioctl+0x1ae/0xfe0
[  108.271745]  ? do_vfs_ioctl+0x1ae/0xfe0
[  108.271754]  ? alloc_file_pseudo+0x1ad/0x270
[  108.271762]  ? ioctl_preallocate+0x1e0/0x1e0
[  108.271770]  ? alloc_file+0x480/0x480
[  108.271778]  ? kasan_check_read+0x11/0x20
[  108.271786]  ? __fget+0x24d/0x320
[  108.271794]  ? iterate_fd+0x180/0x180
[  108.271802]  ? fd_install+0x52/0x60
[  108.271812]  ? security_file_ioctl+0x8c/0xb0
[  108.271820]  ksys_ioctl+0x99/0xb0
[  108.271829]  __x64_sys_ioctl+0x78/0xb0
[  108.271839]  do_syscall_64+0xb1/0x2e0
[  108.271857]  ? prepare_exit_to_usermode+0xc8/0x160
[  108.271871]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
..

I checked the driver source code, but cannot find the reason, so I only 
report the crash...

Can somebody give an explanation about this crash?

This crash is triggered by a runtime fuzzing tool named FIZZER written 
by us.



Best wishes,
Jia-Ju Bai


[BUG] rtlwifi: Resource leaks in error handling code of rtl_pci_probe()

2019-05-14 Thread Jia-Ju Bai

In rtl_pci_probe(), rtl_pci_init() allocates some resources, such as:
_rtl_pci_init_trx_ring
  _rtl_pci_init_rx_ring
_rtl_pci_init_rx_ring
  pci_zalloc_consistent() -- resource
  _rtl_pci_init_one_rxdesc
dev_alloc_skb() -- resource

_rtl_pci_init_trx_ring
  _rtl_pci_init_tx_ring
pci_zalloc_consistent() -- resource

When ieee80211_register_hw() or rtl_pci_intr_mode_decide() fails, these 
resources are not released in error handling code.


A possible fix is to call rtl_pci_deinit() in error handling code, but I 
am not sure whether this is correct.

Thus, I only report the bugs.

These bugs are found by a runtime fuzzing tool named FIZZER written by us.


Best wishes,
Jia-Ju Bai


[PATCH] rtlwifi: Fix null-pointer dereferences in error handling code of rtl_pci_probe()

2019-05-14 Thread Jia-Ju Bai
*BUG 1:
In rtl_pci_probe(), when rtlpriv->cfg->ops->init_sw_vars() fails,
rtl_deinit_core() in the error handling code is executed.
rtl_deinit_core() calls rtl_free_entries_from_scan_list(), which uses
rtlpriv->scan_list.list in list_for_each_entry_safe(), but it has been
initialized. Thus a null-pointer dereference occurs.
The reason is that rtlpriv->scan_list.list is initialized by
INIT_LIST_HEAD() in rtl_init_core(), which has not been called.

To fix this bug, rtl_deinit_core() should not be called when
rtlpriv->cfg->ops->init_sw_vars() fails.

*BUG 2:
In rtl_pci_probe(), rtl_init_core() can fail when rtl_regd_init() in
this function fails, and rtlpriv->scan_list.list has not been
initialized by INIT_LIST_HEAD(). Then, rtl_deinit_core() in the error
handling code of rtl_pci_probe() is executed. Finally, a null-pointer
dereference occurs due to the same reason of the above bug.

To fix this bug, the initialization of lists in rtl_init_core() are
performed before the call to rtl_regd_init().

These bugs are found by a runtime fuzzing tool named FIZZER written by
us.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 15 ---
 drivers/net/wireless/realtek/rtlwifi/pci.c  |  4 ++--
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index 217d2a7a43c7..b3f341ec3710 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -526,8 +526,14 @@ int rtl_init_core(struct ieee80211_hw *hw)
/* <2> rate control register */
hw->rate_control_algorithm = "rtl_rc";
 
+   /* <3> init list */
+   INIT_LIST_HEAD(&rtlpriv->entry_list);
+   INIT_LIST_HEAD(&rtlpriv->scan_list.list);
+   skb_queue_head_init(&rtlpriv->tx_report.queue);
+   skb_queue_head_init(&rtlpriv->c2hcmd_queue);
+
/*
-* <3> init CRDA must come after init
+* <4> init CRDA must come after init
 * mac80211 hw  in _rtl_init_mac80211.
 */
if (rtl_regd_init(hw, rtl_reg_notifier)) {
@@ -535,7 +541,7 @@ int rtl_init_core(struct ieee80211_hw *hw)
return 1;
}
 
-   /* <4> locks */
+   /* <5> locks */
mutex_init(&rtlpriv->locks.conf_mutex);
mutex_init(&rtlpriv->locks.ips_mutex);
mutex_init(&rtlpriv->locks.lps_mutex);
@@ -550,11 +556,6 @@ int rtl_init_core(struct ieee80211_hw *hw)
spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
spin_lock_init(&rtlpriv->locks.fw_ps_lock);
spin_lock_init(&rtlpriv->locks.iqk_lock);
-   /* <5> init list */
-   INIT_LIST_HEAD(&rtlpriv->entry_list);
-   INIT_LIST_HEAD(&rtlpriv->scan_list.list);
-   skb_queue_head_init(&rtlpriv->tx_report.queue);
-   skb_queue_head_init(&rtlpriv->c2hcmd_queue);
 
rtlmac->link_state = MAC80211_NOLINK;
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c 
b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 48ca52102cef..864cb76230c4 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -2267,7 +2267,7 @@ int rtl_pci_probe(struct pci_dev *pdev,
if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
pr_err("Can't init_sw_vars\n");
err = -ENODEV;
-   goto fail3;
+   goto fail2;
}
rtlpriv->cfg->ops->init_sw_leds(hw);
-- 
2.17.0



[BUG] net: huawei: hinic: a possible sleep-in-atomic-context bug in msg_to_mgmt_async

2019-01-10 Thread Jia-Ju Bai

The driver may sleep in an interrupt handler.
The function call path (from bottom to top) in the directory 
"drivers/net/ethernet/huawei/hinic/" in Linux-4.17 is:


[FUNC] down
hinic_hw_mgmt.c, 324: down in msg_to_mgmt_async
hinic_hw_mgmt.c, 408: msg_to_mgmt_async in mgmt_recv_msg_handler
hinic_hw_mgmt.c, 464:mgmt_recv_msg_handler in recv_mgmt_msg_handler
hinic_hw_mgmt.c, 484: recv_mgmt_msg_handler in mgmt_msg_aeqe_handler
hinic_hw_eqs.c, 264: [FUNC_PTR]mgmt_msg_aeqe_handler in aeq_irq_handler
hinic_hw_eqs.c, 355: aeq_irq_handler in eq_irq_handler
hinic_hw_eqs.c, 383: eq_irq_handler in ceq_tasklet

Note that [FUNC_PTR] means a function pointer call.

This bug is found by my static analysis tool (DSAC-2) and checked by my
manual code review.

I do not know how to correctly fix this bug, so I just report it.
A possible way may be to replace up() and down() with spin_lock() and 
spin_unlock().



Best wishes,
Jia-Ju Bai



[BUG] net: huawei: hinic: a possible sleep-in-atomic-context bug in hinic_get_stats64

2019-01-10 Thread Jia-Ju Bai

The driver may sleep while holding a RCU lock.
The function call path (from bottom to top) in Linux-4.17 is:

[FUNC] down
drivers/net/.../hinic/hinic_main.c, 775: down in hinic_get_stats64
net/core/dev.c, 8278: [FUNC_PTR]hinic_get_stats64 in dev_get_stats
net/core/net-sysfs.c, 568: dev_get_stats in netstat_show
net/core/net-sysfs.c, 565: _raw_read_lock in netstat_show

Note that [FUNC_PTR] means a function pointer call.

This bug is found by my static analysis tool (DSAC-2) and checked by my
manual code review.

I do not know how to correctly fix this bug, so I just report it.
A possible way may be to replace up() and down()
with spin_lock() and spin_unlock().


Best wishes,
Jia-Ju Bai


[BUG] net: huawei: hinic: a possible sleep-in-atomic-context bug in hinic_get_stats64

2019-01-10 Thread Jia-Ju Bai

The driver may sleep while holding a RCU lock.
The function call path (from bottom to top) in Linux-4.17 is:

[FUNC] down
drivers/net/.../hinic/hinic_main.c, 775: down in hinic_get_stats64
net/core/dev.c, 8278: [FUNC_PTR]hinic_get_stats64 in dev_get_stats
net/core/net-sysfs.c, 568: dev_get_stats in netstat_show
net/core/net-sysfs.c, 565: _raw_read_lock in netstat_show

Note that [FUNC_PTR] means a function pointer call.

This bug is found by my static analysis tool (DSAC-2) and checked by my
manual code review.

I do not know how to correctly fix this bug, so I just report it.
A possible way may be to replace up() and down()
with spin_lock() and spin_unlock().


Best wishes,
Jia-Ju Bai



Re: [PATCH] net: nvidia: forcedeth: Fix two possible concurrency use-after-free bugs

2019-01-08 Thread Jia-Ju Bai




On 2019/1/9 11:24, Yanjun Zhu wrote:


If you have forcedeth NIC, you can make tests with it.:-)


Ah, I would like to, but I do not have the hardware...


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: nvidia: forcedeth: Fix two possible concurrency use-after-free bugs

2019-01-08 Thread Jia-Ju Bai




On 2019/1/9 10:35, Yanjun Zhu wrote:


On 2019/1/9 10:03, Jia-Ju Bai wrote:



On 2019/1/9 9:24, Yanjun Zhu wrote:


On 2019/1/8 20:57, Jia-Ju Bai wrote:



On 2019/1/8 20:54, Zhu Yanjun wrote:


在 2019/1/8 20:45, Jia-Ju Bai 写道:

In drivers/net/ethernet/nvidia/forcedeth.c, the functions
nv_start_xmit() and nv_start_xmit_optimized() can be concurrently
executed with nv_poll_controller().

nv_start_xmit
   line 2321: prev_tx_ctx->skb = skb;

nv_start_xmit_optimized
   line 2479: prev_tx_ctx->skb = skb;

nv_poll_controller
   nv_do_nic_poll
 line 4134: spin_lock(&np->lock);
 nv_drain_rxtx
   nv_drain_tx
 nv_release_txskb
   line 2004: dev_kfree_skb_any(tx_skb->skb);

Thus, two possible concurrency use-after-free bugs may occur.

To fix these possible bugs,



Does this really occur? Can you reproduce this ?


This bug is not found by the real execution.
It is found by a static tool written by myself, and then I check it 
by manual code review.


Before "line 2004: dev_kfree_skb_any(tx_skb->skb); ",

"

nv_disable_irq(dev);
nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);   <---this stop rxtx
nv_txrx_reset(dev);
"

In this case, does nv_start_xmit or nv_start_xmit_optimized still 
work well?




nv_stop_rxtx() calls nv_stop_tx(dev).

static void nv_stop_tx(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 tx_ctrl = readl(base + NvRegTransmitterControl);

if (!np->mac_in_use)
tx_ctrl &= ~NVREG_XMITCTL_START;
else
tx_ctrl |= NVREG_XMITCTL_TX_PATH_EN;
writel(tx_ctrl, base + NvRegTransmitterControl);
if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
  NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX))
netdev_info(dev, "%s: TransmitterStatus remained busy\n",
__func__);

udelay(NV_TXSTOP_DELAY2);
if (!np->mac_in_use)
writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV,

   base + NvRegTransmitPoll);
}

nv_stop_tx() seems to only write registers to stop transmitting for 
hardware.
But it does not wait until nv_start_xmit() and 
nv_start_xmit_optimized() finish execution.

There are 3 modes in forcedeth NIC.
In throughput mode (0), every tx & rx packet will generate an interrupt.
In CPU mode (1), interrupts are controlled by a timer.
In dynamic mode (2), the mode toggles between throughput and CPU mode 
based on network load.


From the source code,

"np->recover_error = 1;" is related with CPU mode.

nv_start_xmit or nv_start_xmit_optimized seems related with ghroughput 
mode.


In static void nv_do_nic_poll(struct timer_list *t),
when  if (np->recover_error), line 2004: 
dev_kfree_skb_any(tx_skb->skb); will run.


When "np->recover_error=1", do you think nv_start_xmit or 
nv_start_xmit_optimized will be called?


Sorry, I do not know about these modes...
But I still think nv_start_xmit() or nv_start_xmit_optimized() can be 
called here, in no matter which mode :)



Best wishes,
Jia-Ju Bai


Re: [PATCH] net: nvidia: forcedeth: Fix two possible concurrency use-after-free bugs

2019-01-08 Thread Jia-Ju Bai




On 2019/1/9 9:24, Yanjun Zhu wrote:


On 2019/1/8 20:57, Jia-Ju Bai wrote:



On 2019/1/8 20:54, Zhu Yanjun wrote:


在 2019/1/8 20:45, Jia-Ju Bai 写道:

In drivers/net/ethernet/nvidia/forcedeth.c, the functions
nv_start_xmit() and nv_start_xmit_optimized() can be concurrently
executed with nv_poll_controller().

nv_start_xmit
   line 2321: prev_tx_ctx->skb = skb;

nv_start_xmit_optimized
   line 2479: prev_tx_ctx->skb = skb;

nv_poll_controller
   nv_do_nic_poll
 line 4134: spin_lock(&np->lock);
 nv_drain_rxtx
   nv_drain_tx
 nv_release_txskb
   line 2004: dev_kfree_skb_any(tx_skb->skb);

Thus, two possible concurrency use-after-free bugs may occur.

To fix these possible bugs,



Does this really occur? Can you reproduce this ?


This bug is not found by the real execution.
It is found by a static tool written by myself, and then I check it 
by manual code review.


Before "line 2004: dev_kfree_skb_any(tx_skb->skb); ",

"

nv_disable_irq(dev);
nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);   <---this stop rxtx
nv_txrx_reset(dev);
"

In this case, does nv_start_xmit or nv_start_xmit_optimized still work 
well?




nv_stop_rxtx() calls nv_stop_tx(dev).

static void nv_stop_tx(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
u32 tx_ctrl = readl(base + NvRegTransmitterControl);

if (!np->mac_in_use)
tx_ctrl &= ~NVREG_XMITCTL_START;
else
tx_ctrl |= NVREG_XMITCTL_TX_PATH_EN;
writel(tx_ctrl, base + NvRegTransmitterControl);
if (reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
  NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX))
netdev_info(dev, "%s: TransmitterStatus remained busy\n",
__func__);

udelay(NV_TXSTOP_DELAY2);
if (!np->mac_in_use)
writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV,

   base + NvRegTransmitPoll);
}

nv_stop_tx() seems to only write registers to stop transmitting for 
hardware.
But it does not wait until nv_start_xmit() and nv_start_xmit_optimized() 
finish execution.
Maybe netif_stop_queue() should be used here to stop transmitting for 
network layer, but this function does not seem to wait, either.
Do you know any function that can wait until ".ndo_start_xmit" finish 
execution?



Best wishes,
Jia-Ju Bai




[PATCH] isdn: i4l: isdn_tty: Fix some concurrency double-free bugs

2019-01-08 Thread Jia-Ju Bai
The functions isdn_tty_tiocmset() and isdn_tty_set_termios() may be
concurrently executed.

isdn_tty_tiocmset
  isdn_tty_modem_hup
line 719: kfree(info->dtmf_state);
line 721: kfree(info->silence_state);
line 723: kfree(info->adpcms);
line 725: kfree(info->adpcmr);

isdn_tty_set_termios
  isdn_tty_modem_hup
line 719: kfree(info->dtmf_state);
line 721: kfree(info->silence_state);
line 723: kfree(info->adpcms);
line 725: kfree(info->adpcmr);

Thus, some concurrency double-free bugs may occur.

These possible bugs are found by a static tool written by myself and 
my manual code review.

To fix these possible bugs, the mutex lock "modem_info_mutex" used in
isdn_tty_tiocmset() is added in isdn_tty_set_termios().

Signed-off-by: Jia-Ju Bai 
---
 drivers/isdn/i4l/isdn_tty.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 1b2239c1d569..dc1cded716c1 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1437,15 +1437,19 @@ isdn_tty_set_termios(struct tty_struct *tty, struct 
ktermios *old_termios)
 {
modem_info *info = (modem_info *) tty->driver_data;
 
+   mutex_lock(&modem_info_mutex);
if (!old_termios)
isdn_tty_change_speed(info);
else {
if (tty->termios.c_cflag == old_termios->c_cflag &&
tty->termios.c_ispeed == old_termios->c_ispeed &&
-   tty->termios.c_ospeed == old_termios->c_ospeed)
+   tty->termios.c_ospeed == old_termios->c_ospeed) {
+   mutex_unlock(&modem_info_mutex);
return;
+   }
isdn_tty_change_speed(info);
}
+   mutex_unlock(&modem_info_mutex);
 }
 
 /*
-- 
2.17.0



Re: [PATCH] net: nvidia: forcedeth: Fix two possible concurrency use-after-free bugs

2019-01-08 Thread Jia-Ju Bai




On 2019/1/8 20:54, Zhu Yanjun wrote:


在 2019/1/8 20:45, Jia-Ju Bai 写道:

In drivers/net/ethernet/nvidia/forcedeth.c, the functions
nv_start_xmit() and nv_start_xmit_optimized() can be concurrently
executed with nv_poll_controller().

nv_start_xmit
   line 2321: prev_tx_ctx->skb = skb;

nv_start_xmit_optimized
   line 2479: prev_tx_ctx->skb = skb;

nv_poll_controller
   nv_do_nic_poll
 line 4134: spin_lock(&np->lock);
 nv_drain_rxtx
   nv_drain_tx
 nv_release_txskb
   line 2004: dev_kfree_skb_any(tx_skb->skb);

Thus, two possible concurrency use-after-free bugs may occur.

To fix these possible bugs,



Does this really occur? Can you reproduce this ?


This bug is not found by the real execution.
It is found by a static tool written by myself, and then I check it by 
manual code review.



Best wishes,
Jia-Ju Bai


[PATCH] net: nvidia: forcedeth: Fix two possible concurrency use-after-free bugs

2019-01-08 Thread Jia-Ju Bai
In drivers/net/ethernet/nvidia/forcedeth.c, the functions
nv_start_xmit() and nv_start_xmit_optimized() can be concurrently
executed with nv_poll_controller().

nv_start_xmit
  line 2321: prev_tx_ctx->skb = skb;

nv_start_xmit_optimized
  line 2479: prev_tx_ctx->skb = skb;

nv_poll_controller
  nv_do_nic_poll
line 4134: spin_lock(&np->lock);
nv_drain_rxtx
  nv_drain_tx
nv_release_txskb
  line 2004: dev_kfree_skb_any(tx_skb->skb);

Thus, two possible concurrency use-after-free bugs may occur.

To fix these possible bugs, the calls to spin_lock_irqsave() in 
nv_start_xmit() and nv_start_xmit_optimized() are moved to the 
front of "prev_tx_ctx->skb = skb;"

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/nvidia/forcedeth.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/nvidia/forcedeth.c 
b/drivers/net/ethernet/nvidia/forcedeth.c
index 1d9b0d44ddb6..48fa5a0bd2cb 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -2317,6 +2317,8 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
/* set last fragment flag  */
prev_tx->flaglen |= cpu_to_le32(tx_flags_extra);
 
+   spin_lock_irqsave(&np->lock, flags);
+
/* save skb in this slot's context area */
prev_tx_ctx->skb = skb;
 
@@ -2326,8 +2328,6 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, 
struct net_device *dev)
tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
 NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
 
-   spin_lock_irqsave(&np->lock, flags);
-
/* set tx flags */
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
 
@@ -2475,6 +2475,8 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff 
*skb,
/* set last fragment flag  */
prev_tx->flaglen |= cpu_to_le32(NV_TX2_LASTPACKET);
 
+   spin_lock_irqsave(&np->lock, flags);
+
/* save skb in this slot's context area */
prev_tx_ctx->skb = skb;
 
@@ -2491,8 +2493,6 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff 
*skb,
else
start_tx->txvlan = 0;
 
-   spin_lock_irqsave(&np->lock, flags);
-
if (np->tx_limit) {
/* Limit the number of outstanding tx. Setup all fragments, but
 * do not set the VALID bit on the first descriptor. Save a 
pointer
-- 
2.17.0



[PATCH v2] net: arcnet: Fix a possible concurrency use-after-free bug in arcnet_reply_tasklet()

2018-12-26 Thread Jia-Ju Bai
In drivers/net/arcnet/arcnet.c, the functions arcnet_reply_tasklet() and
arcnet_send_packet() may be concurrently executed.

arcnet_reply_tasklet()
  line 430: dev_kfree_skb(lp->outgoing.skb);

arcnet_send_packet()
  line 682: spin_lock_irqsave();
  line 690: lp->outgoing.skb = skb;
  line 691: proto->prepare_tx(..., skb->len, ...)

Thus, a possible concurrency use-after-free bugs may occur.

To fix this bug, the calls to spin_lock_irqsave() and
spin_unlock_irqrestore() are added in arcnet_reply_tasklet() to protect
dev_kfree_skb(lp->outgoing.skb).


Signed-off-by: Jia-Ju Bai 
---
v2:
* Add the definition of flags to fix the compilation error.
---
 drivers/net/arcnet/arcnet.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 8459115d9d4e..1e1b12650964 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -401,6 +401,7 @@ static void arcnet_reply_tasklet(unsigned long data)
struct sock_exterr_skb *serr;
struct sock *sk;
int ret;
+   unsigned long flags;
 
local_irq_disable();
skb = lp->outgoing.skb;
@@ -426,10 +427,14 @@ static void arcnet_reply_tasklet(unsigned long data)
serr->ee.ee_data = skb_shinfo(skb)->tskey;
serr->ee.ee_info = lp->reply_status;
 
+   spin_lock_irqsave(&lp->lock, flags);
+
/* finally erasing outgoing skb */
dev_kfree_skb(lp->outgoing.skb);
lp->outgoing.skb = NULL;
 
+   spin_unlock_irqrestore(&lp->lock, flags);
+
ackskb->dev = lp->dev;
 
ret = sock_queue_err_skb(sk, ackskb);
-- 
2.17.0



[BUG] net: brocade: bna: Possible concurrency use-after-free bugs

2018-12-26 Thread Jia-Ju Bai
In drivers/net/ethernet/brocade/bna/bnad_debugfs.c, the functions 
bnad_debugfs_read_regrd() and bnad_debugfs_write_regrd() may be 
concurrently executed.


bnad_debugfs_read_regrd()
  line 293: if (!bnad->regdata)
  line 297: simple_read_from_buffer(..., bnad->regdata, ...)
  line 300: kfree(bnad->regdata)

bnad_debugfs_write_regrd()
  line 335: kfree(bnad->regdata)
  line 338: kfree(bnad->regdata)
  line 357: regbuf =  (u32 *)bnad->regdata

All these accesses to bnad->regdata are not protected by any lock.
Thus, possible concurrency use-after-free bugs may occur.

A possible fixing way is to use a lock to protect these accesses.
I am not sure about this way, so I only report the bugs.


Best wishes,
Jia-Ju Bai






[PATCH] net: arcnet: Fix a possible concurrency use-after-free bug in arcnet_reply_tasklet()

2018-12-26 Thread Jia-Ju Bai
In drivers/net/arcnet/arcnet.c, the functions arcnet_reply_tasklet() and
arcnet_send_packet() may be concurrently executed.

arcnet_reply_tasklet()
  line 430: dev_kfree_skb(lp->outgoing.skb);

arcnet_send_packet()
  line 682: spin_lock_irqsave();
  line 690: lp->outgoing.skb = skb;
  line 691: proto->prepare_tx(..., skb->len, ...)

Thus, a possible concurrency use-after-free bugs may occur.

To fix this bug, the calls to spin_lock_irqsave() and
spin_unlock_irqrestore() are added in arcnet_reply_tasklet() to protect
dev_kfree_skb(lp->outgoing.skb).

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/arcnet/arcnet.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 8459115d9d4e..c5e943d01d66 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -426,10 +426,14 @@ static void arcnet_reply_tasklet(unsigned long data)
serr->ee.ee_data = skb_shinfo(skb)->tskey;
serr->ee.ee_info = lp->reply_status;
 
+   spin_lock_irqsave(&lp->lock, flags);
+
/* finally erasing outgoing skb */
dev_kfree_skb(lp->outgoing.skb);
lp->outgoing.skb = NULL;
 
+   spin_unlock_irqrestore(&lp->lock, flags);
+
ackskb->dev = lp->dev;
 
ret = sock_queue_err_skb(sk, ackskb);
-- 
2.17.0



[PATCH] isdn: hisax: hfc_pci: Fix a possible concurrency use-after-free bug in HFCPCI_l1hw()

2018-12-26 Thread Jia-Ju Bai
In drivers/isdn/hisax/hfc_pci.c, the functions hfcpci_interrupt() and
HFCPCI_l1hw() may be concurrently executed.

HFCPCI_l1hw()
  line 1173: if (!cs->tx_skb)

hfcpci_interrupt()
  line 942: spin_lock_irqsave();
  line 1066: dev_kfree_skb_irq(cs->tx_skb);

Thus, a possible concurrency use-after-free bug may occur 
in HFCPCI_l1hw().

To fix these bugs, the calls to spin_lock_irqsave() and
spin_unlock_irqrestore() are added in HFCPCI_l1hw(), to protect the
access to cs->tx_skb.

Signed-off-by: Jia-Ju Bai 
---
 drivers/isdn/hisax/hfc_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index ea0e4c6de3fb..0109e0e8bcb6 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1170,11 +1170,13 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
if (cs->debug & L1_DEB_LAPD)
debugl1(cs, "-> PH_REQUEST_PULL");
 #endif
+   spin_lock_irqsave(&cs->lock, flags);
if (!cs->tx_skb) {
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
} else
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+   spin_unlock_irqrestore(&cs->lock, flags);
break;
case (HW_RESET | REQUEST):
spin_lock_irqsave(&cs->lock, flags);
-- 
2.17.0



[PATCH] cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()

2018-12-13 Thread Jia-Ju Bai
The function cw1200_bss_info_changed() and cw1200_hw_scan() can be
concurrently executed.
The two functions both access a possible shared variable "frame.skb".

This shared variable is freed by dev_kfree_skb() in cw1200_upload_beacon(), 
which is called by cw1200_bss_info_changed(). The free operation is 
protected by a mutex lock "priv->conf_mutex" in cw1200_bss_info_changed().

In cw1200_hw_scan(), this shared variable is accessed without the
protection of the mutex lock "priv->conf_mutex". 
Thus, concurrency use-after-free bugs may occur.

To fix these bugs, the original calls to mutex_lock(&priv->conf_mutex) and 
mutex_unlock(&priv->conf_mutex) are moved to the places, which can 
protect the accesses to the shared variable.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/st/cw1200/scan.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/scan.c 
b/drivers/net/wireless/st/cw1200/scan.c
index 67213f11acbd..0a9eac93dd01 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -78,6 +78,10 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
return -EINVAL;
 
+   /* will be unlocked in cw1200_scan_work() */
+   down(&priv->scan.lock);
+   mutex_lock(&priv->conf_mutex);
+
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
req->ie_len);
if (!frame.skb)
@@ -86,19 +90,15 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
if (req->ie_len)
skb_put_data(frame.skb, req->ie, req->ie_len);
 
-   /* will be unlocked in cw1200_scan_work() */
-   down(&priv->scan.lock);
-   mutex_lock(&priv->conf_mutex);
-
ret = wsm_set_template_frame(priv, &frame);
if (!ret) {
/* Host want to be the probe responder. */
ret = wsm_set_probe_responder(priv, true);
}
if (ret) {
+   dev_kfree_skb(frame.skb);
mutex_unlock(&priv->conf_mutex);
up(&priv->scan.lock);
-   dev_kfree_skb(frame.skb);
return ret;
}
 
@@ -120,10 +120,9 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
++priv->scan.n_ssids;
}
 
-   mutex_unlock(&priv->conf_mutex);
-
if (frame.skb)
dev_kfree_skb(frame.skb);
+   mutex_unlock(&priv->conf_mutex);
queue_work(priv->workqueue, &priv->scan.work);
return 0;
 }
-- 
2.17.0



[PATCH] net: wireless: ath: ath9k: Fix a possible data race in ath_chanctx_set_next

2018-05-08 Thread Jia-Ju Bai
The write operation to "sc->next_chan" is protected by
the lock on line 1287, but the read operation to
this data on line 1262 is not protected by the lock.
Thus, there may exist a data race for "sc->next_chan".

To fix this data race, the read operation to "sc->next_chan" 
should be also protected by the lock.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/wireless/ath/ath9k/channel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/channel.c 
b/drivers/net/wireless/ath/ath9k/channel.c
index 1b05b5d7a038..ed3cd5523481 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1257,12 +1257,12 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool 
force)
"Stopping current chanctx: %d\n",
sc->cur_chan->chandef.center_freq1);
sc->cur_chan->stopped = true;
-   spin_unlock_bh(&sc->chan_lock);
 
if (sc->next_chan == &sc->offchannel.chan) {
getrawmonotonic(&ts);
measure_time = true;
}
+   spin_unlock_bh(&sc->chan_lock);
 
ath9k_chanctx_stop_queues(sc, sc->cur_chan);
queues_stopped = true;
-- 
2.17.0



Re: [PATCH] net: 8390: Fix possible data races in __ei_get_stats

2018-05-07 Thread Jia-Ju Bai



On 2018/5/8 13:04, Eric Dumazet wrote:


On 05/07/2018 07:16 PM, Jia-Ju Bai wrote:


Yes, "&dev->stats" will not change, because it is a fixed address.
But the field data in "dev->stats" is changed (rx_frame_errors, rx_crc_errors 
and rx_missed_errors).
So if the driver returns "&dev->stats" without lock protection (like on line 
858), the field data value of this return value can be the changed field data value or unchanged 
field data value.


We do not care.

This function can be called by multiple cpus at the same time.

As soon as one cpu returns from it, another cpu can happily modify 
dev->stats.ANYFIELD.

Your patch fixes nothing at all.



Okay, thanks.
I also find that my patch does not work...


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: 8390: Fix possible data races in __ei_get_stats

2018-05-07 Thread Jia-Ju Bai



On 2018/5/8 9:56, Eric Dumazet wrote:


On 05/07/2018 05:51 PM, Jia-Ju Bai wrote:


On 2018/5/7 22:15, Eric Dumazet wrote:

On 05/07/2018 07:08 AM, Jia-Ju Bai wrote:

The write operations to "dev->stats" are protected by
the spinlock on line 862-864, but the read operations to
this data on line 858 and 867 are not protected by the spinlock.
Thus, there may exist data races for "dev->stats".

To fix the data races, the read operations to "dev->stats" are
protected by the spinlock, and a local variable is used for return.

Signed-off-by: Jia-Ju Bai 
---
   drivers/net/ethernet/8390/lib8390.c | 14 ++
   1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/8390/lib8390.c 
b/drivers/net/ethernet/8390/lib8390.c
index c9c55c9eab9f..198952247d30 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -852,19 +852,25 @@ static struct net_device_stats *__ei_get_stats(struct 
net_device *dev)
   unsigned long ioaddr = dev->base_addr;
   struct ei_device *ei_local = netdev_priv(dev);
   unsigned long flags;
+struct net_device_stats *stats;
+
+spin_lock_irqsave(&ei_local->page_lock, flags);
 /* If the card is stopped, just return the present stats. */
-if (!netif_running(dev))
-return &dev->stats;
+if (!netif_running(dev)) {
+stats = &dev->stats;
+spin_unlock_irqrestore(&ei_local->page_lock, flags);
+return stats;
+}
   -spin_lock_irqsave(&ei_local->page_lock, flags);
   /* Read the counter registers, assuming we are in page 0. */
   dev->stats.rx_frame_errors  += ei_inb_p(ioaddr + EN0_COUNTER0);
   dev->stats.rx_crc_errors+= ei_inb_p(ioaddr + EN0_COUNTER1);
   dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);
+stats = &dev->stats;
   spin_unlock_irqrestore(&ei_local->page_lock, flags);
   -return &dev->stats;
+return stats;
   }
 /*


dev->stats is not a pointer, it is an array embedded in the
struct net_device

So this patch is not needed, since dev->stats can not change.

Thanks for your reply :)

I do not understand that why "dev->stats can not change".
Its data is indeed changed by the code:
  dev->stats.rx_frame_errors  += ei_inb_p(ioaddr + EN0_COUNTER0);
  dev->stats.rx_crc_errors+= ei_inb_p(ioaddr + EN0_COUNTER1);
  dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);

So ?


So I think a data race may occur when returning "dev->stats" without lock 
protection.

&dev->stats is a stable value.

It wont change over the lifetime of net_device object.

Adding a barrier before or after getting &dev->stats is useless, confusing and 
really not needed.



Yes, "&dev->stats" will not change, because it is a fixed address.
But the field data in "dev->stats" is changed (rx_frame_errors, 
rx_crc_errors and rx_missed_errors).
So if the driver returns "&dev->stats" without lock protection (like on 
line 858), the field data value of this return value can be the changed 
field data value or unchanged field data value.



Best wishes,
Jia-Ju Bai


Re: [PATCH] net: 8390: Fix possible data races in __ei_get_stats

2018-05-07 Thread Jia-Ju Bai



On 2018/5/7 22:15, Eric Dumazet wrote:


On 05/07/2018 07:08 AM, Jia-Ju Bai wrote:

The write operations to "dev->stats" are protected by
the spinlock on line 862-864, but the read operations to
this data on line 858 and 867 are not protected by the spinlock.
Thus, there may exist data races for "dev->stats".

To fix the data races, the read operations to "dev->stats" are
protected by the spinlock, and a local variable is used for return.

Signed-off-by: Jia-Ju Bai 
---
  drivers/net/ethernet/8390/lib8390.c | 14 ++
  1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/8390/lib8390.c 
b/drivers/net/ethernet/8390/lib8390.c
index c9c55c9eab9f..198952247d30 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -852,19 +852,25 @@ static struct net_device_stats *__ei_get_stats(struct 
net_device *dev)
unsigned long ioaddr = dev->base_addr;
struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
+   struct net_device_stats *stats;
+
+   spin_lock_irqsave(&ei_local->page_lock, flags);
  
  	/* If the card is stopped, just return the present stats. */

-   if (!netif_running(dev))
-   return &dev->stats;
+   if (!netif_running(dev)) {
+   stats = &dev->stats;
+   spin_unlock_irqrestore(&ei_local->page_lock, flags);
+   return stats;
+   }
  
-	spin_lock_irqsave(&ei_local->page_lock, flags);

/* Read the counter registers, assuming we are in page 0. */
dev->stats.rx_frame_errors  += ei_inb_p(ioaddr + EN0_COUNTER0);
dev->stats.rx_crc_errors+= ei_inb_p(ioaddr + EN0_COUNTER1);
dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);
+   stats = &dev->stats;
spin_unlock_irqrestore(&ei_local->page_lock, flags);
  
-	return &dev->stats;

+   return stats;
  }
  
  /*



dev->stats is not a pointer, it is an array embedded in the
struct net_device

So this patch is not needed, since dev->stats can not change.


Thanks for your reply :)

I do not understand that why "dev->stats can not change".
Its data is indeed changed by the code:
 dev->stats.rx_frame_errors  += ei_inb_p(ioaddr + EN0_COUNTER0);
 dev->stats.rx_crc_errors+= ei_inb_p(ioaddr + EN0_COUNTER1);
 dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);

So I think a data race may occur when returning "dev->stats" without 
lock protection.


By the way, I find this possible data race is similar to the previous 
commit 7b31b4deda76 for the tg3 driver.



Best wishes,
Jia-Ju Bai


[PATCH] net: 8390: Fix possible data races in __ei_get_stats

2018-05-07 Thread Jia-Ju Bai
The write operations to "dev->stats" are protected by 
the spinlock on line 862-864, but the read operations to
this data on line 858 and 867 are not protected by the spinlock.
Thus, there may exist data races for "dev->stats".

To fix the data races, the read operations to "dev->stats" are 
protected by the spinlock, and a local variable is used for return.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/8390/lib8390.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/8390/lib8390.c 
b/drivers/net/ethernet/8390/lib8390.c
index c9c55c9eab9f..198952247d30 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -852,19 +852,25 @@ static struct net_device_stats *__ei_get_stats(struct 
net_device *dev)
unsigned long ioaddr = dev->base_addr;
struct ei_device *ei_local = netdev_priv(dev);
unsigned long flags;
+   struct net_device_stats *stats;
+
+   spin_lock_irqsave(&ei_local->page_lock, flags);
 
/* If the card is stopped, just return the present stats. */
-   if (!netif_running(dev))
-   return &dev->stats;
+   if (!netif_running(dev)) {
+   stats = &dev->stats;
+   spin_unlock_irqrestore(&ei_local->page_lock, flags);
+   return stats;
+   }
 
-   spin_lock_irqsave(&ei_local->page_lock, flags);
/* Read the counter registers, assuming we are in page 0. */
dev->stats.rx_frame_errors  += ei_inb_p(ioaddr + EN0_COUNTER0);
dev->stats.rx_crc_errors+= ei_inb_p(ioaddr + EN0_COUNTER1);
dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2);
+   stats = &dev->stats;
spin_unlock_irqrestore(&ei_local->page_lock, flags);
 
-   return &dev->stats;
+   return stats;
 }
 
 /*
-- 
2.17.0



Re: [PATCH v2] dec: tulip: de4x5: Replace mdelay with usleep_range in de4x5_hw_init

2018-04-11 Thread Jia-Ju Bai



On 2018/4/12 10:21, arvindY wrote:



On Thursday 12 April 2018 07:00 AM, Jia-Ju Bai wrote:



On 2018/4/12 0:16, James Bottomley wrote:

On Wed, 2018-04-11 at 23:39 +0800, Jia-Ju Bai wrote:

de4x5_hw_init() is never called in atomic context.

de4x5_hw_init() is only called by de4x5_pci_probe(), which is only
set as ".probe" in struct pci_driver.

Despite never getting called from atomic context, de4x5_hw_init()
calls mdelay() to busily wait. This is not necessary and can be
replaced with usleep_range() to  avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Did you actually test this?  The usual reason for wanting m/udelay is
that the timing must be exact.  The driver is filled with mdelay()s for
this reason.  The one you've picked on is in the init path so it won't
affect the runtime in any way.  I also don't think we have the hrtimer
machinery for usleep_range() to work properly on parisc, so I don't
think the replacement works.

James



Hello, James.
Thanks for your reply :)

I agree that usleep_range() here will not much affect the real 
execution of this driver.


But I think usleep_range() can more opportunity for other threads to 
use the CPU core to schedule during waiting.
That is why I detect mdelay() that can be replaced with msleep() or 
usleep_range().




James is right, You have added all usleep_range() during system 
boot-up time.

During boot-up system will run as single threaded. Where this change will
not make much sense. System first priority is match the exact timing on
each and every boot-up.



Hello, Arvind.
Thanks for your reply :)

I admit I am not familiar with this driver.
I did not know this driver is only loaded during system boot-up time,
I thought this driver can be loaded as a kernel module (like many 
drivers) after system booting.

After knowing this, I admit my patch is not proper, sorry...


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: dsa: b53: Replace mdelay with msleep in b53_switch_reset_gpio

2018-04-11 Thread Jia-Ju Bai



On 2018/4/12 0:19, Florian Fainelli wrote:

On 04/11/2018 12:14 AM, Jia-Ju Bai wrote:


On 2018/4/11 13:30, Phil Reid wrote:

On 11/04/2018 09:51, Jia-Ju Bai wrote:

b53_switch_reset_gpio() is never called in atomic context.

The call chain ending up at b53_switch_reset_gpio() is:
[1] b53_switch_reset_gpio() <- b53_switch_reset() <-
 b53_reset_switch() <- b53_setup()

b53_switch_reset_gpio() is set as ".setup" in struct dsa_switch_ops.
This function is not called in atomic context.

Despite never getting called from atomic context,
b53_switch_reset_gpio()
calls mdelay() to busily wait.
This is not necessary and can be replaced with msleep() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
   drivers/net/dsa/b53/b53_common.c | 4 ++--
   1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c
b/drivers/net/dsa/b53/b53_common.c
index 274f367..e070ff6 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -597,10 +597,10 @@ static void b53_switch_reset_gpio(struct
b53_device *dev)
   /* Reset sequence: RESET low(50ms)->high(20ms)
*/
   gpio_set_value(gpio, 0);
-mdelay(50);
+msleep(50);
 gpio_set_value(gpio, 1);
-mdelay(20);
+msleep(20);
 dev->current_page = 0xff;
   }


Would that also imply gpio_set_value could be gpio_set_value_cansleep?


Yes, I think gpio_set_value_cansleep() is okay here?
Do I need to send a V2 patch to replace gpio_set_value()?

Yes, I would lump these two changes in the same patch since this is
effectively about solving sleeping vs. non sleeping operations.


Okay, I have sent a V2 patch, and you can have a look :)


Best wishes,
Jia-Ju Bai


[PATCH v2] net: dsa: b53: Using sleep-able operations in b53_switch_reset_gpio

2018-04-11 Thread Jia-Ju Bai
b53_switch_reset_gpio() is never called in atomic context.

The call chain ending up at b53_switch_reset_gpio() is:
[1] b53_switch_reset_gpio() <- b53_switch_reset() <-
b53_reset_switch() <- b53_setup()

b53_switch_reset_gpio() is set as ".setup" in struct dsa_switch_ops.
This function is not called in atomic context.

Despite never getting called from atomic context, b53_switch_reset_gpio()
calls non-sleep operations mdelay() and gpio_set_value().
They are not necessary and can be replaced with msleep() 
and gpio_set_value_cansleep().

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use gpio_set_value_cansleep() to replace gpio_set_value() additionally.
  Thanks for Florian and Phil for good advice.
---
 drivers/net/dsa/b53/b53_common.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 274f367..36cc60d 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -596,11 +596,11 @@ static void b53_switch_reset_gpio(struct b53_device *dev)
 
/* Reset sequence: RESET low(50ms)->high(20ms)
 */
-   gpio_set_value(gpio, 0);
-   mdelay(50);
+   gpio_set_value_cansleep(gpio, 0);
+   msleep(50);
 
-   gpio_set_value(gpio, 1);
-   mdelay(20);
+   gpio_set_value_cansleep(gpio, 1);
+   msleep(20);
 
dev->current_page = 0xff;
 }
-- 
1.9.1



Re: [PATCH v2] dec: tulip: de4x5: Replace mdelay with usleep_range in de4x5_hw_init

2018-04-11 Thread Jia-Ju Bai



On 2018/4/12 0:16, James Bottomley wrote:

On Wed, 2018-04-11 at 23:39 +0800, Jia-Ju Bai wrote:

de4x5_hw_init() is never called in atomic context.

de4x5_hw_init() is only called by de4x5_pci_probe(), which is only
set as ".probe" in struct pci_driver.

Despite never getting called from atomic context, de4x5_hw_init()
calls mdelay() to busily wait. This is not necessary and can be
replaced with usleep_range() to  avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Did you actually test this?  The usual reason for wanting m/udelay is
that the timing must be exact.  The driver is filled with mdelay()s for
this reason.  The one you've picked on is in the init path so it won't
affect the runtime in any way.  I also don't think we have the hrtimer
machinery for usleep_range() to work properly on parisc, so I don't
think the replacement works.

James



Hello, James.
Thanks for your reply :)

I agree that usleep_range() here will not much affect the real execution 
of this driver.


But I think usleep_range() can more opportunity for other threads to use 
the CPU core to schedule during waiting.
That is why I detect mdelay() that can be replaced with msleep() or 
usleep_range().



Best wishes,
Jia-Ju Bai


[PATCH v2] net: samsung: sxgbe: Replace mdelay with usleep_range in sxgbe_sw_reset

2018-04-11 Thread Jia-Ju Bai
sxgbe_sw_reset() is never called in atomic context.

sxgbe_sw_reset() is only called by sxgbe_drv_probe(), which is 
only called by sxgbe_platform_probe().
sxgbe_platform_probe() is set as ".probe" in struct platform_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, sxgbe_sw_reset()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use usleep_range() to correct usleep() in v1.

--- 
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c 
b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 89831ad..99cd586 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -2038,7 +2038,7 @@ static int sxgbe_sw_reset(void __iomem *addr)
if (!(readl(addr + SXGBE_DMA_MODE_REG) &
  SXGBE_DMA_SOFT_RESET))
break;
-   mdelay(10);
+   usleep_range(1, 11000);
}
 
if (retry_count < 0)
-- 
1.9.1



[PATCH v2] dec: tulip: de4x5: Replace mdelay with usleep_range in de4x5_hw_init

2018-04-11 Thread Jia-Ju Bai
de4x5_hw_init() is never called in atomic context.

de4x5_hw_init() is only called by de4x5_pci_probe(), which is only 
set as ".probe" in struct pci_driver.

Despite never getting called from atomic context, de4x5_hw_init() 
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to 
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Use usleep_range() to correct usleep() in v1.

---
 drivers/net/ethernet/dec/tulip/de4x5.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c 
b/drivers/net/ethernet/dec/tulip/de4x5.c
index 0affee9..3fb0119 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -1107,7 +1107,7 @@ static int (*dc_infoblock[])(struct net_device *dev, 
u_char, u_char *) = {
pdev = to_pci_dev (gendev);
pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP);
 }
-mdelay(10);
+usleep_range(1, 11000);
 
 RESET_DE4X5;
 
-- 
1.9.1



Re: [PATCH 1/2] staging: irda: Replace mdelay with usleep_range in stir421x_fw_upload

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 22:26, David Miller wrote:

From: Jia-Ju Bai 
Date: Wed, 11 Apr 2018 16:20:22 +0800


Okay, I now know why many of my patches were not replied.

Many of your patches are not responded to because you handle patch
feedback poorly sometimes.


Okay, thanks for pointing it out.
I will handle patch feedback much more carefully.


Also, all of your networking submissions have been dropped because
the net-next tree is closed.



Okay, I will choose the proper tree to submit.


Best wishes,
Jia-Ju Bai


[PATCH v3] net: tipc: Replace GFP_ATOMIC with GFP_KERNEL in tipc_mon_create

2018-04-11 Thread Jia-Ju Bai
tipc_mon_create() is never called in atomic context.

The call chain ending up at tipc_mon_create() is:
[1] tipc_mon_create() <- tipc_enable_bearer() <- tipc_nl_bearer_enable()
tipc_nl_bearer_enable() calls rtnl_lock(), which indicates this function
is not called in atomic context.

Despite never getting called from atomic context,
tipc_mon_create() calls kzalloc() with GFP_ATOMIC,
which does not sleep for allocation.
GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL,
which can sleep and improve the possibility of successful allocation.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
v2:
* Modify the description of GFP_ATOMIC in v1.
  Thank Eric for good advice.
v3:
* Modify wrong text in description in v2.
  Thank Ying for good advice.
---
 net/tipc/monitor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index 9e109bb..9714d80 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -604,9 +604,9 @@ int tipc_mon_create(struct net *net, int bearer_id)
if (tn->monitors[bearer_id])
return 0;
 
-   mon = kzalloc(sizeof(*mon), GFP_ATOMIC);
-   self = kzalloc(sizeof(*self), GFP_ATOMIC);
-   dom = kzalloc(sizeof(*dom), GFP_ATOMIC);
+   mon = kzalloc(sizeof(*mon), GFP_KERNEL);
+   self = kzalloc(sizeof(*self), GFP_KERNEL);
+   dom = kzalloc(sizeof(*dom), GFP_KERNEL);
if (!mon || !self || !dom) {
kfree(mon);
kfree(self);
-- 
1.9.1



Re: [PATCH v2] net: tipc: Replace GFP_ATOMIC with GFP_KERNEL in tipc_mon_create

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 18:11, Ying Xue wrote:

On 04/10/2018 09:17 AM, Jia-Ju Bai wrote:

tipc_mon_create() is never called in atomic context.

The call chain ending up at dn_route_init() is:

Sorry, I don't think there is any relationship between the following
call chain with dn_route_init().


[1] tipc_mon_create() <- tipc_enable_bearer() <- tipc_nl_bearer_enable()
tipc_nl_bearer_enable() calls rtnl_lock(), which indicates this function
is not called in atomic context.

Despite never getting called from atomic context,
tipc_mon_create() calls kzalloc() with GFP_ATOMIC,
which does not sleep for allocation.
GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL,
which can sleep and improve the possibility of sucessful allocation.

s/sucessful/successful


Thanks for your reply.
I am sorry for my mistakes.
I will revised the text and send a V3.


Jia-Ju Bai


Re: [PATCH 1/2] staging: irda: Replace mdelay with usleep_range in stir421x_fw_upload

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 16:17, Greg KH wrote:

On Wed, Apr 11, 2018 at 04:11:00PM +0800, Jia-Ju Bai wrote:


On 2018/4/11 16:03, Greg KH wrote:

On Wed, Apr 11, 2018 at 03:17:10PM +0800, Jia-Ju Bai wrote:

On 2018/4/11 14:41, Greg KH wrote:

On Wed, Apr 11, 2018 at 09:29:34AM +0800, Jia-Ju Bai wrote:

stir421x_fw_upload() is never called in atomic context.

The call chain ending up at stir421x_fw_upload() is:
[1] stir421x_fw_upload() <- stir421x_patch_device() <- irda_usb_probe()

irda_usb_probe() is set as ".probe" in struct usb_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, stir421x_fw_upload()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
drivers/staging/irda/drivers/irda-usb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Please, at the very least, work off of Linus's tree.  There is no
drivers/staging/irda/ anymore :)


Okay, sorry.
Could you please recommend me a right tree or its git address?

Have you looked in the MAINTAINERS file?  Worst case, always use
linux-next.

greg k-h

Oh, sorry, I did notice the git tree in the MAINTAINERS file.
I always used linux-stable.

linux-stable is almost never the tree to use as it is almost always
12000 patches behind what is in Linus's tree and about 2 changes
behind linux-next.



Okay, I now know why many of my patches were not replied.
I should choose correct tree in the MAINTAINERS file.
Thanks :)


Best wishes,
Jia-Ju Bai


Re: [PATCH 1/2] staging: irda: Replace mdelay with usleep_range in stir421x_fw_upload

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 16:03, Greg KH wrote:

On Wed, Apr 11, 2018 at 03:17:10PM +0800, Jia-Ju Bai wrote:


On 2018/4/11 14:41, Greg KH wrote:

On Wed, Apr 11, 2018 at 09:29:34AM +0800, Jia-Ju Bai wrote:

stir421x_fw_upload() is never called in atomic context.

The call chain ending up at stir421x_fw_upload() is:
[1] stir421x_fw_upload() <- stir421x_patch_device() <- irda_usb_probe()

irda_usb_probe() is set as ".probe" in struct usb_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, stir421x_fw_upload()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
   drivers/staging/irda/drivers/irda-usb.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

Please, at the very least, work off of Linus's tree.  There is no
drivers/staging/irda/ anymore :)


Okay, sorry.
Could you please recommend me a right tree or its git address?

Have you looked in the MAINTAINERS file?  Worst case, always use
linux-next.

greg k-h


Oh, sorry, I did notice the git tree in the MAINTAINERS file.
I always used linux-stable.
Thanks for telling me this :)


Best wishes,
Jia-Ju Bai


Re: [PATCH 1/2] staging: irda: Replace mdelay with usleep_range in stir421x_fw_upload

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 14:41, Greg KH wrote:

On Wed, Apr 11, 2018 at 09:29:34AM +0800, Jia-Ju Bai wrote:

stir421x_fw_upload() is never called in atomic context.

The call chain ending up at stir421x_fw_upload() is:
[1] stir421x_fw_upload() <- stir421x_patch_device() <- irda_usb_probe()

irda_usb_probe() is set as ".probe" in struct usb_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, stir421x_fw_upload()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
  drivers/staging/irda/drivers/irda-usb.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Please, at the very least, work off of Linus's tree.  There is no
drivers/staging/irda/ anymore :)



Okay, sorry.
Could you please recommend me a right tree or its git address?


Best wishes,
Jia-Ju Bai


Re: [PATCH] net: dsa: b53: Replace mdelay with msleep in b53_switch_reset_gpio

2018-04-11 Thread Jia-Ju Bai



On 2018/4/11 13:30, Phil Reid wrote:

On 11/04/2018 09:51, Jia-Ju Bai wrote:

b53_switch_reset_gpio() is never called in atomic context.

The call chain ending up at b53_switch_reset_gpio() is:
[1] b53_switch_reset_gpio() <- b53_switch_reset() <-
b53_reset_switch() <- b53_setup()

b53_switch_reset_gpio() is set as ".setup" in struct dsa_switch_ops.
This function is not called in atomic context.

Despite never getting called from atomic context, 
b53_switch_reset_gpio()

calls mdelay() to busily wait.
This is not necessary and can be replaced with msleep() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
  drivers/net/dsa/b53/b53_common.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c 
b/drivers/net/dsa/b53/b53_common.c

index 274f367..e070ff6 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -597,10 +597,10 @@ static void b53_switch_reset_gpio(struct 
b53_device *dev)

  /* Reset sequence: RESET low(50ms)->high(20ms)
   */
  gpio_set_value(gpio, 0);
-mdelay(50);
+msleep(50);
gpio_set_value(gpio, 1);
-mdelay(20);
+msleep(20);
dev->current_page = 0xff;
  }


Would that also imply gpio_set_value could be gpio_set_value_cansleep?



Yes, I think gpio_set_value_cansleep() is okay here?
Do I need to send a V2 patch to replace gpio_set_value()?


Best wishes,
Jia-Ju Bai


[PATCH 1/2] isdn: hisax_fcpcipnp: Replace mdelay with usleep_range in fcpci_init

2018-04-10 Thread Jia-Ju Bai
fcpci_init() is never called in atomic context.

The call chain ending up at fcpci_init() is:
[1] fcpci_init() <- fcpcipnp_setup() <- fcpnp_probe()

fcpnp_probe() is set as ".probe" in struct pnp_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, fcpci_init()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/isdn/hisax/hisax_fcpcipnp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c 
b/drivers/isdn/hisax/hisax_fcpcipnp.c
index e4f7573..4789c9d 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -706,7 +706,7 @@ static inline void fcpci_init(struct fritz_adapter *adapter)
 
outb(AVM_STATUS1_ENA_IOM | adapter->irq,
 adapter->io + AVM_STATUS1);
-   mdelay(10);
+   usleep_range(1, 11000);
 }
 
 // --
-- 
1.9.1



[PATCH 2/2] isdn: hisax_fcpcipnp: Replace mdelay with usleep_range in fcpcipnp_setup

2018-04-10 Thread Jia-Ju Bai
fcpcipnp_setup() is never called in atomic context.

The call chain ending up at fcpcipnp_setup() is:
[1] fcpcipnp_setup() <- fcpnp_probe()

fcpnp_probe() is set as ".probe" in struct pnp_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, fcpcipnp_setup()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/isdn/hisax/hisax_fcpcipnp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c 
b/drivers/isdn/hisax/hisax_fcpcipnp.c
index e4f7573..06068a42 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -772,11 +772,11 @@ static int fcpcipnp_setup(struct fritz_adapter *adapter)
 
// Reset
outb(0, adapter->io + AVM_STATUS0);
-   mdelay(10);
+   usleep_range(1, 11000);
outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
-   mdelay(10);
+   usleep_range(1, 11000);
outb(0, adapter->io + AVM_STATUS0);
-   mdelay(10);
+   usleep_range(1, 11000);
 
switch (adapter->type) {
case AVM_FRITZ_PCIV2:
-- 
1.9.1



[PATCH] net: sun: cassini: Replace GFP_ATOMIC with GFP_KERNEL in cas_check_invariants

2018-04-10 Thread Jia-Ju Bai
cas_check_invariants() is never called in atomic context.

cas_check_invariants() is only called by cas_init_one(), which is 
only set as ".probe" in struct pci_driver.

Despite never getting called from atomic context,
cas_check_invariants() calls alloc_pages() with GFP_ATOMIC,
which does not sleep for allocation.
GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL,
which can sleep and improve the possibility of sucessful allocation.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/sun/cassini.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sun/cassini.c 
b/drivers/net/ethernet/sun/cassini.c
index 382993c..4dd38e3 100644
--- a/drivers/net/ethernet/sun/cassini.c
+++ b/drivers/net/ethernet/sun/cassini.c
@@ -3412,7 +3412,7 @@ static int cas_check_invariants(struct cas *cp)
 #ifdef USE_PAGE_ORDER
if (PAGE_SHIFT < CAS_JUMBO_PAGE_SHIFT) {
/* see if we can allocate larger pages */
-   struct page *page = alloc_pages(GFP_ATOMIC,
+   struct page *page = alloc_pages(GFP_KERNEL,
CAS_JUMBO_PAGE_SHIFT -
PAGE_SHIFT);
if (page) {
-- 
1.9.1



[PATCH] net: samsung: sxgbe: Replace mdelay with usleep_range in sxgbe_sw_reset

2018-04-10 Thread Jia-Ju Bai
sxgbe_sw_reset() is never called in atomic context.

sxgbe_sw_reset() is only called by sxgbe_drv_probe(), which is 
only called by sxgbe_platform_probe().
sxgbe_platform_probe() is set as ".probe" in struct platform_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, sxgbe_sw_reset()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c 
b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 89831ad..99cd586 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -2038,7 +2038,7 @@ static int sxgbe_sw_reset(void __iomem *addr)
if (!(readl(addr + SXGBE_DMA_MODE_REG) &
  SXGBE_DMA_SOFT_RESET))
break;
-   mdelay(10);
+   usleep(1, 11000);
}
 
if (retry_count < 0)
-- 
1.9.1



[PATCH] net: ieee802154: atusb: Replace GFP_ATOMIC with GFP_KERNEL in atusb_probe

2018-04-10 Thread Jia-Ju Bai
atusb_probe() is never called in atomic context.
This function is only set as ".probe" in struct usb_driver.

Despite never getting called from atomic context,
atusb_probe() calls usb_alloc_urb() with GFP_ATOMIC,
which does not sleep for allocation.
GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL,
which can sleep and improve the possibility of sucessful allocation.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ieee802154/atusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index ef68851..ab6a505 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -789,7 +789,7 @@ static int atusb_probe(struct usb_interface *interface,
atusb->tx_dr.bRequest = ATUSB_TX;
atusb->tx_dr.wValue = cpu_to_le16(0);
 
-   atusb->tx_urb = usb_alloc_urb(0, GFP_ATOMIC);
+   atusb->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!atusb->tx_urb)
goto fail;
 
-- 
1.9.1



[PATCH] intel: i40evf: Replace GFP_ATOMIC with GFP_KERNEL in i40evf_add_vlan

2018-04-10 Thread Jia-Ju Bai
i40evf_add_vlan() is never called in atomic context.

i40evf_add_vlan() is only called by i40evf_vlan_rx_add_vid(), 
which is only set as ".ndo_vlan_rx_add_vid" in struct net_device_ops.
".ndo_vlan_rx_add_vid" is not called in atomic context.

Despite never getting called from atomic context, 
i40evf_add_vlan() calls kzalloc() with GFP_ATOMIC, 
which does not sleep for allocation.
GFP_ATOMIC is not necessary and can be replaced with GFP_KERNEL, 
which can sleep and improve the possibility of sucessful allocation.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/intel/i40evf/i40evf_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c 
b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 1825d95..04b2b9c 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -770,7 +770,7 @@ i40evf_vlan_filter *i40evf_add_vlan(struct i40evf_adapter 
*adapter, u16 vlan)
 
f = i40evf_find_vlan(adapter, vlan);
if (!f) {
-   f = kzalloc(sizeof(*f), GFP_ATOMIC);
+   f = kzalloc(sizeof(*f), GFP_KERNEL);
if (!f)
goto clearout;
 
-- 
1.9.1



[PATCH] dec: tulip: de4x5: Replace mdelay with usleep_range in de4x5_hw_init

2018-04-10 Thread Jia-Ju Bai
de4x5_hw_init() is never called in atomic context.

de4x5_hw_init() is only called by de4x5_pci_probe(), which is only 
set as ".probe" in struct pci_driver.

Despite never getting called from atomic context, de4x5_hw_init() 
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to 
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/ethernet/dec/tulip/de4x5.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c 
b/drivers/net/ethernet/dec/tulip/de4x5.c
index 0affee9..3fb0119 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -1107,7 +1107,7 @@ static int (*dc_infoblock[])(struct net_device *dev, 
u_char, u_char *) = {
pdev = to_pci_dev (gendev);
pci_write_config_byte(pdev, PCI_CFDA_PSM, WAKEUP);
 }
-mdelay(10);
+usleep(1, 11000);
 
 RESET_DE4X5;
 
-- 
1.9.1



[PATCH] net: dsa: b53: Replace mdelay with msleep in b53_switch_reset_gpio

2018-04-10 Thread Jia-Ju Bai
b53_switch_reset_gpio() is never called in atomic context.

The call chain ending up at b53_switch_reset_gpio() is:
[1] b53_switch_reset_gpio() <- b53_switch_reset() <- 
b53_reset_switch() <- b53_setup()

b53_switch_reset_gpio() is set as ".setup" in struct dsa_switch_ops.
This function is not called in atomic context.

Despite never getting called from atomic context, b53_switch_reset_gpio()
calls mdelay() to busily wait.
This is not necessary and can be replaced with msleep() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/dsa/b53/b53_common.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 274f367..e070ff6 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -597,10 +597,10 @@ static void b53_switch_reset_gpio(struct b53_device *dev)
/* Reset sequence: RESET low(50ms)->high(20ms)
 */
gpio_set_value(gpio, 0);
-   mdelay(50);
+   msleep(50);
 
gpio_set_value(gpio, 1);
-   mdelay(20);
+   msleep(20);
 
dev->current_page = 0xff;
 }
-- 
1.9.1



[PATCH 2/2] net: can: sja1000: Replace mdelay with usleep_range in pcan_add_channels

2018-04-10 Thread Jia-Ju Bai
pcan_add_channels() is never called in atomic context.

pcan_add_channels() is only called by pcan_probe(), which is only set as 
".probe" in struct pcmcia_driver.

Despite never getting called from atomic context, pcan_add_channels()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/can/sja1000/peak_pcmcia.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/sja1000/peak_pcmcia.c 
b/drivers/net/can/sja1000/peak_pcmcia.c
index dd56133..1a1fbf3 100644
--- a/drivers/net/can/sja1000/peak_pcmcia.c
+++ b/drivers/net/can/sja1000/peak_pcmcia.c
@@ -530,7 +530,7 @@ static int pcan_add_channels(struct pcan_pccard *card)
pcan_write_reg(card, PCC_CCR, ccr);
 
/* wait 2ms before unresetting channels */
-   mdelay(2);
+   usleep_range(2000, 3000);
 
ccr &= ~PCC_CCR_RST_ALL;
pcan_write_reg(card, PCC_CCR, ccr);
-- 
1.9.1



[PATCH 1/2] net: can: sja1000: Replace mdelay with usleep_range in peak_pci_probe

2018-04-10 Thread Jia-Ju Bai
peak_pci_probe() is never called in atomic context.

peak_pci_probe() is set as ".probe" in struct pci_driver.

Despite never getting called from atomic context, peak_pci_probe()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/net/can/sja1000/peak_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/sja1000/peak_pci.c 
b/drivers/net/can/sja1000/peak_pci.c
index 131026f..48cf821 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -608,7 +608,7 @@ static int peak_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
writeb(0x00, cfg_base + PITA_GPIOICR);
/* Toggle reset */
writeb(0x05, cfg_base + PITA_MISC + 3);
-   mdelay(5);
+   usleep_range(5000, 6000);
/* Leave parport mux mode */
writeb(0x04, cfg_base + PITA_MISC + 3);
 
-- 
1.9.1



[PATCH 2/2] staging: irda: Replace mdelay with usleep_range in irda_usb_probe

2018-04-10 Thread Jia-Ju Bai
irda_usb_probe() is never called in atomic context.

irda_usb_probe() is only set as ".probe" in struct usb_driver.

Despite never getting called from atomic context, irda_usb_probe()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/staging/irda/drivers/irda-usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/irda/drivers/irda-usb.c 
b/drivers/staging/irda/drivers/irda-usb.c
index 723e49b..6ff5b08 100644
--- a/drivers/staging/irda/drivers/irda-usb.c
+++ b/drivers/staging/irda/drivers/irda-usb.c
@@ -1710,7 +1710,7 @@ static int irda_usb_probe(struct usb_interface *intf,
pr_debug("usb_control_msg failed %d\n", ret);
goto err_out_3;
} else {
-   mdelay(10);
+   usleep_range(1, 11000);
}
}
 
-- 
1.9.1



[PATCH 1/2] staging: irda: Replace mdelay with usleep_range in stir421x_fw_upload

2018-04-10 Thread Jia-Ju Bai
stir421x_fw_upload() is never called in atomic context.

The call chain ending up at stir421x_fw_upload() is:
[1] stir421x_fw_upload() <- stir421x_patch_device() <- irda_usb_probe()

irda_usb_probe() is set as ".probe" in struct usb_driver.
This function is not called in atomic context.

Despite never getting called from atomic context, stir421x_fw_upload()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.

Signed-off-by: Jia-Ju Bai 
---
 drivers/staging/irda/drivers/irda-usb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/irda/drivers/irda-usb.c 
b/drivers/staging/irda/drivers/irda-usb.c
index 723e49b..c6c8c2c 100644
--- a/drivers/staging/irda/drivers/irda-usb.c
+++ b/drivers/staging/irda/drivers/irda-usb.c
@@ -1050,7 +1050,7 @@ static int stir421x_fw_upload(struct irda_usb_cb *self,
if (ret < 0)
break;
 
-   mdelay(10);
+   usleep_range(1, 11000);
}
 
kfree(patch_block);
-- 
1.9.1



  1   2   3   >