2016-04-18 15:10:53 +08:00
# include "tests.h"
# include <sys/ipc.h>
# include <sys/sem.h>
2016-09-13 19:18:42 +03:00
# include <stdint.h>
2016-04-18 15:10:53 +08:00
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
2016-09-13 19:18:42 +03:00
# include "xlat.h"
# include "xlat/semop_flags.h"
2017-06-17 22:23:09 +00:00
union semun {
2016-04-18 15:10:53 +08:00
int val ;
struct semid_ds * buf ;
unsigned short * array ;
struct seminfo * __buf ;
} ;
static int id = - 1 ;
static void
cleanup ( void )
{
semctl ( id , 0 , IPC_RMID , 0 ) ;
id = - 1 ;
}
int
main ( void )
{
2016-09-13 19:18:42 +03:00
static const int bogus_semid = 0xfdb97531 ;
static void * const bogus_sops = ( void * ) - 1L ;
static const size_t bogus_nsops = ( size_t ) 0xdefaceddeadbeefULL ;
2017-04-23 23:10:57 +00:00
TAIL_ALLOC_OBJECT_CONST_PTR ( struct timespec , ts ) ;
2016-09-13 19:18:42 +03:00
int rc ;
2016-04-18 15:10:53 +08:00
id = semget ( IPC_PRIVATE , 1 , 0600 ) ;
if ( id < 0 )
perror_msg_and_skip ( " semget " ) ;
atexit ( cleanup ) ;
union semun sem_union = { . val = 0 } ;
if ( semctl ( id , 0 , SETVAL , sem_union ) = = - 1 )
perror_msg_and_skip ( " semctl " ) ;
2017-03-16 13:46:36 +00:00
TAIL_ALLOC_OBJECT_CONST_PTR ( struct sembuf , sem_b ) ;
TAIL_ALLOC_OBJECT_CONST_PTR ( struct sembuf , sem_b2 ) ;
2016-09-13 19:18:42 +03:00
rc = semop ( bogus_semid , NULL , bogus_nsops ) ;
printf ( " semop(%d, NULL, %u) = %s \n " ,
bogus_semid , ( unsigned ) bogus_nsops , sprintrc ( rc ) ) ;
rc = semop ( bogus_semid , bogus_sops , 1 ) ;
printf ( " semop(%d, %p, %u) = %s \n " ,
bogus_semid , bogus_sops , 1 , sprintrc ( rc ) ) ;
2016-04-18 15:10:53 +08:00
sem_b - > sem_num = 0 ;
sem_b - > sem_op = 1 ;
sem_b - > sem_flg = SEM_UNDO ;
2016-09-13 19:18:42 +03:00
sem_b2 - > sem_num = 0xface ;
sem_b2 - > sem_op = 0xf00d ;
sem_b2 - > sem_flg = 0xbeef ;
rc = semop ( bogus_semid , sem_b2 , 2 ) ;
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 01:15:19 +00:00
printf ( " semop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u) = %s \n " ,
2016-09-13 19:18:42 +03:00
bogus_semid , sem_b2 - > sem_num , sem_b2 - > sem_op ,
sem_b2 - > sem_flg & SEM_UNDO ? " SEM_UNDO| " : " " ,
sem_b2 - > sem_flg & IPC_NOWAIT ? " IPC_NOWAIT| " : " " ,
2018-06-02 18:25:56 +02:00
( short ) ( sem_b2 - > sem_flg & ~ ( SEM_UNDO | IPC_NOWAIT ) ) ,
2016-09-13 19:18:42 +03:00
sem_b2 + 1 , 2 , sprintrc ( rc ) ) ;
2016-04-18 15:10:53 +08:00
if ( semop ( id , sem_b , 1 ) )
perror_msg_and_skip ( " semop, 1 " ) ;
printf ( " semop(%d, [{0, 1, SEM_UNDO}], 1) = 0 \n " , id ) ;
sem_b - > sem_op = - 1 ;
if ( semop ( id , sem_b , 1 ) )
perror_msg_and_skip ( " semop, -1 " ) ;
printf ( " semop(%d, [{0, -1, SEM_UNDO}], 1) = 0 \n " , id ) ;
2016-09-13 19:18:42 +03:00
rc = semtimedop ( bogus_semid , NULL , bogus_nsops , NULL ) ;
printf ( " semtimedop(%d, NULL, %u, NULL) = %s \n " ,
bogus_semid , ( unsigned ) bogus_nsops , sprintrc ( rc ) ) ;
rc = semtimedop ( id , sem_b + 1 , 1 , ts + 1 ) ;
printf ( " semtimedop(%d, %p, 1, %p) = %s \n " ,
id , sem_b + 1 , ts + 1 , sprintrc ( rc ) ) ;
2017-04-23 23:10:57 +00:00
ts - > tv_sec = 1 ;
ts - > tv_nsec = 123456789 ;
2016-09-13 19:18:42 +03:00
rc = semtimedop ( bogus_semid , sem_b2 , 2 , ts ) ;
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 01:15:19 +00:00
printf ( " semtimedop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u "
Print microseconds/nanoseconds as non-negative
Negative micro/nanoseconds values are treated as invalid by kernel
anyway, and in one case (timespec_valid in include/linux/time.h)
it is even checked by conversion to unsigned long.
* print_timespec.c (timespec_fmt): Change tv_sec format to %lld and
tv_nsec format to %llu.
(print_timespec_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timespec): Likewise.
* print_timeval.c (timeval_fmt): Change tv_sec format to %lld and
tv_usec format to %llu.
(print_timeval_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timeval, print_timeval32_t, sprint_timeval32): Likewise.
* defs.h (TIMESPEC_TEXT_BUFSIZE): Update.
* tests/adjtimex.c (main): Change tv_sec printing format to %lld, cast
it to long long; change tv_usec printing format to %llu, process it with
zero_extend_signed_to_ull.
* tests/clock_nanosleep.c (main): Change tv_sec printing format to %lld,
cast it to long long; change tv_nsec printing format to %llu, process it
with zero_extend_signed_to_ull.
* tests/clock_xettime.c (main): Likewise.
* tests/futex.c (main): Likewise.
* tests/futimesat.c (print_tv): Likewise.
* tests/getrusage.c (invoke_print): Likewise.
* tests/mq_sendrecv.c (do_send, do_recv, main): Likewise.
* tests/nanosleep.c (main): Likewise.
* tests/pselect6.c (main): Likewise.
* tests/restart_syscall.c (main): Likewise.
* tests/rt_sigtimedwait.c (iterate, main): Likewise.
* tests/sched_rr_get_interval.c (main): Likewise.
* tests/semop.c (main): Likewise.
* tests/timer_xettime.c (main): Likewise.
* tests/timerfd_xettime.c (main): Likewise.
* tests/waitid.c (main): Likewise.
* tests/xetitimer.c (main): Likewise.
* tests/xettimeofday.c (main): Likewise.
* tests/xselect.c (main): Likewise.
* tests/xutimes.c (print_tv): Likewise.
* tests/wait4.c (sprint_rusage): Likewise.
* tests/waitid.c (sprint_rusage): Likewise.
* tests/utimensat.c (print_ts): Likewise.
(main): Add check for higher bits of tv_sec/tv_nsec.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-23 05:57:03 +02:00
" , {tv_sec=%lld, tv_nsec=%llu}) = %s \n " ,
2016-09-13 19:18:42 +03:00
bogus_semid , sem_b2 - > sem_num , sem_b2 - > sem_op ,
sem_b2 - > sem_flg & SEM_UNDO ? " SEM_UNDO| " : " " ,
sem_b2 - > sem_flg & IPC_NOWAIT ? " IPC_NOWAIT| " : " " ,
2018-06-02 18:25:56 +02:00
( short ) ( sem_b2 - > sem_flg & ~ ( SEM_UNDO | IPC_NOWAIT ) ) ,
2016-09-13 19:18:42 +03:00
sem_b2 + 1 , 2 ,
Print microseconds/nanoseconds as non-negative
Negative micro/nanoseconds values are treated as invalid by kernel
anyway, and in one case (timespec_valid in include/linux/time.h)
it is even checked by conversion to unsigned long.
* print_timespec.c (timespec_fmt): Change tv_sec format to %lld and
tv_nsec format to %llu.
(print_timespec_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timespec): Likewise.
* print_timeval.c (timeval_fmt): Change tv_sec format to %lld and
tv_usec format to %llu.
(print_timeval_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timeval, print_timeval32_t, sprint_timeval32): Likewise.
* defs.h (TIMESPEC_TEXT_BUFSIZE): Update.
* tests/adjtimex.c (main): Change tv_sec printing format to %lld, cast
it to long long; change tv_usec printing format to %llu, process it with
zero_extend_signed_to_ull.
* tests/clock_nanosleep.c (main): Change tv_sec printing format to %lld,
cast it to long long; change tv_nsec printing format to %llu, process it
with zero_extend_signed_to_ull.
* tests/clock_xettime.c (main): Likewise.
* tests/futex.c (main): Likewise.
* tests/futimesat.c (print_tv): Likewise.
* tests/getrusage.c (invoke_print): Likewise.
* tests/mq_sendrecv.c (do_send, do_recv, main): Likewise.
* tests/nanosleep.c (main): Likewise.
* tests/pselect6.c (main): Likewise.
* tests/restart_syscall.c (main): Likewise.
* tests/rt_sigtimedwait.c (iterate, main): Likewise.
* tests/sched_rr_get_interval.c (main): Likewise.
* tests/semop.c (main): Likewise.
* tests/timer_xettime.c (main): Likewise.
* tests/timerfd_xettime.c (main): Likewise.
* tests/waitid.c (main): Likewise.
* tests/xetitimer.c (main): Likewise.
* tests/xettimeofday.c (main): Likewise.
* tests/xselect.c (main): Likewise.
* tests/xutimes.c (print_tv): Likewise.
* tests/wait4.c (sprint_rusage): Likewise.
* tests/waitid.c (sprint_rusage): Likewise.
* tests/utimensat.c (print_ts): Likewise.
(main): Add check for higher bits of tv_sec/tv_nsec.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-23 05:57:03 +02:00
( long long ) ts - > tv_sec , zero_extend_signed_to_ull ( ts - > tv_nsec ) ,
2016-09-13 19:18:42 +03:00
sprintrc ( rc ) ) ;
sem_b - > sem_op = 1 ;
if ( semtimedop ( id , sem_b , 1 , NULL ) )
perror_msg_and_skip ( " semtimedop, 1 " ) ;
printf ( " semtimedop(%d, [{0, 1, SEM_UNDO}], 1, NULL) = 0 \n " , id ) ;
sem_b - > sem_op = - 1 ;
if ( semtimedop ( id , sem_b , 1 , ts ) )
perror_msg_and_skip ( " semtimedop, -1 " ) ;
Print microseconds/nanoseconds as non-negative
Negative micro/nanoseconds values are treated as invalid by kernel
anyway, and in one case (timespec_valid in include/linux/time.h)
it is even checked by conversion to unsigned long.
* print_timespec.c (timespec_fmt): Change tv_sec format to %lld and
tv_nsec format to %llu.
(print_timespec_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timespec): Likewise.
* print_timeval.c (timeval_fmt): Change tv_sec format to %lld and
tv_usec format to %llu.
(print_timeval_t): Cast tv_sec to long long and process tv_nsec with
zero_extend_signed_to_ull.
(sprint_timeval, print_timeval32_t, sprint_timeval32): Likewise.
* defs.h (TIMESPEC_TEXT_BUFSIZE): Update.
* tests/adjtimex.c (main): Change tv_sec printing format to %lld, cast
it to long long; change tv_usec printing format to %llu, process it with
zero_extend_signed_to_ull.
* tests/clock_nanosleep.c (main): Change tv_sec printing format to %lld,
cast it to long long; change tv_nsec printing format to %llu, process it
with zero_extend_signed_to_ull.
* tests/clock_xettime.c (main): Likewise.
* tests/futex.c (main): Likewise.
* tests/futimesat.c (print_tv): Likewise.
* tests/getrusage.c (invoke_print): Likewise.
* tests/mq_sendrecv.c (do_send, do_recv, main): Likewise.
* tests/nanosleep.c (main): Likewise.
* tests/pselect6.c (main): Likewise.
* tests/restart_syscall.c (main): Likewise.
* tests/rt_sigtimedwait.c (iterate, main): Likewise.
* tests/sched_rr_get_interval.c (main): Likewise.
* tests/semop.c (main): Likewise.
* tests/timer_xettime.c (main): Likewise.
* tests/timerfd_xettime.c (main): Likewise.
* tests/waitid.c (main): Likewise.
* tests/xetitimer.c (main): Likewise.
* tests/xettimeofday.c (main): Likewise.
* tests/xselect.c (main): Likewise.
* tests/xutimes.c (print_tv): Likewise.
* tests/wait4.c (sprint_rusage): Likewise.
* tests/waitid.c (sprint_rusage): Likewise.
* tests/utimensat.c (print_ts): Likewise.
(main): Add check for higher bits of tv_sec/tv_nsec.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-23 05:57:03 +02:00
printf ( " semtimedop(%d, [{0, -1, SEM_UNDO}], 1 "
" , {tv_sec=%lld, tv_nsec=%llu}) = 0 \n " , id ,
( long long ) ts - > tv_sec , zero_extend_signed_to_ull ( ts - > tv_nsec ) ) ;
2016-09-13 19:18:42 +03:00
2017-04-23 23:10:57 +00:00
sem_b - > sem_op = 1 ;
ts - > tv_sec = 0xdeadbeefU ;
ts - > tv_nsec = 0xfacefeedU ;
rc = semtimedop ( id , sem_b , 1 , ts ) ;
printf ( " semtimedop(%d, [{0, 1, SEM_UNDO}], 1 "
" , {tv_sec=%lld, tv_nsec=%llu}) = %s \n " ,
id , ( long long ) ts - > tv_sec ,
zero_extend_signed_to_ull ( ts - > tv_nsec ) , sprintrc ( rc ) ) ;
sem_b - > sem_op = - 1 ;
ts - > tv_sec = ( time_t ) 0xcafef00ddeadbeefLL ;
ts - > tv_nsec = ( long ) 0xbadc0dedfacefeedLL ;
rc = semtimedop ( id , sem_b , 1 , ts ) ;
printf ( " semtimedop(%d, [{0, -1, SEM_UNDO}], 1 "
" , {tv_sec=%lld, tv_nsec=%llu}) = %s \n " ,
id , ( long long ) ts - > tv_sec ,
zero_extend_signed_to_ull ( ts - > tv_nsec ) , sprintrc ( rc ) ) ;
2016-04-18 15:10:53 +08:00
puts ( " +++ exited with 0 +++ " ) ;
return 0 ;
}