aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-09 01:28:47 -0400
committerArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-09 01:28:47 -0400
commit0ba7a3ba6608de6e0c0bfe3009a63d7e0b7ab0ce (patch)
treedb5b9c5a778e0cbc08bcbf7f5b25174499b13a1d /net
parente104411b82f5c4d19752c335492036abdbf5880d (diff)
[CCID3] Avoid unsigned integer overflows in usecs_div
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/ccids/ccid3.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 7bf3b3a91e97..ae0500c79d07 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -43,12 +43,22 @@
43#include "ccid3.h" 43#include "ccid3.h"
44 44
45/* 45/*
46 * Reason for maths with 10 here is to avoid 32 bit overflow when a is big. 46 * Reason for maths here is to avoid 32 bit overflow when a is big.
47 * With this we get close to the limit.
47 */ 48 */
48static inline u32 usecs_div(const u32 a, const u32 b) 49static inline u32 usecs_div(const u32 a, const u32 b)
49{ 50{
50 const u32 tmp = a * (USEC_PER_SEC / 10); 51 const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 :
51 return b > 20 ? tmp / (b / 10) : tmp; 52 a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 :
53 a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 :
54 a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 :
55 a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 :
56 a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 :
57 a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
58 a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
59 100000;
60 const u32 tmp = a * (USEC_PER_SEC / div);
61 return (b >= 2 * div) ? tmp / (b / div) : tmp;
52} 62}
53 63
54static int ccid3_debug; 64static int ccid3_debug;