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:
Albert ARIBAUD (3ADEV) 2016-06-29 09:17:50 +02:00
parent 0f11007c19
commit 303622f01c
7 changed files with 138 additions and 22 deletions

View File

@ -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?
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
from libc or from the Linux kernel which are known not to be Y2038-proof.
because it is Y2038-unsafe. This may be because it uses types or functions from
GNU libc or from the Linux kernel which are known not to be Y2038-proof.
3. How does the Y2038 cppcheck addon work?
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-
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
correctly configured Y2038-proof time support.
@ -85,10 +85,10 @@ The Y2038 cppcheck performs the following checks:
which defaults to 32-bit time support.
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:
Warning: <symbol> might be Y2038-sensitive
Warning: <symbol> is Y2038-unsafe
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.
@ -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-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-3-no-use-time-bits.c:13]: (warning) timespec might be Y2038-sensitive
[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:13]: (warning) timespec is Y2038-unsafe
[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
pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also

View File

@ -8,4 +8,24 @@
#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 */

View File

@ -11,8 +11,8 @@
int main(int argc, char **argv)
{
clockid_t my_clk_id;
clockid_t my_clk_id = CLOCK_REALTIME;
struct timespec *my_tp;
return clock_gettime( my_clk_id, &my_tp);
return clock_gettime(my_clk_id, &my_tp);
}

View File

@ -9,8 +9,8 @@
int main(int argc, char **argv)
{
clockid_t my_clk_id;
clockid_t my_clk_id = CLOCK_REALTIME;
struct timespec *my_tp;
return clock_gettime( my_clk_id, &my_tp);
return clock_gettime(my_clk_id, &my_tp);
}

View File

@ -9,8 +9,8 @@
int main(int argc, char **argv)
{
clockid_t my_clk_id;
clockid_t my_clk_id = CLOCK_REALTIME;
struct timespec *my_tp;
return clock_gettime( my_clk_id, &my_tp);
return clock_gettime(my_clk_id, &my_tp);
}

View File

@ -8,8 +8,8 @@
int main(int argc, char **argv)
{
clockid_t my_clk_id;
clockid_t my_clk_id = CLOCK_REALTIME;
struct timespec *my_tp;
return clock_gettime( my_clk_id, &my_tp);
return clock_gettime(my_clk_id, &my_tp);
}

View File

@ -6,7 +6,7 @@
#
# 1. _TIME_BITS being defined to something else than 64 bits
# 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:
# $ 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)
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
# and functions) which would be affected by the Y2038 bug.
id_Y2038 = [
'time_t',
# Y2038-unsafe types by definition
'time_t'
# Types using Y2038-unsafe types
'lastlog',
'msqid_ds',
'semid_ds',
'timeb',
'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
@ -182,7 +278,7 @@ for dumpfile in dumpfiles:
if not any(lower <= int(token.linenr) <= upper
for (lower, upper) in safe_ranges):
reportTokDiag(args.template, cfg, token, 'warning',
token.str + ' might be Y2038-sensitive')
token.str + ' is Y2038-unsafe')
token = token.next
printDiagnostics()