selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
Subsystems (3)
John Stultz
maintainerPATCH 1/1 selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
So, the struct adjtimex freq field takes a signed value who's units are in shifted (<<16) parts-per-million.
Unfortunately for negative adjustments, the straightforward use of:
freq = ppm<<16
will trip undefined behavior warnings with clang:
valid-adjtimex.c:66:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-499<<16,
~~~~^
valid-adjtimex.c:67:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-450<<16,
~~~~^...
So fix our use of shifting negative values in the valid-adjtimex test case to use multiply by (1<<16) to avoid this.
The patch also aligns the values a bit to make it look nicer.
--- .../testing/selftests/timers/valid-adjtimex.c | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-)
tools/testing/selftests/timers/valid-adjtimex.c +35 -34
@@ -62,45 +62,46 @@ int clear_time_state(void)#define NUM_FREQ_OUTOFRANGE 4#define NUM_FREQ_INVALID 2 +#define SHIFTED_PPM (1 << 16)long valid_freq[NUM_FREQ_VALID ] = { --499 <<16 , --450 <<16 , --400 <<16 , --350 <<16 , --300 <<16 , --250 <<16 , --200 <<16 , --150 <<16 , --100 <<16 , --75 <<16 , --50 <<16 , --25 <<16 , --10 <<16 , --5 <<16 , --1 <<16 , +-499 *SHIFTED_PPM , +-450 *SHIFTED_PPM , +-400 *SHIFTED_PPM , +-350 *SHIFTED_PPM , +-300 *SHIFTED_PPM , +-250 *SHIFTED_PPM , +-200 *SHIFTED_PPM , +-150 *SHIFTED_PPM , +-100 *SHIFTED_PPM , +-75 *SHIFTED_PPM , +-50 *SHIFTED_PPM , +-25 *SHIFTED_PPM , +-10 *SHIFTED_PPM , +-5 *SHIFTED_PPM , +-1 *SHIFTED_PPM ,-1000 , -1 <<16 , -5 <<16 , -10 <<16 , -25 <<16 , -50 <<16 , -75 <<16 , -100 <<16 , -150 <<16 , -200 <<16 , -250 <<16 , -300 <<16 , -350 <<16 , -400 <<16 , -450 <<16 , -499 <<16 , +1 *SHIFTED_PPM , +5 *SHIFTED_PPM , +10 *SHIFTED_PPM , +25 *SHIFTED_PPM , +50 *SHIFTED_PPM , +75 *SHIFTED_PPM , +100 *SHIFTED_PPM , +150 *SHIFTED_PPM , +200 *SHIFTED_PPM , +250 *SHIFTED_PPM , +300 *SHIFTED_PPM , +350 *SHIFTED_PPM , +400 *SHIFTED_PPM , +450 *SHIFTED_PPM , +499 *SHIFTED_PPM , };long outofrange_freq[NUM_FREQ_OUTOFRANGE ] = { --1000 <<16 , --550 <<16 , -550 <<16 , -1000 <<16 , +-1000 *SHIFTED_PPM , +-550 *SHIFTED_PPM , +550 *SHIFTED_PPM , +1000 *SHIFTED_PPM , };#define LONG_MAX (~0UL>>1)
Signature · 1 line
2.44.0.478.gd926399ef9-goog
Quoted 21 lines · John Stultz
So, the struct adjtimex freq field takes a signed value who's units are in shifted (<<16) parts-per-million.
Unfortunately for negative adjustments, the straightforward use of:
freq = ppm<<16will trip undefined behavior warnings with clang:
valid-adjtimex.c:66:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-499<<16, ~~~~^ valid-adjtimex.c:67:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value] -450<<16, ~~~~^...
So fix our use of shifting negative values in the valid-adjtimex test case to use multiply by (1<<16) to avoid this.
The patch also aligns the values a bit to make it look nicer.
Quoted 14 lines
Cc Thomas Gleixner <[email protected]>Cc Stephen Boyd <[email protected]>Cc Anna-Maria Behnsen <[email protected]>Cc Frederic Weisbecker <[email protected]>Cc Shuah Khan <[email protected]>Cc Nathan Chancellor <[email protected]>Cc Nick Desaulniers <[email protected]>Cc Lee Jones <[email protected]>Cc Muhammad Usama Anjum <[email protected]>Reported-by Lee Jones <[email protected]>Reported-by Muhammad Usama Anjum <[email protected]>Signed-off-by John Stultz <[email protected]>
Quoted 89 lines
--- .../testing/selftests/timers/valid-adjtimex.c | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-)tools/testing/selftests/timers/valid-adjtimex.c +35
-34@@ -62,45 +62,46 @@ int clear_time_state(void)#define NUM_FREQ_OUTOFRANGE 4#define NUM_FREQ_INVALID 2 +#define SHIFTED_PPM (1 << 16)long valid_freq[NUM_FREQ_VALID ] = { --499 <<16 , --450 <<16 , --400 <<16 , --350 <<16 , --300 <<16 , --250 <<16 , --200 <<16 , --150 <<16 , --100 <<16 , --75 <<16 , --50 <<16 , --25 <<16 , --10 <<16 , --5 <<16 , --1 <<16 , +-499 *SHIFTED_PPM , +-450 *SHIFTED_PPM , +-400 *SHIFTED_PPM , +-350 *SHIFTED_PPM , +-300 *SHIFTED_PPM , +-250 *SHIFTED_PPM , +-200 *SHIFTED_PPM , +-150 *SHIFTED_PPM , +-100 *SHIFTED_PPM , +-75 *SHIFTED_PPM , +-50 *SHIFTED_PPM , +-25 *SHIFTED_PPM , +-10 *SHIFTED_PPM , +-5 *SHIFTED_PPM , +-1 *SHIFTED_PPM ,-1000 , -1 <<16 , -5 <<16 , -10 <<16 , -25 <<16 , -50 <<16 , -75 <<16 , -100 <<16 , -150 <<16 , -200 <<16 , -250 <<16 , -300 <<16 , -350 <<16 , -400 <<16 , -450 <<16 , -499 <<16 , +1 *SHIFTED_PPM , +5 *SHIFTED_PPM , +10 *SHIFTED_PPM , +25 *SHIFTED_PPM , +50 *SHIFTED_PPM , +75 *SHIFTED_PPM , +100 *SHIFTED_PPM , +150 *SHIFTED_PPM , +200 *SHIFTED_PPM , +250 *SHIFTED_PPM , +300 *SHIFTED_PPM , +350 *SHIFTED_PPM , +400 *SHIFTED_PPM , +450 *SHIFTED_PPM , +499 *SHIFTED_PPM , };long outofrange_freq[NUM_FREQ_OUTOFRANGE ] = { --1000 <<16 , --550 <<16 , -550 <<16 , -1000 <<16 , +-1000 *SHIFTED_PPM , +-550 *SHIFTED_PPM , +550 *SHIFTED_PPM , +1000 *SHIFTED_PPM , };#define LONG_MAX (~0UL>>1)
Signature · 2 lines
BR, Muhammad Usama Anjum
The following commit has been merged into the timers/urgent branch of tip:
The following commit has been merged into the timers/urgent branch of tip:
Commit-ID: 076361362122a6d8a4c45f172ced5576b2d4a50d Gitweb: https://git.kernel.org/tip/076361362122a6d8a4c45f172ced5576b2d4a50d Author: John Stultz <[email protected]> AuthorDate: Tue, 09 Apr 2024 13:22:12 -07:00 Committer: Thomas Gleixner <[email protected]> CommitterDate: Wed, 10 Apr 2024 22:07:42 +02:00
selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
The struct adjtimex freq field takes a signed value who's units are in shifted (<<16) parts-per-million.
Unfortunately for negative adjustments, the straightforward use of:
freq = ppm << 16 trips undefined behavior warnings with clang:
valid-adjtimex.c:66:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-499<<16,
~~~~^
valid-adjtimex.c:67:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-450<<16,
~~~~^..
Fix it by using a multiply by (1 << 16) instead of shifting negative values in the valid-adjtimex test case. Align the values for better readability.
--- tools/testing/selftests/timers/valid-adjtimex.c | 73 +++++++--------- 1 file changed, 36 insertions(+), 37 deletions(-)
tools/testing/selftests/timers/valid-adjtimex.c +36 -37
@@ -21,9 +21,6 @@* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - - -#include <stdio.h> #include <stdlib.h> #include <time.h>
@@ -62,45 +59,47 @@ int clear_time_state(void)#define NUM_FREQ_OUTOFRANGE 4#define NUM_FREQ_INVALID 2 +#define SHIFTED_PPM (1 << 16) +long valid_freq[NUM_FREQ_VALID ] = { --499 <<16 , --450 <<16 , --400 <<16 , --350 <<16 , --300 <<16 , --250 <<16 , --200 <<16 , --150 <<16 , --100 <<16 , --75 <<16 , --50 <<16 , --25 <<16 , --10 <<16 , --5 <<16 , --1 <<16 , +-499 *SHIFTED_PPM , +-450 *SHIFTED_PPM , +-400 *SHIFTED_PPM , +-350 *SHIFTED_PPM , +-300 *SHIFTED_PPM , +-250 *SHIFTED_PPM , +-200 *SHIFTED_PPM , +-150 *SHIFTED_PPM , +-100 *SHIFTED_PPM , +-75 *SHIFTED_PPM , +-50 *SHIFTED_PPM , +-25 *SHIFTED_PPM , +-10 *SHIFTED_PPM , +-5 *SHIFTED_PPM , +-1 *SHIFTED_PPM ,-1000 , -1 <<16 , -5 <<16 , -10 <<16 , -25 <<16 , -50 <<16 , -75 <<16 , -100 <<16 , -150 <<16 , -200 <<16 , -250 <<16 , -300 <<16 , -350 <<16 , -400 <<16 , -450 <<16 , -499 <<16 , +1 *SHIFTED_PPM , +5 *SHIFTED_PPM , +10 *SHIFTED_PPM , +25 *SHIFTED_PPM , +50 *SHIFTED_PPM , +75 *SHIFTED_PPM , +100 *SHIFTED_PPM , +150 *SHIFTED_PPM , +200 *SHIFTED_PPM , +250 *SHIFTED_PPM , +300 *SHIFTED_PPM , +350 *SHIFTED_PPM , +400 *SHIFTED_PPM , +450 *SHIFTED_PPM , +499 *SHIFTED_PPM , };long outofrange_freq[NUM_FREQ_OUTOFRANGE ] = { --1000 <<16 , --550 <<16 , -550 <<16 , -1000 <<16 , +-1000 *SHIFTED_PPM , +-550 *SHIFTED_PPM , +550 *SHIFTED_PPM , +1000 *SHIFTED_PPM , };#define LONG_MAX (~0UL>>1)
Shuah Khan
maintainerQuoted 35 lines · John Stultz
So, the struct adjtimex freq field takes a signed value who's units are in shifted (<<16) parts-per-million.
Unfortunately for negative adjustments, the straightforward use of:
freq = ppm<<16will trip undefined behavior warnings with clang:
valid-adjtimex.c:66:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value]
-499<<16, ~~~~^ valid-adjtimex.c:67:6: warning: shifting a negative signed value is undefined [-Wshift-negative-value] -450<<16, ~~~~^...
So fix our use of shifting negative values in the valid-adjtimex test case to use multiply by (1<<16) to avoid this.
The patch also aligns the values a bit to make it look nicer.
Cc Thomas Gleixner <[email protected]>Cc Stephen Boyd <[email protected]>Cc Anna-Maria Behnsen <[email protected]>Cc Frederic Weisbecker <[email protected]>Cc Shuah Khan <[email protected]>Cc Nathan Chancellor <[email protected]>Cc Nick Desaulniers <[email protected]>Cc Lee Jones <[email protected]>Cc Muhammad Usama Anjum <[email protected]>Reported-by Lee Jones <[email protected]>Reported-by Muhammad Usama Anjum <[email protected]>Signed-off-by John Stultz <[email protected]>
Quoted 1 line
---
Applied to linux-kselftest next for Linux6.10-rc1.
thanks,
-- Shuah
Shuah!
Quoted 2 lines · Shuah Khan
Applied to linux-kselftest next for Linux6.10-rc1.
I took this already through my tree as I have more timer selftest related stuff pending and coming up soon along with actual kernel changes.
Thanks,
tglx