diff options
author | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-09-09 01:28:47 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@mandriva.com> | 2005-09-09 01:28:47 -0400 |
commit | 0ba7a3ba6608de6e0c0bfe3009a63d7e0b7ab0ce (patch) | |
tree | db5b9c5a778e0cbc08bcbf7f5b25174499b13a1d /net/dccp | |
parent | e104411b82f5c4d19752c335492036abdbf5880d (diff) |
[CCID3] Avoid unsigned integer overflows in usecs_div
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 16 |
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 | */ |
48 | static inline u32 usecs_div(const u32 a, const u32 b) | 49 | static 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 | ||
54 | static int ccid3_debug; | 64 | static int ccid3_debug; |