Update Y2038 addon
- standardize on kernel's 'Y2038-[un]safe' - expand Y2038-unsafe symbols list - make y2038 addon C test more complete
This commit is contained in:
parent
0f11007c19
commit
303622f01c
|
@ -39,14 +39,14 @@ There is Y2038-proofing work in progress on the Linux and GNU glibc front.
|
||||||
2. What is the Y2038 ccpcheck addon?
|
2. What is the Y2038 ccpcheck addon?
|
||||||
|
|
||||||
The Y2038 cppcheck addon is a tool to help detect code which might need fixing
|
The Y2038 cppcheck addon is a tool to help detect code which might need fixing
|
||||||
because it is Y2038-sensitive. This may be because it uses types or functions
|
because it is Y2038-unsafe. This may be because it uses types or functions from
|
||||||
from libc or from the Linux kernel which are known not to be Y2038-proof.
|
GNU libc or from the Linux kernel which are known not to be Y2038-proof.
|
||||||
|
|
||||||
3. How does the Y2038 cppcheck addon work?
|
3. How does the Y2038 cppcheck addon work?
|
||||||
|
|
||||||
The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code
|
The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code
|
||||||
files and looks for the names of types or functions which are known to be Y2038-
|
files and looks for the names of types or functions which are known to be Y2038-
|
||||||
sensitive, and emits diagnostics whenever it finds one.
|
unsafe, and emits diagnostics whenever it finds one.
|
||||||
|
|
||||||
Of course, this is of little use if your code uses a Y2038-proof glibc and
|
Of course, this is of little use if your code uses a Y2038-proof glibc and
|
||||||
correctly configured Y2038-proof time support.
|
correctly configured Y2038-proof time support.
|
||||||
|
@ -85,10 +85,10 @@ The Y2038 cppcheck performs the following checks:
|
||||||
which defaults to 32-bit time support.
|
which defaults to 32-bit time support.
|
||||||
|
|
||||||
3. Upon meeting a symbol (type or function) which is known to be Y2038-
|
3. Upon meeting a symbol (type or function) which is known to be Y2038-
|
||||||
sensitive, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly
|
unsafe, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly
|
||||||
defined, this warning diagnostic is emitted:
|
defined, this warning diagnostic is emitted:
|
||||||
|
|
||||||
Warning: <symbol> might be Y2038-sensitive
|
Warning: <symbol> is Y2038-unsafe
|
||||||
|
|
||||||
This reflects the fact that the user code is referring to a symbol
|
This reflects the fact that the user code is referring to a symbol
|
||||||
which, when glibc defaults to 32-bit time support, might fail Y2038.
|
which, when glibc defaults to 32-bit time support, might fail Y2038.
|
||||||
|
@ -143,8 +143,8 @@ Checking addons/y2038/test/y2038-test-4-good.c.dump, config ""...
|
||||||
[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here
|
[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here
|
||||||
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
|
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
|
||||||
[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here
|
[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here
|
||||||
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec might be Y2038-sensitive
|
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec is Y2038-unsafe
|
||||||
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime might be Y2038-sensitive
|
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime is Y2038-unsafe
|
||||||
|
|
||||||
Note: y2038.py recognizes option --template as cppcheck does, including
|
Note: y2038.py recognizes option --template as cppcheck does, including
|
||||||
pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also
|
pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also
|
||||||
|
|
|
@ -8,4 +8,24 @@
|
||||||
|
|
||||||
#define _USE_TIME_BITS64
|
#define _USE_TIME_BITS64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declare just enough for clock_gettime
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int clockid_t;
|
||||||
|
|
||||||
|
typedef int __time_t;
|
||||||
|
|
||||||
|
typedef long int __syscall_slong_t;
|
||||||
|
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
__time_t tv_sec; /* Seconds. */
|
||||||
|
__syscall_slong_t tv_nsec; /* Nanoseconds. */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int clock_gettime(clockid_t clk_id, struct timespec *tp);
|
||||||
|
|
||||||
|
#define CLOCK_REALTIME 0
|
||||||
|
|
||||||
#endif /* INC2038 */
|
#endif /* INC2038 */
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
clockid_t my_clk_id;
|
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||||
struct timespec *my_tp;
|
struct timespec *my_tp;
|
||||||
|
|
||||||
return clock_gettime( my_clk_id, &my_tp);
|
return clock_gettime(my_clk_id, &my_tp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
clockid_t my_clk_id;
|
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||||
struct timespec *my_tp;
|
struct timespec *my_tp;
|
||||||
|
|
||||||
return clock_gettime( my_clk_id, &my_tp);
|
return clock_gettime(my_clk_id, &my_tp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
clockid_t my_clk_id;
|
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||||
struct timespec *my_tp;
|
struct timespec *my_tp;
|
||||||
|
|
||||||
return clock_gettime( my_clk_id, &my_tp);
|
return clock_gettime(my_clk_id, &my_tp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
clockid_t my_clk_id;
|
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||||
struct timespec *my_tp;
|
struct timespec *my_tp;
|
||||||
|
|
||||||
return clock_gettime( my_clk_id, &my_tp);
|
return clock_gettime(my_clk_id, &my_tp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# 1. _TIME_BITS being defined to something else than 64 bits
|
# 1. _TIME_BITS being defined to something else than 64 bits
|
||||||
# 2. _USE_TIME_BITS64 being defined when _TIME_BITS is not
|
# 2. _USE_TIME_BITS64 being defined when _TIME_BITS is not
|
||||||
# 3. Any Y2038-sensitive symbol when _USE_TIME_BITS64 is not defined.
|
# 3. Any Y2038-unsafe symbol when _USE_TIME_BITS64 is not defined.
|
||||||
#
|
#
|
||||||
# Example usage:
|
# Example usage:
|
||||||
# $ cppcheck --dump path-to-src/
|
# $ cppcheck --dump path-to-src/
|
||||||
|
@ -77,17 +77,113 @@ re_define_use_time_bits64 = re.compile(r'^\s*#\s*define\s+_USE_TIME_BITS64\s*$')
|
||||||
# test for '#undef _USE_TIME_BITS64' (if it ever happens)
|
# test for '#undef _USE_TIME_BITS64' (if it ever happens)
|
||||||
re_undef_use_time_bits64 = re.compile(r'^\s*#\s*undef\s+_USE_TIME_BITS64\s*$')
|
re_undef_use_time_bits64 = re.compile(r'^\s*#\s*undef\s+_USE_TIME_BITS64\s*$')
|
||||||
|
|
||||||
#------------------------------------
|
#---------------------------------
|
||||||
# List of Y2038-sensitive identifiers
|
# List of Y2038-unsafe identifiers
|
||||||
#------------------------------------
|
#---------------------------------
|
||||||
|
|
||||||
# This is WIP. Eventually it should contain all identifiers (types
|
# This is WIP. Eventually it should contain all identifiers (types
|
||||||
# and functions) which would be affected by the Y2038 bug.
|
# and functions) which would be affected by the Y2038 bug.
|
||||||
|
|
||||||
id_Y2038 = [
|
id_Y2038 = [
|
||||||
'time_t',
|
# Y2038-unsafe types by definition
|
||||||
|
'time_t'
|
||||||
|
# Types using Y2038-unsafe types
|
||||||
|
'lastlog',
|
||||||
|
'msqid_ds',
|
||||||
|
'semid_ds',
|
||||||
|
'timeb',
|
||||||
'timespec',
|
'timespec',
|
||||||
'clock_gettime'
|
'timeval',
|
||||||
|
'utimbuf',
|
||||||
|
'itimerspec',
|
||||||
|
'stat',
|
||||||
|
'clnt_ops',
|
||||||
|
'elf_prstatus',
|
||||||
|
'itimerval',
|
||||||
|
'ntptimeval',
|
||||||
|
'rusage',
|
||||||
|
'timex',
|
||||||
|
'utmp',
|
||||||
|
'utmpx',
|
||||||
|
# APIs using 2038-unsafe types
|
||||||
|
'ctime',
|
||||||
|
'ctime_r',
|
||||||
|
'difftime',
|
||||||
|
'gmtime',
|
||||||
|
'gmtime_r',
|
||||||
|
'localtime',
|
||||||
|
'localtime_r',
|
||||||
|
'mktime',
|
||||||
|
'stime',
|
||||||
|
'timegm',
|
||||||
|
'timelocal',
|
||||||
|
'time',
|
||||||
|
'msgctl',
|
||||||
|
'ftime',
|
||||||
|
'aio_suspend',
|
||||||
|
'clock_getres',
|
||||||
|
'clock_gettime',
|
||||||
|
'clock_nanosleep',
|
||||||
|
'clock_settime',
|
||||||
|
'futimens',
|
||||||
|
'mq_timedreceive',
|
||||||
|
'mq_timedsend',
|
||||||
|
'nanosleep',
|
||||||
|
'pselect',
|
||||||
|
'pthread_cond_timedwait',
|
||||||
|
'pthread_mutex_timedlock',
|
||||||
|
'pthread_rwlock_timedrdlock',
|
||||||
|
'pthread_rwlock_timedwrlock',
|
||||||
|
'sched_rr_get_interval',
|
||||||
|
'sem_timedwait',
|
||||||
|
'sigtimedwait',
|
||||||
|
'timespec_get',
|
||||||
|
'utimensat',
|
||||||
|
'adjtime',
|
||||||
|
'pmap_rmtcall',
|
||||||
|
'clntudp_bufcreate',
|
||||||
|
'clntudp_create',
|
||||||
|
'futimes',
|
||||||
|
'gettimeofday',
|
||||||
|
'lutimes',
|
||||||
|
'select',
|
||||||
|
'settimeofday',
|
||||||
|
'utimes',
|
||||||
|
'utime',
|
||||||
|
'timerfd_gettime',
|
||||||
|
'timerfd_settime',
|
||||||
|
'timer_gettime',
|
||||||
|
'timer_settime',
|
||||||
|
'fstatat',
|
||||||
|
'fstat',
|
||||||
|
'__fxstatat',
|
||||||
|
'__fxstat',
|
||||||
|
'lstat',
|
||||||
|
'__lxstat',
|
||||||
|
'stat',
|
||||||
|
'__xstat',
|
||||||
|
'struct itimerval',
|
||||||
|
'setitimer',
|
||||||
|
'getitimer',
|
||||||
|
'ntp_gettime',
|
||||||
|
'getrusage',
|
||||||
|
'wait3',
|
||||||
|
'wait4',
|
||||||
|
'adjtimex',
|
||||||
|
'ntp_adjtime',
|
||||||
|
'getutent_r',
|
||||||
|
'getutent',
|
||||||
|
'getutid_r',
|
||||||
|
'getutid',
|
||||||
|
'getutline_r',
|
||||||
|
'getutline',
|
||||||
|
'login',
|
||||||
|
'pututline',
|
||||||
|
'updwtmp',
|
||||||
|
'getutxent',
|
||||||
|
'getutxid',
|
||||||
|
'getutxline',
|
||||||
|
'pututxline'
|
||||||
]
|
]
|
||||||
|
|
||||||
# return all files ending in .dump among or under the given paths
|
# return all files ending in .dump among or under the given paths
|
||||||
|
@ -182,7 +278,7 @@ for dumpfile in dumpfiles:
|
||||||
if not any(lower <= int(token.linenr) <= upper
|
if not any(lower <= int(token.linenr) <= upper
|
||||||
for (lower, upper) in safe_ranges):
|
for (lower, upper) in safe_ranges):
|
||||||
reportTokDiag(args.template, cfg, token, 'warning',
|
reportTokDiag(args.template, cfg, token, 'warning',
|
||||||
token.str + ' might be Y2038-sensitive')
|
token.str + ' is Y2038-unsafe')
|
||||||
token = token.next
|
token = token.next
|
||||||
|
|
||||||
printDiagnostics()
|
printDiagnostics()
|
||||||
|
|
Loading…
Reference in New Issue