Bug in mtd_speedtest?
I think I may have found an overflow condition in the speed calculation of mtd_speedtest on some platforms with larger flash partitions:
Consider for example if goodebcnt = 15000, and mtd->erasesize = 256*1024, then there is an intermediate product of 3932160000 which results in the sign bit being set on a 32 bit integer. Maybe k should be an unsigned long long?
.....
static long calc_speed(void)
{
long ms, k, speed;
ms = (finish.tv_sec - start.tv_sec) * 1000 +
(finish.tv_usec - start.tv_usec) / 1000;
k = goodebcnt * mtd->erasesize / 1024;
speed = (k * 1000) / ms;
return speed;
}.....
Quoted 7 lines · David Lambert
I think I may have found an overflow condition in the speed calculation of
mtd_speedteston some platforms with larger flash partitions:Consider for example if goodebcnt = 15000, and
mtd->erasesize= 256*1024, then there is an intermediate product of 3932160000 which results in the sign bit being set on a 32 bit integer. Maybe k should be an unsigned long long?
Please, just send a patch :-)
Signature · 2 lines
Best Regards, Artem Bityutskiy (Артём Битюцкий)
Artem,
Please find attached patch.
Regards,
Dave.
Quoted 10 lines · Artem Bityutskiy
Quoted 7 lines · David Lambert
I think I may have found an overflow condition in the speed calculation of
mtd_speedteston some platforms with larger flash partitions:Consider for example if goodebcnt = 15000, and
mtd->erasesize= 256*1024, then there is an intermediate product of 3932160000 which results in the sign bit being set on a 32 bit integer. Maybe k should be an unsigned long long?Please, just send a patch :-)
Index: mtd_speedtest.c
===================================================================
RCS file: /home/cvsroot/ECMB/src/snapgear/linux-2.6.30.1.x/drivers/mtd/tests/mtd_speedtest.c,v retrieving revision 1.1.1.1
mtd_speedtest.c +7 -6
@@ -281,13 +281,14 @@static long calc_speed (void ) { -long ms, k, speed; +uint64_t k; +long ms; - ms = (finish.tv_sec - start.tv_sec) *1000 + - (finish.tv_usec - start.tv_usec) /1000 ; - k = goodebcnt * mtd->erasesize /1024 ; - speed = (k *1000 ) / ms; -return speed; + ms = (finish.tv_sec - start.tv_sec) *1000 +/* Time in milli-seconds from start to ...*/ + (finish.tv_usec - start.tv_usec) /1000 ;/* finish */ + k = (goodebcnt * (mtd->erasesize /1024 ) *1000 );/* Number of kBytes transferred * 1000 */ +do_div (k, ms);/* k now contains number of kBytes/second */ +return k; }static int scan_for_bad_eraseblocks (void )
Quoted 2 lines · [email protected] wrote:
Artem,
Please find attached patch.
The comments make lines over 80 chars and are not needed, it is clear enough from the code what it does.
--
Jon Povey
[email protected]
Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB .
The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network
Quoted 2 lines · David Lambert
Artem,
Please find attached patch.
Thank you, but you made pretty good job to prevent me from applying it! :-)
Quoted 6 lines
Index:
mtd_speedtest.c
===================================================================
RCS
file:/home/cvsroot/ECMB/src/snapgear/linux-2.6.30.1.x/drivers/mtd/tests/mtd_speedtest.c,vretrieving revision 1.1.1.1
diff -u -r1.1.1.1mtd_speedtest.c
This means git am won't work... neither patch -p1 ...
Also, not author name (From:), not commit message, not Signed-off-by...
Quoted 7 lines
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 renamed from mtd_speedtest.c 10 Aug 2009 19:42:00 -0000 1.1.1.1 +0
-1@@ -281,13 +281,14 @@ static long calc_speed(void) { - long ms, k, speed;
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 line 288
Quoted 10 lines
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 renamed from mtd_speedtest.c 10 Aug 2009 19:42:00 -0000 1.1.1.1 +4
-5+ uint64_t k; + long ms; - ms = (finish.tv_sec - start.tv_sec) * 1000 + - (finish.tv_usec - start.tv_usec) / 1000; - k = goodebcnt * mtd->erasesize / 1024; - speed = (k * 1000) / ms; - return speed; + ms = (finish.tv_sec - start.tv_sec) * 1000 + /* Time in milli-seconds from start to ...*/ + (finish.tv_usec - start.tv_usec) / 1000; /* finish */
This would not pass scripts/checkpatch.pl. Please, kill the comments. Also, I you use spaces instead of tabs...
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 line 290
Quoted 2 lines
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 renamed from mtd_speedtest.c 10 Aug 2009 19:42:00 -0000 1.1.1.1 +2
-0+ k = (goodebcnt * (mtd->erasesize / 1024) * 1000); /* Number of kBytes transferred * 1000 */ + do_div(k, ms); /* k now contains number of kBytes/second */
The old code had a check against ms == 0, you removed it, why?
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 line 291
Quoted 1 line
mtd_speedtest.c 4 Mar 2011 17:51:23 -0000 renamed from mtd_speedtest.c 10 Aug 2009 19:42:00 -0000 1.1.1.1 +1
-0+ return k;
Anyway, since I anyway spent 20 minutes with this patch, here is what I ended up. I've pushed it to my l2 tree. If I made a mistake or you are unhappy about it, please, send your *properly formatted* version instead.
Thanks!
Quoted 1 line
From
008cfa97a772a83407a7e2657c0c5bfe36c7fc7fMon Sep 17 00:00:00 2001
From: David Lambert <[email protected]>
Date: Mon, 7 Mar 2011 12:00:46 +0200
Subject: [PATCH] mtd: speedtest: fix integer overflow
32-bit integers used in 'calc_speed()' may overflow and lead to incorrect results. Use 64-bit integers instead.
--- drivers/mtd/tests/mtd_speedtest.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-)
drivers/mtd/tests/mtd_speedtest.c +7 -7
@@ -314,16 +314,16 @@ static inline void stop_timing(void)static long calc_speed (void ) { -long ms, k, speed; +uint64_t k; +long ms; ms = (finish.tv_sec - start.tv_sec) *1000 + (finish.tv_usec - start.tv_usec) /1000 ; - k = goodebcnt * mtd->erasesize /1024 ; -if (ms) - speed = (k *1000 ) / ms; -else - speed =0 ; -return speed; +if (ms ==0 ) +return 0 ; + k = goodebcnt * (mtd->erasesize /1024 ) *1000 ; +do_div (k, ms); +return k; }static int scan_for_bad_eraseblocks (void )
Signature · 5 lines
1.7.2.3 -- Best Regards, Artem Bityutskiy (Артём Битюцкий)