2016-12-26 15:24:45 +03:00
/*
* Support for decoding of DM_ * ioctl commands .
*
* Copyright ( c ) 2016 Mikulas Patocka < mpatocka @ redhat . com >
* Copyright ( c ) 2016 Masatake Yamato < yamato @ redhat . com >
* Copyright ( c ) 2016 Dmitry V . Levin < ldv @ altlinux . org >
* Copyright ( c ) 2016 Eugene Syromyatnikov < evgsyr @ gmail . com >
2017-05-22 20:14:52 +03:00
* Copyright ( c ) 2016 - 2017 The strace developers .
2016-12-26 15:24:45 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2016-10-03 00:59:06 +03:00
# include "defs.h"
# ifdef HAVE_LINUX_DM_IOCTL_H
2017-07-11 03:20:54 +03:00
# include "print_fields.h"
2016-10-03 00:59:06 +03:00
# include <linux / dm-ioctl.h>
# include <linux / ioctl.h>
# if DM_VERSION_MAJOR == 4
/* Definitions for command which have been added later */
# ifndef DM_LIST_VERSIONS
# define DM_LIST_VERSIONS _IOWR(DM_IOCTL, 0xd, struct dm_ioctl)
# endif
# ifndef DM_TARGET_MSG
# define DM_TARGET_MSG _IOWR(DM_IOCTL, 0xe, struct dm_ioctl)
# endif
# ifndef DM_DEV_SET_GEOMETRY
# define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, 0xf, struct dm_ioctl)
# endif
static void
dm_decode_device ( const unsigned int code , const struct dm_ioctl * ioc )
{
switch ( code ) {
case DM_REMOVE_ALL :
case DM_LIST_DEVICES :
case DM_LIST_VERSIONS :
break ;
default :
2017-07-11 03:20:54 +03:00
if ( ioc - > dev )
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " , " , * ioc , dev ) ;
2017-07-11 03:20:54 +03:00
if ( ioc - > name [ 0 ] )
PRINT_FIELD_CSTRING ( " , " , * ioc , name ) ;
if ( ioc - > uuid [ 0 ] )
PRINT_FIELD_CSTRING ( " , " , * ioc , uuid ) ;
2016-10-03 00:59:06 +03:00
break ;
}
}
static void
dm_decode_values ( struct tcb * tcp , const unsigned int code ,
const struct dm_ioctl * ioc )
{
if ( entering ( tcp ) ) {
switch ( code ) {
case DM_TABLE_LOAD :
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " , " , * ioc , target_count ) ;
2016-10-03 00:59:06 +03:00
break ;
case DM_DEV_SUSPEND :
if ( ioc - > flags & DM_SUSPEND_FLAG )
break ;
/* Fall through */
case DM_DEV_RENAME :
case DM_DEV_REMOVE :
case DM_DEV_WAIT :
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " , " , * ioc , event_nr ) ;
2016-10-03 00:59:06 +03:00
break ;
}
} else if ( ! syserror ( tcp ) ) {
switch ( code ) {
case DM_DEV_CREATE :
case DM_DEV_RENAME :
case DM_DEV_SUSPEND :
case DM_DEV_STATUS :
case DM_DEV_WAIT :
case DM_TABLE_LOAD :
case DM_TABLE_CLEAR :
case DM_TABLE_DEPS :
case DM_TABLE_STATUS :
case DM_TARGET_MSG :
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " , " , * ioc , target_count ) ;
PRINT_FIELD_U ( " , " , * ioc , open_count ) ;
PRINT_FIELD_U ( " , " , * ioc , event_nr ) ;
2016-10-03 00:59:06 +03:00
break ;
}
}
}
# include "xlat/dm_flags.h"
static void
dm_decode_flags ( const struct dm_ioctl * ioc )
{
2017-07-14 03:08:09 +03:00
PRINT_FIELD_FLAGS ( " , " , * ioc , flags , dm_flags , " DM_??? " ) ;
2016-10-03 00:59:06 +03:00
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_dm_target_spec ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 06:03:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
static const uint32_t target_spec_size =
sizeof ( struct dm_target_spec ) ;
uint32_t i ;
uint32_t offset = ioc - > data_start ;
2017-04-24 22:14:41 +03:00
uint32_t offset_end = 0 ;
2016-10-03 00:59:06 +03:00
if ( abbrev ( tcp ) ) {
if ( ioc - > target_count )
tprints ( " , ... " ) ;
return ;
}
for ( i = 0 ; i < ioc - > target_count ; i + + ) {
2017-04-24 22:14:41 +03:00
tprints ( " , " ) ;
if ( i & & offset < = offset_end )
goto misplaced ;
2016-10-03 00:59:06 +03:00
offset_end = offset + target_spec_size ;
if ( offset_end < = offset | | offset_end > ioc - > data_size )
goto misplaced ;
if ( i > = max_strlen ) {
tprints ( " ... " ) ;
break ;
}
2017-04-24 22:14:41 +03:00
struct dm_target_spec s ;
2016-10-03 00:59:06 +03:00
if ( umove_or_printaddr ( tcp , addr + offset , & s ) )
break ;
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " { " , s , sector_start ) ;
PRINT_FIELD_U ( " , " , s , length ) ;
2016-10-03 00:59:06 +03:00
if ( exiting ( tcp ) )
2017-07-14 03:08:09 +03:00
PRINT_FIELD_D ( " , " , s , status ) ;
2016-10-03 00:59:06 +03:00
2017-07-11 03:20:54 +03:00
PRINT_FIELD_CSTRING ( " , " , s , target_type ) ;
2016-10-03 00:59:06 +03:00
tprints ( " , string= " ) ;
printstr_ex ( tcp , addr + offset_end , ioc - > data_size - offset_end ,
QUOTE_0_TERMINATED ) ;
2017-02-18 03:58:17 +03:00
tprints ( " } " ) ;
2016-10-03 00:59:06 +03:00
if ( entering ( tcp ) )
offset + = s . next ;
else
offset = ioc - > data_start + s . next ;
}
return ;
misplaced :
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced struct dm_target_spec " ) ;
2016-10-03 00:59:06 +03:00
}
bool
dm_print_dev ( struct tcb * tcp , void * dev_ptr , size_t dev_size , void * dummy )
{
uint64_t * dev = ( uint64_t * ) dev_ptr ;
2016-12-26 15:25:35 +03:00
print_dev_t ( * dev ) ;
2016-10-03 00:59:06 +03:00
return 1 ;
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_dm_target_deps ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 06:03:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
2017-04-24 22:14:41 +03:00
if ( ioc - > data_start = = ioc - > data_size )
return ;
tprints ( " , " ) ;
if ( abbrev ( tcp ) ) {
tprints ( " ... " ) ;
return ;
}
2016-10-03 00:59:06 +03:00
static const uint32_t target_deps_dev_offs =
offsetof ( struct dm_target_deps , dev ) ;
uint64_t dev_buf ;
struct dm_target_deps s ;
uint32_t offset = ioc - > data_start ;
uint32_t offset_end = offset + target_deps_dev_offs ;
uint32_t space ;
if ( offset_end < = offset | | offset_end > ioc - > data_size )
goto misplaced ;
if ( umove_or_printaddr ( tcp , addr + offset , & s ) )
return ;
space = ( ioc - > data_size - offset_end ) / sizeof ( dev_buf ) ;
if ( s . count > space )
goto misplaced ;
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " { " , s , count ) ;
2016-10-03 00:59:06 +03:00
2017-07-14 03:08:09 +03:00
tprints ( " , deps= " ) ;
2016-10-03 00:59:06 +03:00
print_array ( tcp , addr + offset_end , s . count , & dev_buf , sizeof ( dev_buf ) ,
umoven_or_printaddr , dm_print_dev , NULL ) ;
tprints ( " } " ) ;
return ;
misplaced :
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced struct dm_target_deps " ) ;
2016-10-03 00:59:06 +03:00
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_dm_name_list ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 06:03:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
static const uint32_t name_list_name_offs =
offsetof ( struct dm_name_list , name ) ;
struct dm_name_list s ;
uint32_t offset = ioc - > data_start ;
2017-04-24 22:14:41 +03:00
uint32_t offset_end = 0 ;
2016-10-03 00:59:06 +03:00
uint32_t count ;
2017-04-24 22:14:41 +03:00
if ( ioc - > data_start = = ioc - > data_size )
return ;
2016-10-03 00:59:06 +03:00
if ( abbrev ( tcp ) ) {
tprints ( " , ... " ) ;
return ;
}
for ( count = 0 ; ; count + + ) {
2017-04-24 22:14:41 +03:00
tprints ( " , " ) ;
if ( count & & offset < = offset_end )
goto misplaced ;
2016-10-03 00:59:06 +03:00
offset_end = offset + name_list_name_offs ;
if ( offset_end < = offset | | offset_end > ioc - > data_size )
goto misplaced ;
if ( count > = max_strlen ) {
tprints ( " ... " ) ;
break ;
}
if ( umove_or_printaddr ( tcp , addr + offset , & s ) )
break ;
2017-07-09 16:54:01 +03:00
PRINT_FIELD_DEV ( " { " , s , dev ) ;
tprints ( " , name= " ) ;
2016-10-03 00:59:06 +03:00
printstr_ex ( tcp , addr + offset_end , ioc - > data_size - offset_end ,
QUOTE_0_TERMINATED ) ;
tprints ( " } " ) ;
if ( ! s . next )
break ;
offset + = s . next ;
}
return ;
misplaced :
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced struct dm_name_list " ) ;
2016-10-03 00:59:06 +03:00
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_dm_target_versions ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 06:03:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
static const uint32_t target_vers_name_offs =
offsetof ( struct dm_target_versions , name ) ;
struct dm_target_versions s ;
uint32_t offset = ioc - > data_start ;
2017-04-24 22:14:41 +03:00
uint32_t offset_end = 0 ;
2016-10-03 00:59:06 +03:00
uint32_t count ;
2017-04-24 22:14:41 +03:00
if ( ioc - > data_start = = ioc - > data_size )
return ;
2016-10-03 00:59:06 +03:00
if ( abbrev ( tcp ) ) {
tprints ( " , ... " ) ;
return ;
}
for ( count = 0 ; ; count + + ) {
2017-04-24 22:14:41 +03:00
tprints ( " , " ) ;
if ( count & & offset < = offset_end )
goto misplaced ;
2016-10-03 00:59:06 +03:00
offset_end = offset + target_vers_name_offs ;
if ( offset_end < = offset | | offset_end > ioc - > data_size )
goto misplaced ;
if ( count > = max_strlen ) {
tprints ( " ... " ) ;
break ;
}
if ( umove_or_printaddr ( tcp , addr + offset , & s ) )
break ;
tprints ( " {name= " ) ;
printstr_ex ( tcp , addr + offset_end , ioc - > data_size - offset_end ,
QUOTE_0_TERMINATED ) ;
tprintf ( " , version=% " PRIu32 " .% " PRIu32 " .% " PRIu32 " } " ,
s . version [ 0 ] , s . version [ 1 ] , s . version [ 2 ] ) ;
if ( ! s . next )
break ;
offset + = s . next ;
}
return ;
misplaced :
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced struct dm_target_versions " ) ;
2016-10-03 00:59:06 +03:00
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_dm_target_msg ( struct tcb * const tcp , const kernel_ulong_t addr ,
2017-06-18 01:23:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
2017-04-24 22:14:41 +03:00
if ( ioc - > data_start = = ioc - > data_size )
return ;
tprints ( " , " ) ;
2016-10-03 00:59:06 +03:00
if ( abbrev ( tcp ) ) {
2017-04-24 22:14:41 +03:00
tprints ( " ... " ) ;
2016-10-03 00:59:06 +03:00
return ;
}
2017-04-24 22:14:41 +03:00
static const uint32_t target_msg_message_offs =
offsetof ( struct dm_target_msg , message ) ;
uint32_t offset = ioc - > data_start ;
uint32_t offset_end = offset + target_msg_message_offs ;
2016-10-03 00:59:06 +03:00
if ( offset_end > offset & & offset_end < = ioc - > data_size ) {
struct dm_target_msg s ;
if ( umove_or_printaddr ( tcp , addr + offset , & s ) )
return ;
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " { " , s , sector ) ;
tprints ( " , message= " ) ;
2016-10-03 00:59:06 +03:00
printstr_ex ( tcp , addr + offset_end , ioc - > data_size - offset_end ,
QUOTE_0_TERMINATED ) ;
tprints ( " } " ) ;
} else {
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced struct dm_target_msg " ) ;
2016-10-03 00:59:06 +03:00
}
}
static void
2016-12-26 13:26:03 +03:00
dm_decode_string ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 06:03:09 +03:00
const struct dm_ioctl * const ioc )
2016-10-03 00:59:06 +03:00
{
2017-04-24 22:14:41 +03:00
tprints ( " , " ) ;
2016-10-03 00:59:06 +03:00
if ( abbrev ( tcp ) ) {
2017-04-24 22:14:41 +03:00
tprints ( " ... " ) ;
2016-10-03 00:59:06 +03:00
return ;
}
2017-04-24 22:14:41 +03:00
uint32_t offset = ioc - > data_start ;
if ( offset < = ioc - > data_size ) {
tprints ( " string= " ) ;
2016-10-03 00:59:06 +03:00
printstr_ex ( tcp , addr + offset , ioc - > data_size - offset ,
QUOTE_0_TERMINATED ) ;
} else {
2017-04-24 22:14:41 +03:00
tprints ( " ??? " ) ;
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " misplaced string " ) ;
2016-10-03 00:59:06 +03:00
}
}
static inline bool
dm_ioctl_has_params ( const unsigned int code )
{
switch ( code ) {
case DM_VERSION :
case DM_REMOVE_ALL :
case DM_DEV_CREATE :
case DM_DEV_REMOVE :
case DM_DEV_SUSPEND :
case DM_DEV_STATUS :
case DM_TABLE_CLEAR :
return false ;
}
return true ;
}
static int
Change type of ioctl 3rd argument from long to kernel_ureg_t
* defs.h (DECL_IOCTL): Change arg type from long to kernel_ureg_t.
* dm.c (dm_known_ioctl, dm_ioctl): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* fs_x_ioctl.c (fs_x_ioctl): Likewise.
* ioctl.c (ioctl_decode): Likewise.
* loop.c (decode_loop_info, decode_loop_info64): Change addr type
from long to kernel_ureg_t.
(loop_ioctl): Change arg type from long to kernel_ureg_t.
* ptp.c (ptp_ioctl): Likewise.
* scsi.c (print_sg_io_v3_req, print_sg_io_v3_res, print_sg_io_v4_req,
print_sg_io_v4_res, scsi_ioctl): Likewise.
* sock.c (print_ifreq, sock_ioctl): Likewise.
(decode_ifconf): Change addr type from long to kernel_ureg_t.
* term.c (decode_termios, decode_termio, decode_winsize, decode_ttysize,
decode_modem_flags): Likewise.
(term_ioctl): Change arg type from long to kernel_ureg_t.
* ubi.c (ubi_ioctl): Likewise.
* userfaultfd.c (uffdio_ioctl): Likewise.
2016-12-21 06:03:09 +03:00
dm_known_ioctl ( struct tcb * const tcp , const unsigned int code ,
2016-12-26 13:26:03 +03:00
const kernel_ulong_t arg )
2016-10-03 00:59:06 +03:00
{
struct dm_ioctl * ioc = NULL ;
struct dm_ioctl * entering_ioc = NULL ;
bool ioc_changed = false ;
if ( entering ( tcp ) ) {
ioc = malloc ( sizeof ( * ioc ) ) ;
if ( ! ioc )
return 0 ;
} else {
ioc = alloca ( sizeof ( * ioc ) ) ;
}
if ( ( umoven ( tcp , arg , offsetof ( struct dm_ioctl , data ) , ioc ) < 0 ) | |
( ioc - > data_size < offsetof ( struct dm_ioctl , data_size ) ) ) {
if ( entering ( tcp ) )
free ( ioc ) ;
return 0 ;
}
if ( entering ( tcp ) )
set_tcb_priv_data ( tcp , ioc , free ) ;
else {
entering_ioc = get_tcb_priv_data ( tcp ) ;
/*
* retrieve_status , __dev_status called only in case of success ,
* so it looks like there ' s no need to check open_count ,
* event_nr , target_count , dev fields for change ( they are
* printed only in case of absence of errors ) .
*/
if ( ! entering_ioc | |
( ioc - > version [ 0 ] ! = entering_ioc - > version [ 0 ] ) | |
( ioc - > version [ 1 ] ! = entering_ioc - > version [ 1 ] ) | |
( ioc - > version [ 2 ] ! = entering_ioc - > version [ 2 ] ) | |
( ioc - > data_size ! = entering_ioc - > data_size ) | |
( ioc - > data_start ! = entering_ioc - > data_start ) | |
( ioc - > flags ! = entering_ioc - > flags ) )
ioc_changed = true ;
}
if ( exiting ( tcp ) & & syserror ( tcp ) & & ! ioc_changed )
2017-08-14 20:25:13 +03:00
return RVAL_IOCTL_PARSED ;
2016-10-03 00:59:06 +03:00
/*
* device mapper code uses % d in some places and % u in another , but
* fields themselves are declared as __u32 .
*/
tprintf ( " %s{version=%u.%u.%u " , entering ( tcp ) ? " , " : " => " ,
ioc - > version [ 0 ] , ioc - > version [ 1 ] , ioc - > version [ 2 ] ) ;
/*
* if we use a different version of ABI , do not attempt to decode
* ioctl fields
*/
if ( ioc - > version [ 0 ] ! = DM_VERSION_MAJOR ) {
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " unsupported device mapper ABI version " ) ;
2016-10-03 00:59:06 +03:00
goto skip ;
}
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " , " , * ioc , data_size ) ;
2016-10-03 00:59:06 +03:00
if ( ioc - > data_size < offsetof ( struct dm_ioctl , data ) ) {
Introduce tprintf_comment and tprints_comment functions
* defs.h (tprintf_comment, tprints_comment): New prototypes.
* strace.c (tvprintf): New function.
(tprintf): Use it.
(tprintf_comment, tprints_comment): New functions.
* aio.c (tprint_lio_opcode): Use tprints_comment.
* dm.c (dm_decode_dm_target_spec, dm_decode_dm_target_deps,
dm_decode_dm_name_list, dm_decode_dm_target_versions,
dm_decode_dm_target_msg, dm_decode_string, dm_known_ioctl): Likewise.
* futex.c (SYS_FUNC(futex)): Likewise.
* perf.c (print_perf_event_attr): Likewise.
* seccomp.c (decode_bpf_code): Likewise.
* util.c (printxvals, printxval_searchn, printflags64): Likewise.
* btrfs.c (print_u64, btrfs_print_key_type, btrfs_print_objectid,
print_key_value_internal): Likewise.
(btrfs_ioctl): Use tprints_comment and tprintf_comment.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* execve.c (printargc): Use tprintf_comment.
* tests/btrfs.c (btrfs_test_get_dev_stats_ioctl,
btrfs_test_features_ioctls): Update expected output.
2017-04-24 22:31:54 +03:00
tprints_comment ( " data_size too small " ) ;
2016-10-03 00:59:06 +03:00
goto skip ;
}
2017-04-24 22:14:41 +03:00
if ( dm_ioctl_has_params ( code ) )
2017-07-14 03:08:09 +03:00
PRINT_FIELD_U ( " , " , * ioc , data_start ) ;
2017-04-24 22:14:41 +03:00
2016-10-03 00:59:06 +03:00
dm_decode_device ( code , ioc ) ;
dm_decode_values ( tcp , code , ioc ) ;
dm_decode_flags ( ioc ) ;
switch ( code ) {
case DM_DEV_WAIT :
case DM_TABLE_STATUS :
if ( entering ( tcp ) | | syserror ( tcp ) )
break ;
dm_decode_dm_target_spec ( tcp , arg , ioc ) ;
break ;
case DM_TABLE_LOAD :
if ( exiting ( tcp ) )
break ;
dm_decode_dm_target_spec ( tcp , arg , ioc ) ;
break ;
case DM_TABLE_DEPS :
if ( entering ( tcp ) | | syserror ( tcp ) )
break ;
dm_decode_dm_target_deps ( tcp , arg , ioc ) ;
break ;
case DM_LIST_DEVICES :
if ( entering ( tcp ) | | syserror ( tcp ) )
break ;
dm_decode_dm_name_list ( tcp , arg , ioc ) ;
break ;
case DM_LIST_VERSIONS :
if ( entering ( tcp ) | | syserror ( tcp ) )
break ;
dm_decode_dm_target_versions ( tcp , arg , ioc ) ;
break ;
case DM_TARGET_MSG :
if ( entering ( tcp ) )
dm_decode_dm_target_msg ( tcp , arg , ioc ) ;
else if ( ! syserror ( tcp ) & & ioc - > flags & DM_DATA_OUT_FLAG )
dm_decode_string ( tcp , arg , ioc ) ;
break ;
case DM_DEV_RENAME :
case DM_DEV_SET_GEOMETRY :
if ( exiting ( tcp ) )
break ;
dm_decode_string ( tcp , arg , ioc ) ;
break ;
}
skip :
tprints ( " } " ) ;
2017-08-14 20:25:13 +03:00
return RVAL_IOCTL_PARSED ;
2016-10-03 00:59:06 +03:00
}
int
2016-12-26 13:26:03 +03:00
dm_ioctl ( struct tcb * const tcp , const unsigned int code , const kernel_ulong_t arg )
2016-10-03 00:59:06 +03:00
{
switch ( code ) {
case DM_VERSION :
case DM_REMOVE_ALL :
case DM_LIST_DEVICES :
case DM_DEV_CREATE :
case DM_DEV_REMOVE :
case DM_DEV_RENAME :
case DM_DEV_SUSPEND :
case DM_DEV_STATUS :
case DM_DEV_WAIT :
case DM_TABLE_LOAD :
case DM_TABLE_CLEAR :
case DM_TABLE_DEPS :
case DM_TABLE_STATUS :
case DM_LIST_VERSIONS :
case DM_TARGET_MSG :
case DM_DEV_SET_GEOMETRY :
return dm_known_ioctl ( tcp , code , arg ) ;
default :
2017-08-27 01:24:37 +03:00
return RVAL_DECODED ;
2016-10-03 00:59:06 +03:00
}
}
# else /* !(DM_VERSION_MAJOR == 4) */
int
2016-12-26 13:26:03 +03:00
dm_ioctl ( struct tcb * const tcp , const unsigned int code , const kernel_ulong_t arg )
2016-10-03 00:59:06 +03:00
{
2017-08-27 01:24:37 +03:00
return RVAL_DECODED ;
2016-10-03 00:59:06 +03:00
}
# endif /* DM_VERSION_MAJOR == 4 */
# endif /* HAVE_LINUX_DM_IOCTL_H */