* [PATCH 0/7] fix IS_ERR_VALUE usage
@ 2016-02-15 14:35 Andrzej Hajda
2016-02-15 14:35 ` [PATCH 1/7] netfilter: " Andrzej Hajda
2016-02-17 10:48 ` [PATCH 0/7] " Arnd Bergmann
0 siblings, 2 replies; 5+ messages in thread
From: Andrzej Hajda @ 2016-02-15 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Andrzej Hajda, coreteam, linux-arm-kernel, linux-fbdev,
linux-media, linux-mips, linuxppc-dev, linux-samsung-soc,
linux-serial, linux-usb, netdev, netfilter-devel,
Bartlomiej Zolnierkiewicz, Marek Szyprowski
Hi,
This small set of independent patches tries to fix incorrect
IS_ERR_VALUE macro usage. It fixes most usages leading to errors
as described in [1]. It also follows conclusion from the discussion
[1][2] - IS_ERR_VALUE should be used only with unsigned long type,
signed types should use comparison 'ret < 0'.
The patchset does not fix errors present in net/ethernet/freescale
and soc/fsq/qe drivers - these drivers mixes different types:
dma_addr_t, u32, unsigned long, fixing it properly seems to me more
challenging, maybe maintainers or brave volunteers can look it.
The list of missing fixes:
drivers/net/ethernet/freescale/fs_enet/mac-scc.c:149:36-37: WARNING: incorrect argument type in IS_ERR_VALUE(fep -> ring_mem_addr)
drivers/net/ethernet/freescale/ucc_geth.c:2237:48-49: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> tx_bd_ring_offset [ j ])
drivers/net/ethernet/freescale/ucc_geth.c:2314:48-49: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> rx_bd_ring_offset [ j ])
drivers/net/ethernet/freescale/ucc_geth.c:2524:44-45: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> tx_glbl_pram_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2544:45-46: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> thread_dat_tx_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2571:46-47: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> send_q_mem_reg_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2612:42-43: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> scheduler_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2659:54-55: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> tx_fw_statistics_pram_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2696:44-45: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> rx_glbl_pram_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2715:45-46: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> thread_dat_rx_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2736:54-55: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> rx_fw_statistics_pram_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2756:53-54: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> rx_irq_coalescing_tbl_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2822:44-45: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> rx_bd_qs_tbl_offset)
drivers/net/ethernet/freescale/ucc_geth.c:2908:47-48: WARNING: incorrect argument type in IS_ERR_VALUE(ugeth -> exf_glbl_param_offset)
drivers/net/ethernet/freescale/ucc_geth.c:292:36-37: WARNING: incorrect argument type in IS_ERR_VALUE(init_enet_offset)
drivers/net/ethernet/freescale/ucc_geth.c:3042:39-40: WARNING: incorrect argument type in IS_ERR_VALUE(init_enet_pram_offset)
drivers/soc/fsl/qe/ucc_fast.c:271:60-61: WARNING: incorrect argument type in IS_ERR_VALUE(uccf -> ucc_fast_tx_virtual_fifo_base_offset)
drivers/soc/fsl/qe/ucc_fast.c:284:60-61: WARNING: incorrect argument type in IS_ERR_VALUE(uccf -> ucc_fast_rx_virtual_fifo_base_offset)
drivers/soc/fsl/qe/ucc_slow.c:186:38-39: WARNING: incorrect argument type in IS_ERR_VALUE(uccs -> us_pram_offset)
drivers/soc/fsl/qe/ucc_slow.c:213:38-39: WARNING: incorrect argument type in IS_ERR_VALUE(uccs -> rx_base_offset)
drivers/soc/fsl/qe/ucc_slow.c:224:38-39: WARNING: incorrect argument type in IS_ERR_VALUE(uccs -> tx_base_offset)
drivers/net/ethernet/freescale/fs_enet/mac-fcc.c:110:35-36: WARNING: unknown argument type in IS_ERR_VALUE(fpi -> dpram_offset)
[1]: http://permalink.gmane.org/gmane.linux.kernel/2120927
[2]: http://permalink.gmane.org/gmane.linux.kernel/2150581
Regards
Andrzej
Andrzej Hajda (7):
netfilter: fix IS_ERR_VALUE usage
MIPS: module: fix incorrect IS_ERR_VALUE macro usages
drivers: char: mem: fix IS_ERROR_VALUE usage
atmel-isi: fix IS_ERR_VALUE usage
serial: clps711x: fix IS_ERR_VALUE usage
fbdev: exynos: fix IS_ERR_VALUE usage
usb: gadget: fsl_qe_udc: fix IS_ERR_VALUE usage
arch/mips/kernel/module-rela.c | 2 +-
arch/mips/kernel/module.c | 2 +-
drivers/char/mem.c | 2 +-
drivers/media/platform/soc_camera/atmel-isi.c | 4 ++--
drivers/tty/serial/clps711x.c | 14 ++++++++------
drivers/usb/gadget/udc/fsl_qe_udc.c | 2 +-
drivers/video/fbdev/exynos/exynos_mipi_dsi.c | 6 +++---
include/linux/netfilter/x_tables.h | 6 +++---
net/ipv4/netfilter/arp_tables.c | 11 +++++++----
net/ipv4/netfilter/ip_tables.c | 12 ++++++++----
net/ipv6/netfilter/ip6_tables.c | 13 +++++++++----
11 files changed, 44 insertions(+), 30 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/7] netfilter: fix IS_ERR_VALUE usage
2016-02-15 14:35 [PATCH 0/7] fix IS_ERR_VALUE usage Andrzej Hajda
@ 2016-02-15 14:35 ` Andrzej Hajda
2016-02-17 2:31 ` Al Viro
2016-02-17 10:48 ` [PATCH 0/7] " Arnd Bergmann
1 sibling, 1 reply; 5+ messages in thread
From: Andrzej Hajda @ 2016-02-15 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Andrzej Hajda, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam
IS_ERR_VALUE should be used only with unsigned long type.
Otherwise it can work incorrectly. To achieve this function
xt_percpu_counter_alloc is modified to return unsigned long,
and its result is assigned to temporary variable to perform
error checking, before assigning to .pcnt field.
The patch follows conclusion from discussion on LKML [1][2].
[1]: http://permalink.gmane.org/gmane.linux.kernel/2120927
[2]: http://permalink.gmane.org/gmane.linux.kernel/2150581
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
---
include/linux/netfilter/x_tables.h | 6 +++---
net/ipv4/netfilter/arp_tables.c | 11 +++++++----
net/ipv4/netfilter/ip_tables.c | 12 ++++++++----
net/ipv6/netfilter/ip6_tables.c | 13 +++++++++----
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index c557741..79d4306 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -370,16 +370,16 @@ static inline unsigned long ifname_compare_aligned(const char *_a,
* allows us to return 0 for single core systems without forcing
* callers to deal with SMP vs. NONSMP issues.
*/
-static inline u64 xt_percpu_counter_alloc(void)
+static inline unsigned long xt_percpu_counter_alloc(void)
{
if (nr_cpu_ids > 1) {
void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
sizeof(struct xt_counters));
if (res == NULL)
- return (u64) -ENOMEM;
+ return -ENOMEM;
- return (u64) (__force unsigned long) res;
+ return (__force unsigned long) res;
}
return 0;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b488cac..6dcc208 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -521,14 +521,16 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
struct xt_entry_target *t;
struct xt_target *target;
int ret;
+ unsigned long pcnt;
ret = check_entry(e, name);
if (ret)
return ret;
- e->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(e->counters.pcnt))
+ pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt))
return -ENOMEM;
+ e->counters.pcnt = pcnt;
t = arpt_get_target(e);
target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
@@ -1423,11 +1425,12 @@ static int translate_compat_table(const char *name,
i = 0;
xt_entry_foreach(iter1, entry1, newinfo->size) {
- iter1->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(iter1->counters.pcnt)) {
+ unsigned long pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt)) {
ret = -ENOMEM;
break;
}
+ iter1->counters.pcnt = pcnt;
ret = check_target(iter1, name);
if (ret != 0) {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index b99affa..ad57c78 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -665,14 +665,16 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
unsigned int j;
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;
+ unsigned long pcnt;
ret = check_entry(e, name);
if (ret)
return ret;
- e->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(e->counters.pcnt))
+ pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt))
return -ENOMEM;
+ e->counters.pcnt = pcnt;
j = 0;
mtpar.net = net;
@@ -1609,10 +1611,12 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
struct xt_mtchk_param mtpar;
unsigned int j;
int ret = 0;
+ unsigned long pcnt;
- e->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(e->counters.pcnt))
+ pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt))
return -ENOMEM;
+ e->counters.pcnt = pcnt;
j = 0;
mtpar.net = net;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 99425cf..4291c8d 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -678,14 +678,16 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
unsigned int j;
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;
+ unsigned long pcnt;
ret = check_entry(e, name);
if (ret)
return ret;
- e->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(e->counters.pcnt))
+ pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt))
return -ENOMEM;
+ e->counters.pcnt = pcnt;
j = 0;
mtpar.net = net;
@@ -1619,10 +1621,13 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,
int ret = 0;
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;
+ unsigned long pcnt;
- e->counters.pcnt = xt_percpu_counter_alloc();
- if (IS_ERR_VALUE(e->counters.pcnt))
+ pcnt = xt_percpu_counter_alloc();
+ if (IS_ERR_VALUE(pcnt))
return -ENOMEM;
+ e->counters.pcnt = pcnt;
+
j = 0;
mtpar.net = net;
mtpar.table = name;
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/7] netfilter: fix IS_ERR_VALUE usage
2016-02-15 14:35 ` [PATCH 1/7] netfilter: " Andrzej Hajda
@ 2016-02-17 2:31 ` Al Viro
2016-02-17 8:45 ` Andrzej Hajda
0 siblings, 1 reply; 5+ messages in thread
From: Al Viro @ 2016-02-17 2:31 UTC (permalink / raw)
To: Andrzej Hajda
Cc: linux-kernel, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam
On Mon, Feb 15, 2016 at 03:35:19PM +0100, Andrzej Hajda wrote:
> IS_ERR_VALUE should be used only with unsigned long type.
> Otherwise it can work incorrectly. To achieve this function
> xt_percpu_counter_alloc is modified to return unsigned long,
> and its result is assigned to temporary variable to perform
> error checking, before assigning to .pcnt field.
Wrong fix, IMO. Just have an anon union of u64 pcnt and
struct xt_counters __percpu *pcpu in there. And make this
> +static inline unsigned long xt_percpu_counter_alloc(void)
> {
> if (nr_cpu_ids > 1) {
> void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
> sizeof(struct xt_counters));
>
> if (res == NULL)
> - return (u64) -ENOMEM;
> + return -ENOMEM;
>
> - return (u64) (__force unsigned long) res;
> + return (__force unsigned long) res;
> }
>
> return 0;
take struct xt_counters * and return 0 or -ENOMEM. Storing the result of
allocation in ->pcpu of passed structure.
I mean, look at the callers -
> - e->counters.pcnt = xt_percpu_counter_alloc();
> - if (IS_ERR_VALUE(e->counters.pcnt))
> + pcnt = xt_percpu_counter_alloc();
> + if (IS_ERR_VALUE(pcnt))
> return -ENOMEM;
> + e->counters.pcnt = pcnt;
should be
if (xt_percpu_counter_alloc(&e->counters) < 0)
return -ENOMEM;
and similar for the rest of callers. Moreover, if you look at the _users_
of that fields, you'll see that a bunch of those actually want to use
->pcpu instead of doing all those casts.
Really, that's the point - IS_ERR_VALUE is a big red flag saying "we need
to figure out what's going on in that place", which does include reading
through the code. Mechanical "solutions" like that only hide the problem.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/7] netfilter: fix IS_ERR_VALUE usage
2016-02-17 2:31 ` Al Viro
@ 2016-02-17 8:45 ` Andrzej Hajda
0 siblings, 0 replies; 5+ messages in thread
From: Andrzej Hajda @ 2016-02-17 8:45 UTC (permalink / raw)
To: Al Viro
Cc: linux-kernel, Bartlomiej Zolnierkiewicz, Marek Szyprowski,
Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel, coreteam
On 02/17/2016 03:31 AM, Al Viro wrote:
> On Mon, Feb 15, 2016 at 03:35:19PM +0100, Andrzej Hajda wrote:
>> IS_ERR_VALUE should be used only with unsigned long type.
>> Otherwise it can work incorrectly. To achieve this function
>> xt_percpu_counter_alloc is modified to return unsigned long,
>> and its result is assigned to temporary variable to perform
>> error checking, before assigning to .pcnt field.
> Wrong fix, IMO. Just have an anon union of u64 pcnt and
> struct xt_counters __percpu *pcpu in there. And make this
>
>> +static inline unsigned long xt_percpu_counter_alloc(void)
>> {
>> if (nr_cpu_ids > 1) {
>> void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
>> sizeof(struct xt_counters));
>>
>> if (res == NULL)
>> - return (u64) -ENOMEM;
>> + return -ENOMEM;
>>
>> - return (u64) (__force unsigned long) res;
>> + return (__force unsigned long) res;
>> }
>>
>> return 0;
> take struct xt_counters * and return 0 or -ENOMEM. Storing the result of
> allocation in ->pcpu of passed structure.
>
> I mean, look at the callers -
>
>> - e->counters.pcnt = xt_percpu_counter_alloc();
>> - if (IS_ERR_VALUE(e->counters.pcnt))
>> + pcnt = xt_percpu_counter_alloc();
>> + if (IS_ERR_VALUE(pcnt))
>> return -ENOMEM;
>> + e->counters.pcnt = pcnt;
> should be
> if (xt_percpu_counter_alloc(&e->counters) < 0)
> return -ENOMEM;
>
> and similar for the rest of callers. Moreover, if you look at the _users_
> of that fields, you'll see that a bunch of those actually want to use
> ->pcpu instead of doing all those casts.
>
> Really, that's the point - IS_ERR_VALUE is a big red flag saying "we need
> to figure out what's going on in that place", which does include reading
> through the code. Mechanical "solutions" like that only hide the problem.
>
>
I just tried to make the patch the least invasive :)
The problem with your proposition is that struct xt_counters is exposed
to userspace as well as the structs containing it:
struct arpt_entry,
struct ipt_entry,
struct ip6t_entry
Mixing __percpu pointer into these structures seems problematic.
Maybe it would be better to skip adding union and do ugly casting
in xt_percpu_counter_alloc(struct xt_counters *) and friends.
Regards
Andrzej
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 0/7] fix IS_ERR_VALUE usage
2016-02-15 14:35 [PATCH 0/7] fix IS_ERR_VALUE usage Andrzej Hajda
2016-02-15 14:35 ` [PATCH 1/7] netfilter: " Andrzej Hajda
@ 2016-02-17 10:48 ` Arnd Bergmann
1 sibling, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2016-02-17 10:48 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Andrzej Hajda, linux-kernel, linux-mips, linux-fbdev,
linux-samsung-soc, Bartlomiej Zolnierkiewicz, netdev, linux-usb,
coreteam, netfilter-devel, linux-serial, Marek Szyprowski,
linuxppc-dev, linux-media
On Monday 15 February 2016 15:35:18 Andrzej Hajda wrote:
>
> Andrzej Hajda (7):
> netfilter: fix IS_ERR_VALUE usage
> MIPS: module: fix incorrect IS_ERR_VALUE macro usages
> drivers: char: mem: fix IS_ERROR_VALUE usage
> atmel-isi: fix IS_ERR_VALUE usage
> serial: clps711x: fix IS_ERR_VALUE usage
> fbdev: exynos: fix IS_ERR_VALUE usage
> usb: gadget: fsl_qe_udc: fix IS_ERR_VALUE usage
>
Can you Cc me the next time on all of the patches? I only got
three of them this time.
Arnd
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-02-17 10:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-15 14:35 [PATCH 0/7] fix IS_ERR_VALUE usage Andrzej Hajda
2016-02-15 14:35 ` [PATCH 1/7] netfilter: " Andrzej Hajda
2016-02-17 2:31 ` Al Viro
2016-02-17 8:45 ` Andrzej Hajda
2016-02-17 10:48 ` [PATCH 0/7] " Arnd Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).