2016-10-03 00:59:06 +03:00
/*
* Check decoding of DM_ * commands of ioctl syscall .
*
* Copyright ( c ) 2016 Mikulas Patocka < mpatocka @ redhat . com >
* Copyright ( c ) 2016 Eugene Syromyatnikov < evgsyr @ gmail . com >
2017-05-22 20:14:52 +03:00
* Copyright ( c ) 2016 - 2017 The strace developers .
2016-10-03 00:59:06 +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 .
*/
# include "tests.h"
# ifdef HAVE_LINUX_DM_IOCTL_H
# include <errno.h>
# include <inttypes.h>
# include <stdbool.h>
# include <stdio.h>
# include <stddef.h>
# include <string.h>
# include <sys / ioctl.h>
2017-01-01 21:59:12 +03:00
# include <linux / ioctl.h>
2016-10-03 00:59:06 +03:00
# include <linux / dm-ioctl.h>
# ifndef VERBOSE
# define VERBOSE 0
# endif
# define STR32 "AbCdEfGhIjKlMnOpQrStUvWxYz012345"
# define ALIGNED_SIZE(s_, t_) \
( ( ( s_ ) + ( ALIGNOF ( t_ ) - 1UL ) ) & ~ ( ALIGNOF ( t_ ) - 1UL ) )
# define ALIGNED_OFFSET(t_, m_) \
ALIGNED_SIZE ( offsetof ( t_ , m_ ) , t_ )
static const char str129 [ ] = STR32 STR32 STR32 STR32 " 6 " ;
static const __u64 dts_sector_base = ( __u64 ) 0xdeadca75facef157ULL ;
static const __u64 dts_sector_step = ( __u64 ) 0x100000001ULL ;
static const __u64 dts_length_base = ( __u64 ) 0xbadc0dedda7a1057ULL ;
static const __u64 dts_length_step = ( __u64 ) 0x700000007ULL ;
static const __s32 dts_status_base = ( __s32 ) 3141592653U ;
static const __s32 dts_status_step = 0x1234 ;
static const size_t min_sizeof_dm_ioctl =
offsetof ( struct dm_ioctl , data ) ;
static struct s {
struct dm_ioctl ioc ;
union {
struct {
struct dm_target_spec target_spec ;
char target_params [ 256 ] ;
} ts ;
struct {
struct dm_target_msg target_msg ;
char target_string [ 256 ] ;
} tm ;
char string [ 256 ] ;
} u ;
} s ;
struct dm_table_open_test {
struct dm_ioctl ioc ;
struct dm_target_spec target0 ;
char param0 [ 1 ] ;
struct dm_target_spec target1 ;
char param1 [ 2 ] ;
struct dm_target_spec target2 ;
char param2 [ 3 ] ;
struct dm_target_spec target3 ;
char param3 [ 4 ] ;
struct dm_target_spec target4 ;
char param4 [ 5 ] ;
struct dm_target_spec target5 ;
char param5 [ 6 ] ;
struct dm_target_spec target6 ;
char param6 [ 7 ] ;
struct dm_target_spec target7 ;
char param7 [ 8 ] ;
struct dm_target_spec target8 ;
char param8 [ 9 ] ;
struct dm_target_spec target9 ;
char param9 [ 10 ] ;
} ;
struct dm_target_msg_test {
struct dm_ioctl ioc ;
struct dm_target_msg msg ;
} ;
struct args {
unsigned int arg ;
const char * str ;
bool has_params ;
bool has_event_nr ;
} ;
static void
init_s ( struct dm_ioctl * s , size_t size , size_t offs )
{
memset ( s , 0 , size ) ;
s - > version [ 0 ] = DM_VERSION_MAJOR ;
s - > version [ 1 ] = 1 ;
s - > version [ 2 ] = 2 ;
s - > data_size = size ;
s - > data_start = offs ;
s - > dev = 0x1234 ;
strcpy ( s - > name , " nnn " ) ;
strcpy ( s - > uuid , " uuu " ) ;
}
static void
init_dm_target_spec ( struct dm_target_spec * ptr , uint32_t id )
{
ptr - > sector_start = dts_sector_base + dts_sector_step * id ;
ptr - > length = dts_length_base + dts_length_step * id ;
ptr - > status = dts_status_base + dts_status_step * id ;
strncpy ( ptr - > target_type , str129 +
id % ( sizeof ( str129 ) - sizeof ( ptr - > target_type ) ) ,
id % ( sizeof ( ptr - > target_type ) + 1 ) ) ;
if ( id % ( sizeof ( ptr - > target_type ) + 1 ) < sizeof ( ptr - > target_type ) )
ptr - > target_type [ id % ( sizeof ( ptr - > target_type ) + 1 ) ] = ' \0 ' ;
}
# if VERBOSE
static void
print_dm_target_spec ( struct dm_target_spec * ptr , uint32_t id )
{
printf ( " {sector_start=% " PRI__u64 " , length=% " PRI__u64 " , "
" target_type= \" %.*s \" , string= " ,
dts_sector_base + dts_sector_step * id ,
dts_length_base + dts_length_step * id ,
( int ) ( id % ( sizeof ( ptr - > target_type ) + 1 ) ) ,
str129 + id % ( sizeof ( str129 ) - sizeof ( ptr - > target_type ) ) ) ;
}
# endif /* VERBOSE */
int
main ( void )
{
2017-01-01 21:59:12 +03:00
static kernel_ulong_t dummy_dm_ioctl1 =
_IOC ( _IOC_READ , DM_IOCTL , 0 , 0x1fff ) ;
static kernel_ulong_t dummy_dm_ioctl2 =
_IOC ( _IOC_READ | _IOC_WRITE , DM_IOCTL , 0xed , 0 ) ;
static kernel_ulong_t dummy_dm_arg =
( kernel_ulong_t ) 0xbadc0dedda7a1057ULL ;
2016-10-03 00:59:06 +03:00
/* We can't check these properly for now */
static struct args dummy_check_cmds_nodev [ ] = {
{ ARG_STR ( DM_REMOVE_ALL ) , false } ,
{ ARG_STR ( DM_LIST_DEVICES ) , true } ,
{ ARG_STR ( DM_LIST_VERSIONS ) , true } ,
} ;
static struct args dummy_check_cmds [ ] = {
{ ARG_STR ( DM_DEV_CREATE ) , false } ,
{ ARG_STR ( DM_DEV_REMOVE ) , false , true } ,
{ ARG_STR ( DM_DEV_STATUS ) , false } ,
{ ARG_STR ( DM_DEV_WAIT ) , true , true } ,
{ ARG_STR ( DM_TABLE_CLEAR ) , false } ,
{ ARG_STR ( DM_TABLE_DEPS ) , true } ,
{ ARG_STR ( DM_TABLE_STATUS ) , true } ,
} ;
struct dm_ioctl * unaligned_dm_arg =
tail_alloc ( offsetof ( struct dm_ioctl , data ) ) ;
struct dm_ioctl * dm_arg =
tail_alloc ( ALIGNED_OFFSET ( struct dm_ioctl , data ) ) ;
struct dm_table_open_test * dm_arg_open1 =
tail_alloc ( ALIGNED_OFFSET ( struct dm_table_open_test , target1 ) ) ;
struct dm_table_open_test * dm_arg_open2 =
tail_alloc ( ALIGNED_OFFSET ( struct dm_table_open_test , param1 ) ) ;
struct dm_table_open_test * dm_arg_open3 =
tail_alloc ( ALIGNED_OFFSET ( struct dm_table_open_test , target9 ) ) ;
struct dm_target_msg_test * dm_arg_msg =
tail_alloc ( sizeof ( * dm_arg_msg ) ) ;
long rc ;
const char * errstr ;
unsigned int i ;
/* Incorrect operation */
ioctl ( - 1 , _IOW ( DM_IOCTL , 0xde , int ) , dm_arg ) ;
2017-01-01 21:53:48 +03:00
printf ( " ioctl(-1, _IOC(_IOC_WRITE, %#x, 0xde, %#zx), %p) = "
2016-10-03 00:59:06 +03:00
" -1 EBADF (%m) \n " ,
DM_IOCTL , sizeof ( int ) , dm_arg ) ;
2017-01-01 21:59:12 +03:00
ioctl ( - 1 , dummy_dm_ioctl1 , 0 ) ;
printf ( " ioctl(-1, _IOC(_IOC_READ, %#x, 0, %#x), 0) = -1 EBADF (%m) \n " ,
DM_IOCTL , ( unsigned int ) _IOC_SIZE ( dummy_dm_ioctl1 ) ) ;
ioctl ( - 1 , dummy_dm_ioctl2 , dummy_dm_arg ) ;
printf ( " ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, %#x, %#x, 0), %#lx) = "
" -1 EBADF (%m) \n " ,
DM_IOCTL , ( unsigned int ) _IOC_NR ( dummy_dm_ioctl2 ) ,
( unsigned long ) dummy_dm_arg ) ;
2016-10-03 00:59:06 +03:00
/* DM_VERSION */
/* Incorrect pointer */
ioctl ( - 1 , DM_VERSION , dm_arg + 1 ) ;
printf ( " ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m) \n " , dm_arg + 1 ) ;
/* Incorrect data_size */
init_s ( dm_arg , 0 , 0 ) ;
ioctl ( - 1 , DM_VERSION , & s ) ;
printf ( " ioctl(-1, DM_VERSION, %p) = -1 EBADF (%m) \n " , & s ) ;
/* Incorrect version */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
dm_arg - > version [ 0 ] = 0xbadc0ded ;
dm_arg - > version [ 1 ] = 0xbadc0dee ;
dm_arg - > version [ 2 ] = 0xbadc0def ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
2017-04-24 22:14:41 +03:00
printf ( " ioctl(-1, DM_VERSION, {version=%u.%u.%u "
" /* unsupported device mapper ABI version */}) = "
2016-10-03 00:59:06 +03:00
" -1 EBADF (%m) \n " , 0xbadc0ded , 0xbadc0dee , 0xbadc0def ) ;
/* Incorrect data_size */
init_s ( dm_arg , 14 , 64 ) ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
2017-04-24 22:14:41 +03:00
printf ( " ioctl(-1, DM_VERSION, {version=4.1.2, data_size=14 "
" /* data_size too small */}) = -1 EBADF (%m) \n " ) ;
2016-10-03 00:59:06 +03:00
/* Unterminated name/uuid */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
strncpy ( dm_arg - > name , str129 , sizeof ( dm_arg - > name ) ) ;
strncpy ( dm_arg - > uuid , str129 , sizeof ( dm_arg - > uuid ) ) ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
printf ( " ioctl(-1, DM_VERSION, {version=4.1.2, data_size=%zu, "
" dev=makedev(18, 52), name= \" %.127s \" , uuid= \" %.128s \" , "
" flags=0}) = -1 EBADF (%m) \n " ,
min_sizeof_dm_ioctl , str129 , str129 ) ;
/* Normal call */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
printf ( " ioctl(-1, DM_VERSION, "
" {version=4.1.2, data_size=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0}) = "
" -1 EBADF (%m) \n " , min_sizeof_dm_ioctl ) ;
/* Zero dev, name, uuid */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
dm_arg - > data_size = 0xfacefeed ;
dm_arg - > dev = 0 ;
dm_arg - > name [ 0 ] = ' \0 ' ;
dm_arg - > uuid [ 0 ] = ' \0 ' ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
printf ( " ioctl(-1, DM_VERSION, "
" {version=4.1.2, data_size=%u, flags=0}) = "
" -1 EBADF (%m) \n " , 0xfacefeed ) ;
/* Flag */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
dm_arg - > flags = 0xffffffff ;
ioctl ( - 1 , DM_VERSION , dm_arg ) ;
printf ( " ioctl(-1, DM_VERSION, "
" {version=4.1.2, data_size=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags= "
" DM_READONLY_FLAG|DM_SUSPEND_FLAG|DM_EXISTS_FLAG| "
" DM_PERSISTENT_DEV_FLAG|DM_STATUS_TABLE_FLAG| "
" DM_ACTIVE_PRESENT_FLAG|DM_INACTIVE_PRESENT_FLAG| "
" DM_BUFFER_FULL_FLAG|DM_SKIP_BDGET_FLAG|DM_SKIP_LOCKFS_FLAG| "
" DM_NOFLUSH_FLAG|DM_QUERY_INACTIVE_TABLE_FLAG| "
" DM_UEVENT_GENERATED_FLAG|DM_UUID_FLAG|DM_SECURE_DATA_FLAG| "
" DM_DATA_OUT_FLAG|DM_DEFERRED_REMOVE|DM_INTERNAL_SUSPEND_FLAG| "
" 0xfff80080}) = -1 EBADF (%m) \n " ,
min_sizeof_dm_ioctl ) ;
/* Normal call */
init_s ( & s . ioc , sizeof ( s . ioc ) , 0 ) ;
ioctl ( - 1 , DM_VERSION , & s ) ;
printf ( " ioctl(-1, DM_VERSION, "
" {version=4.1.2, data_size=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0}) = "
" -1 EBADF (%m) \n " , sizeof ( s . ioc ) ) ;
/* DM_REMOVE_ALL */
/* DM_LIST_DEVICES */
/* DM_LIST_VERSIONS */
for ( i = 0 ; i < ARRAY_SIZE ( dummy_check_cmds_nodev ) ; i + + ) {
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
ioctl ( - 1 , dummy_check_cmds_nodev [ i ] . arg , dm_arg ) ;
printf ( " ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, "
" flags=0}) = -1 EBADF (%m) \n " ,
dummy_check_cmds_nodev [ i ] . str ,
min_sizeof_dm_ioctl ,
dummy_check_cmds_nodev [ i ] . has_params ?
" , data_start=0 " : " " ) ;
}
/* DM_DEV_CREATE */
/* DM_DEV_REMOVE */
/* DM_DEV_STATUS */
/* DM_DEV_WAIT */
/* DM_TABLE_CLEAR */
/* DM_TABLE_DEPS */
/* DM_TABLE_STATUS */
for ( i = 0 ; i < ARRAY_SIZE ( dummy_check_cmds ) ; i + + ) {
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
ioctl ( - 1 , dummy_check_cmds [ i ] . arg , dm_arg ) ;
printf ( " ioctl(-1, %s, {version=4.1.2, data_size=%zu%s, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" %s, "
" flags=0}) = -1 EBADF (%m) \n " ,
dummy_check_cmds [ i ] . str , min_sizeof_dm_ioctl ,
dummy_check_cmds [ i ] . has_params ? " , data_start=0 " : " " ,
dummy_check_cmds [ i ] . has_event_nr ? " , event_nr=0 " : " " ) ;
}
/* DM_DEV_SUSPEND */
init_s ( & s . ioc , sizeof ( s . ioc ) , 0 ) ;
s . ioc . flags = DM_SUSPEND_FLAG ;
s . ioc . event_nr = 0xbadc0ded ;
ioctl ( - 1 , DM_DEV_SUSPEND , & s ) ;
printf ( " ioctl(-1, DM_DEV_SUSPEND, "
" {version=4.1.2, data_size=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" flags=DM_SUSPEND_FLAG}) = -1 EBADF (%m) \n " , sizeof ( s . ioc ) ) ;
init_s ( & s . ioc , sizeof ( s . ioc ) , 0 ) ;
s . ioc . event_nr = 0xbadc0ded ;
ioctl ( - 1 , DM_DEV_SUSPEND , & s ) ;
printf ( " ioctl(-1, DM_DEV_SUSPEND, "
" {version=4.1.2, data_size=%zu, dev=makedev(18, 52), "
" name= \" nnn \" , uuid= \" uuu \" , event_nr=3134983661, "
" flags=0}) = -1 EBADF (%m) \n " , sizeof ( s . ioc ) ) ;
/* DM_TABLE_LOAD */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
s . ioc . target_count = 1 ;
s . u . ts . target_spec . sector_start = 0x10 ;
s . u . ts . target_spec . length = 0x20 ;
s . u . ts . target_spec . next =
sizeof ( s . u . ts . target_spec ) + sizeof ( s . u . ts . target_params ) ;
strcpy ( s . u . ts . target_spec . target_type , " tgt " ) ;
strcpy ( s . u . ts . target_params , " tparams " ) ;
ioctl ( - 1 , DM_TABLE_LOAD , & s ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%u, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=1, flags=0, "
# if VERBOSE
" {sector_start=16, length=32, target_type= \" tgt \" , "
" string= \" tparams \" } "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " , s . ioc . data_size , s . ioc . data_start ) ;
/* No targets */
init_s ( dm_arg , min_sizeof_dm_ioctl , min_sizeof_dm_ioctl ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) ;
dm_arg - > target_count = 0 ;
ioctl ( - 1 , DM_TABLE_LOAD , dm_arg ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=0, flags=0}) = -1 EBADF (%m) \n " ,
sizeof ( * dm_arg ) , min_sizeof_dm_ioctl ) ;
/* Invalid data_start */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0xfffffff8 ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) ;
dm_arg - > target_count = 1234 ;
ioctl ( - 1 , DM_TABLE_LOAD , dm_arg ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=1234, flags=0, "
# if VERBOSE
2017-04-24 22:14:41 +03:00
" ??? /* misplaced struct dm_target_spec */ "
# else
2016-10-03 00:59:06 +03:00
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " , sizeof ( * dm_arg ) , 0xfffffff8 ) ;
/* Inaccessible pointer */
init_s ( & dm_arg_open1 - > ioc , offsetof ( struct dm_table_open_test , target1 ) ,
offsetof ( struct dm_table_open_test , target1 ) ) ;
dm_arg_open1 - > ioc . data_size = sizeof ( * dm_arg_open1 ) ;
dm_arg_open1 - > ioc . target_count = 0xdeaddea1 ;
ioctl ( - 1 , DM_TABLE_LOAD , dm_arg_open1 ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=3735936673, flags=0, "
# if VERBOSE
" %p "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " , sizeof ( * dm_arg_open1 ) ,
offsetof ( struct dm_table_open_test , target1 )
# if VERBOSE
, ( char * ) dm_arg_open1 +
offsetof ( struct dm_table_open_test , target1 )
# endif /* VERBOSE */
) ;
/* Inaccessible string */
init_s ( & dm_arg_open2 - > ioc , offsetof ( struct dm_table_open_test , param1 ) ,
offsetof ( struct dm_table_open_test , target1 ) ) ;
dm_arg_open2 - > ioc . data_size = sizeof ( * dm_arg_open2 ) ;
dm_arg_open2 - > ioc . target_count = 2 ;
init_dm_target_spec ( & dm_arg_open2 - > target1 , 7 ) ;
dm_arg_open2 - > target1 . next =
offsetof ( struct dm_table_open_test , target3 ) -
offsetof ( struct dm_table_open_test , target1 ) ;
rc = ioctl ( - 1 , DM_TABLE_LOAD , dm_arg_open2 ) ;
errstr = sprintrc ( rc ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=2, flags=0, " ,
sizeof ( * dm_arg_open2 ) ,
offsetof ( struct dm_table_open_test , target1 ) ) ;
# if VERBOSE
print_dm_target_spec ( & dm_arg_open2 - > target1 , 7 ) ;
printf ( " %p}, %p " ,
( char * ) dm_arg_open2 +
offsetof ( struct dm_table_open_test , param1 ) ,
( char * ) dm_arg_open2 +
offsetof ( struct dm_table_open_test , target3 ) ) ;
# else /* !VERBOSE */
printf ( " ... " ) ;
# endif /* VERBOSE */
printf ( " }) = %s \n " , errstr ) ;
/* Incorrect next */
init_s ( & dm_arg_open3 - > ioc , offsetof ( struct dm_table_open_test , target5 ) ,
offsetof ( struct dm_table_open_test , target0 ) ) ;
dm_arg_open3 - > ioc . target_count = 4 ;
init_dm_target_spec ( & dm_arg_open3 - > target0 , 9 ) ;
dm_arg_open3 - > target0 . next =
offsetof ( struct dm_table_open_test , target1 ) -
offsetof ( struct dm_table_open_test , target0 ) ;
dm_arg_open3 - > param0 [ 0 ] = ' \0 ' ;
init_dm_target_spec ( & dm_arg_open3 - > target1 , 15 ) ;
dm_arg_open3 - > target1 . next =
offsetof ( struct dm_table_open_test , target3 ) -
offsetof ( struct dm_table_open_test , target1 ) ;
dm_arg_open3 - > param1 [ 0 ] = ' \377 ' ;
dm_arg_open3 - > param1 [ 1 ] = ' \0 ' ;
init_dm_target_spec ( & dm_arg_open3 - > target3 , 42 ) ;
dm_arg_open3 - > target3 . next = 0xdeadbeef ;
dm_arg_open3 - > param3 [ 0 ] = ' \1 ' ;
dm_arg_open3 - > param3 [ 1 ] = ' \2 ' ;
dm_arg_open3 - > param3 [ 2 ] = ' \0 ' ;
rc = ioctl ( - 1 , DM_TABLE_LOAD , dm_arg_open3 ) ;
errstr = sprintrc ( rc ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=4, flags=0, " ,
offsetof ( struct dm_table_open_test , target5 ) ,
offsetof ( struct dm_table_open_test , target0 ) ) ;
# if VERBOSE
print_dm_target_spec ( & dm_arg_open3 - > target0 , 9 ) ;
printf ( " \" \" }, " ) ;
print_dm_target_spec ( & dm_arg_open3 - > target1 , 15 ) ;
printf ( " \" \\ 377 \" }, " ) ;
print_dm_target_spec ( & dm_arg_open3 - > target1 , 42 ) ;
2017-04-24 22:14:41 +03:00
printf ( " \" \\ 1 \\ 2 \" }, ??? /* misplaced struct dm_target_spec */ " ) ;
2016-10-03 00:59:06 +03:00
# else /* !VERBOSE */
printf ( " ... " ) ;
# endif /* VERBOSE */
printf ( " }) = %s \n " , errstr ) ;
# define FILL_DM_TARGET(id, id_next) \
do { \
init_dm_target_spec ( & dm_arg_open3 - > target # # id , id ) ; \
dm_arg_open3 - > target # # id . next = \
offsetof ( struct dm_table_open_test , \
target # # id_next ) - \
offsetof ( struct dm_table_open_test , \
target # # id ) ; \
strncpy ( dm_arg_open3 - > param # # id , str129 + id * 2 , id ) ; \
dm_arg_open3 - > param # # id [ id ] = ' \0 ' ; \
} while ( 0 )
# define PRINT_DM_TARGET(id) \
do { \
print_dm_target_spec ( & dm_arg_open3 - > target # # id , id ) ; \
printf ( " \" %.*s \" }, " , id , str129 + id * 2 ) ; \
} while ( 0 )
/* max_strlen limit */
init_s ( & dm_arg_open3 - > ioc , offsetof ( struct dm_table_open_test , target9 ) ,
offsetof ( struct dm_table_open_test , target0 ) ) ;
dm_arg_open3 - > ioc . data_size = sizeof ( * dm_arg_open3 ) ;
dm_arg_open3 - > ioc . target_count = 0xbadc0ded ;
FILL_DM_TARGET ( 0 , 1 ) ;
FILL_DM_TARGET ( 1 , 2 ) ;
FILL_DM_TARGET ( 2 , 3 ) ;
FILL_DM_TARGET ( 3 , 4 ) ;
FILL_DM_TARGET ( 4 , 5 ) ;
FILL_DM_TARGET ( 5 , 6 ) ;
FILL_DM_TARGET ( 6 , 7 ) ;
FILL_DM_TARGET ( 7 , 8 ) ;
FILL_DM_TARGET ( 8 , 9 ) ;
rc = ioctl ( - 1 , DM_TABLE_LOAD , dm_arg_open3 ) ;
errstr = sprintrc ( rc ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=3134983661, flags=0, " ,
sizeof ( * dm_arg_open3 ) ,
offsetof ( struct dm_table_open_test , target0 ) ) ;
# if VERBOSE
PRINT_DM_TARGET ( 0 ) ;
PRINT_DM_TARGET ( 1 ) ;
PRINT_DM_TARGET ( 2 ) ;
PRINT_DM_TARGET ( 3 ) ;
PRINT_DM_TARGET ( 4 ) ;
PRINT_DM_TARGET ( 5 ) ;
PRINT_DM_TARGET ( 6 ) ;
PRINT_DM_TARGET ( 7 ) ;
PRINT_DM_TARGET ( 8 ) ;
# endif /* VERBOSE */
printf ( " ...}) = %s \n " , errstr ) ;
/* DM_TARGET_MSG */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
s . u . tm . target_msg . sector = 0x1234 ;
strcpy ( s . u . string + offsetof ( struct dm_target_msg , message ) ,
" long target msg " ) ;
ioctl ( - 1 , DM_TARGET_MSG , & s ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%u, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, "
# if VERBOSE
" {sector=4660, message= \" long targ \" ...} "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
s . ioc . data_size , s . ioc . data_start ) ;
/* Invalid data_start */
init_s ( dm_arg , min_sizeof_dm_ioctl , min_sizeof_dm_ioctl ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) ;
ioctl ( - 1 , DM_TARGET_MSG , dm_arg ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, "
# if VERBOSE
2017-04-24 22:14:41 +03:00
" ??? /* misplaced struct dm_target_msg */ "
2016-10-03 00:59:06 +03:00
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
sizeof ( * dm_arg ) , min_sizeof_dm_ioctl ) ;
/* Invalid data_start */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0xffffffff ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) ;
ioctl ( - 1 , DM_TARGET_MSG , dm_arg ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%zu, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, "
# if VERBOSE
2017-04-24 22:14:41 +03:00
" ??? /* misplaced struct dm_target_msg */ "
2016-10-03 00:59:06 +03:00
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
sizeof ( * dm_arg ) , 0xffffffff ) ;
/* Inaccessible pointer */
init_s ( dm_arg , min_sizeof_dm_ioctl , 0 ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) + sizeof ( struct dm_target_msg ) ;
dm_arg - > data_start = sizeof ( * dm_arg ) ;
ioctl ( - 1 , DM_TARGET_MSG , dm_arg ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, "
# if VERBOSE
" %p "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
sizeof ( * dm_arg ) + sizeof ( struct dm_target_msg ) ,
sizeof ( * dm_arg )
# if VERBOSE
, ( char * ) dm_arg + sizeof ( * dm_arg )
# endif /* VERBOSE */
) ;
/* Inaccessible string */
init_s ( & dm_arg_msg - > ioc , sizeof ( * dm_arg_msg ) ,
offsetof ( struct dm_target_msg_test , msg ) ) ;
dm_arg_msg - > ioc . data_size = sizeof ( * dm_arg_msg ) + 1 ;
dm_arg_msg - > msg . sector = ( __u64 ) 0xdeadbeeffacef157ULL ;
rc = ioctl ( - 1 , DM_TARGET_MSG , dm_arg_msg ) ;
errstr = sprintrc ( rc ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, " ,
sizeof ( * dm_arg_msg ) + 1 ,
offsetof ( struct dm_target_msg_test , msg ) ) ;
# if VERBOSE
printf ( " {sector=% " PRI__u64 " , message=%p} " ,
( __u64 ) 0xdeadbeeffacef157ULL ,
( char * ) dm_arg_msg +
offsetof ( struct dm_target_msg_test , msg . message ) ) ;
# else /* !VERBOSE */
printf ( " ... " ) ;
# endif /* VERBOSE */
printf ( " }) = %s \n " , errstr ) ;
/* Zero-sied string */
init_s ( & dm_arg_msg - > ioc , sizeof ( * dm_arg_msg ) ,
offsetof ( struct dm_target_msg_test , msg ) ) ;
dm_arg_msg - > msg . sector = ( __u64 ) 0xdeadbeeffacef157ULL ;
rc = ioctl ( - 1 , DM_TARGET_MSG , dm_arg_msg ) ;
errstr = sprintrc ( rc ) ;
printf ( " ioctl(-1, DM_TARGET_MSG, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, " ,
sizeof ( * dm_arg_msg ) , offsetof ( struct dm_target_msg_test , msg ) ) ;
# if VERBOSE
printf ( " {sector=% " PRI__u64 " , message= \" \" } " ,
( __u64 ) 0xdeadbeeffacef157ULL ) ;
# else /* !VERBOSE */
printf ( " ... " ) ;
# endif /* VERBOSE */
printf ( " }) = %s \n " , errstr ) ;
/* DM_DEV_SET_GEOMETRY */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
strcpy ( s . u . string , " 10 20 30 40 " ) ;
ioctl ( - 1 , DM_DEV_SET_GEOMETRY , & s ) ;
printf ( " ioctl(-1, DM_DEV_SET_GEOMETRY, "
" {version=4.1.2, data_size=%u, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , flags=0, "
# if VERBOSE
" string= \" 10 20 30 \" ... "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
s . ioc . data_size , s . ioc . data_start ) ;
/* DM_DEV_RENAME */
/* Inaccessible data */
init_s ( dm_arg , min_sizeof_dm_ioctl , min_sizeof_dm_ioctl ) ;
dm_arg - > data_size = sizeof ( * dm_arg ) ;
memcpy ( unaligned_dm_arg , dm_arg , offsetof ( struct dm_ioctl , data ) ) ;
ioctl ( - 1 , DM_DEV_RENAME , unaligned_dm_arg ) ;
printf ( " ioctl(-1, DM_DEV_RENAME, "
" {version=4.1.2, data_size=%zu, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , event_nr=0, "
" flags=0, "
# if VERBOSE
" string=%p "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
sizeof ( * unaligned_dm_arg ) , min_sizeof_dm_ioctl
# if VERBOSE
, ( char * ) unaligned_dm_arg + min_sizeof_dm_ioctl
# endif /* VERBOSE */
) ;
/* Incorrect data_start data */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
s . ioc . data_start = 0xdeadbeef ;
ioctl ( - 1 , DM_DEV_RENAME , & s ) ;
printf ( " ioctl(-1, DM_DEV_RENAME, "
" {version=4.1.2, data_size=%u, data_start=3735928559, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , event_nr=0, "
" flags=0, "
# if VERBOSE
2017-04-24 22:14:41 +03:00
" ??? /* misplaced string */ "
2016-10-03 00:59:06 +03:00
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
s . ioc . data_size ) ;
/* Strange but still valid data_start */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
/* Curiously, this is a valid structure */
s . ioc . data_start = offsetof ( struct dm_ioctl , name ) + 1 ;
ioctl ( - 1 , DM_DEV_RENAME , & s ) ;
printf ( " ioctl(-1, DM_DEV_RENAME, "
" {version=4.1.2, data_size=%u, data_start=%zu, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , event_nr=0, "
" flags=0, "
# if VERBOSE
" string= \" nn \" "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
s . ioc . data_size ,
offsetof ( struct dm_ioctl , name ) + 1 ) ;
/* Correct data */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
strcpy ( s . u . string , " new long name " ) ;
ioctl ( - 1 , DM_DEV_RENAME , & s ) ;
printf ( " ioctl(-1, DM_DEV_RENAME, "
" {version=4.1.2, data_size=%u, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , event_nr=0, "
" flags=0, "
# if VERBOSE
" string= \" new long \" ... "
# else /* !VERBOSE */
" ... "
# endif /* VERBOSE */
" }) = -1 EBADF (%m) \n " ,
s . ioc . data_size , s . ioc . data_start ) ;
/* DM_TABLE_LOAD */
init_s ( & s . ioc , sizeof ( s ) , offsetof ( struct s , u ) ) ;
s . ioc . target_count = - 1U ;
ioctl ( - 1 , DM_TABLE_LOAD , & s ) ;
printf ( " ioctl(-1, DM_TABLE_LOAD, "
" {version=4.1.2, data_size=%u, data_start=%u, "
" dev=makedev(18, 52), name= \" nnn \" , uuid= \" uuu \" , "
" target_count=4294967295, flags=0, "
# if VERBOSE
2017-04-24 22:14:41 +03:00
" {sector_start=0, length=0, target_type= \" \" , string= \" \" } "
" , ??? /* misplaced struct dm_target_spec */ "
# else
" ... "
2016-10-03 00:59:06 +03:00
# endif /* VERBOSE */
2017-04-24 22:14:41 +03:00
" }) = -1 EBADF (%m) \n " ,
2016-10-03 00:59:06 +03:00
s . ioc . data_size , s . ioc . data_start ) ;
puts ( " +++ exited with 0 +++ " ) ;
return 0 ;
}
# else /* !HAVE_LINUX_DM_IOCTL_H */
SKIP_MAIN_UNDEFINED ( " HAVE_LINUX_DM_IOCTL_H " )
# endif /* HAVE_LINUX_DM_IOCTL_H */