]>
Commit | Line | Data |
---|---|---|
9b50f08f GKH |
1 | From 5a581b367b5df0531265311fc681c2abd377e5e6 Mon Sep 17 00:00:00 2001 |
2 | From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | |
3 | Date: Sat, 27 Jul 2013 03:53:54 -0700 | |
4 | Subject: jiffies: Avoid undefined behavior from signed overflow | |
5 | ||
6 | From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> | |
7 | ||
8 | commit 5a581b367b5df0531265311fc681c2abd377e5e6 upstream. | |
9 | ||
10 | According to the C standard 3.4.3p3, overflow of a signed integer results | |
11 | in undefined behavior. This commit therefore changes the definitions | |
12 | of time_after(), time_after_eq(), time_after64(), and time_after_eq64() | |
13 | to avoid this undefined behavior. The trick is that the subtraction | |
14 | is done using unsigned arithmetic, which according to 6.2.5p9 cannot | |
15 | overflow because it is defined as modulo arithmetic. This has the added | |
16 | (though admittedly quite small) benefit of shortening four lines of code | |
17 | by four characters each. | |
18 | ||
19 | Note that the C standard considers the cast from unsigned to | |
20 | signed to be implementation-defined, see 6.3.1.3p3. However, on a | |
21 | two's-complement system, an implementation that defines anything other | |
22 | than a reinterpretation of the bits is free to come to me, and I will be | |
23 | happy to act as a witness for its being committed to an insane asylum. | |
24 | (Although I have nothing against saturating arithmetic or signals in some | |
25 | cases, these things really should not be the default when compiling an | |
26 | operating-system kernel.) | |
27 | ||
28 | Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | |
29 | Cc: John Stultz <john.stultz@linaro.org> | |
30 | Cc: "David S. Miller" <davem@davemloft.net> | |
31 | Cc: Arnd Bergmann <arnd@arndb.de> | |
32 | Cc: Ingo Molnar <mingo@kernel.org> | |
33 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
34 | Cc: Eric Dumazet <eric.dumazet@gmail.com> | |
35 | Cc: Kevin Easton <kevin@guarana.org> | |
36 | [ paulmck: Included time_after64() and time_after_eq64(), as suggested | |
37 | by Eric Dumazet, also fixed commit message.] | |
38 | Reviewed-by: Josh Triplett <josh@joshtriplett.org> | |
39 | Ruchi Kandoi <kandoiruchi@google.com> | |
40 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
41 | ||
42 | --- | |
43 | include/linux/jiffies.h | 8 ++++---- | |
44 | 1 file changed, 4 insertions(+), 4 deletions(-) | |
45 | ||
46 | --- a/include/linux/jiffies.h | |
47 | +++ b/include/linux/jiffies.h | |
48 | @@ -101,13 +101,13 @@ static inline u64 get_jiffies_64(void) | |
49 | #define time_after(a,b) \ | |
50 | (typecheck(unsigned long, a) && \ | |
51 | typecheck(unsigned long, b) && \ | |
52 | - ((long)(b) - (long)(a) < 0)) | |
53 | + ((long)((b) - (a)) < 0)) | |
54 | #define time_before(a,b) time_after(b,a) | |
55 | ||
56 | #define time_after_eq(a,b) \ | |
57 | (typecheck(unsigned long, a) && \ | |
58 | typecheck(unsigned long, b) && \ | |
59 | - ((long)(a) - (long)(b) >= 0)) | |
60 | + ((long)((a) - (b)) >= 0)) | |
61 | #define time_before_eq(a,b) time_after_eq(b,a) | |
62 | ||
63 | /* | |
64 | @@ -130,13 +130,13 @@ static inline u64 get_jiffies_64(void) | |
65 | #define time_after64(a,b) \ | |
66 | (typecheck(__u64, a) && \ | |
67 | typecheck(__u64, b) && \ | |
68 | - ((__s64)(b) - (__s64)(a) < 0)) | |
69 | + ((__s64)((b) - (a)) < 0)) | |
70 | #define time_before64(a,b) time_after64(b,a) | |
71 | ||
72 | #define time_after_eq64(a,b) \ | |
73 | (typecheck(__u64, a) && \ | |
74 | typecheck(__u64, b) && \ | |
75 | - ((__s64)(a) - (__s64)(b) >= 0)) | |
76 | + ((__s64)((a) - (b)) >= 0)) | |
77 | #define time_before_eq64(a,b) time_after_eq64(b,a) | |
78 | ||
79 | /* |