[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1324645592.2223.9.camel@edumazet-HP-Compaq-6005-Pro-SFF-PC>
Date: Fri, 23 Dec 2011 14:06:32 +0100
From: Eric Dumazet <eric.dumazet@...il.com>
To: Xi Wang <xi.wang@...il.com>
Cc: Tom Herbert <therbert@...gle.com>,
"David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org
Subject: Re: [PATCH v2] rps: fix insufficient bounds checking in
store_rps_dev_flow_table_cnt()
Le vendredi 23 décembre 2011 à 00:56 -0500, Xi Wang a écrit :
> On Dec 23, 2011, at 12:35 AM, Eric Dumazet wrote:
> > By the way, the theorical limit on number of flows on 64bit platform is
> > 2^32 (rxhash being an u32)
> >
> > Not sure spending 32GB per table would be wise for typical machines :)
>
> True, a large rps_flow_cnt is not that useful. ;-)
>
> Anyway, my point is that if the patch looks confusing to you, then
> it is probably not good. I am happy to see a more elegant fix.
>
I'll submit following patch for net-next, once your patch is in this
tree.
- Full u32 range on 64bit arches (2^32 flows max)
- Use of kstrtoul() instead of simple_strtoul()
net/core/net-sysfs.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 385aefe..63bd152 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -618,7 +618,7 @@ static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
char *buf)
{
struct rps_dev_flow_table *flow_table;
- unsigned int val = 0;
+ unsigned long val = 0;
rcu_read_lock();
flow_table = rcu_dereference(queue->rps_flow_table);
@@ -626,7 +626,7 @@ static ssize_t show_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
val = flow_table->mask + 1;
rcu_read_unlock();
- return sprintf(buf, "%u\n", val);
+ return sprintf(buf, "%lu\n", val);
}
static void rps_dev_flow_table_release_work(struct work_struct *work)
@@ -650,24 +650,23 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
struct rx_queue_attribute *attr,
const char *buf, size_t len)
{
- unsigned int count;
- char *endp;
+ unsigned long i, count;
struct rps_dev_flow_table *table, *old_table;
static DEFINE_SPINLOCK(rps_dev_flow_lock);
+ int rc;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- count = simple_strtoul(buf, &endp, 0);
- if (endp == buf)
- return -EINVAL;
+ rc = kstrtoul(buf, 0, &count);
+ if (rc < 0)
+ return rc;
if (count) {
- int i;
-
- if (count > INT_MAX)
- return -EINVAL;
count = roundup_pow_of_two(count);
+ if (!count ||
+ count != (unsigned long)(u32)count)
+ return -EINVAL;
if (count > (ULONG_MAX - sizeof(struct rps_dev_flow_table))
/ sizeof(struct rps_dev_flow)) {
/* Enforce a limit to prevent overflow */
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists