2017-01-09 00:22:42 +00:00
/*
* Check decoding of ioctl SG_IO v3 commands .
*
* Copyright ( c ) 2017 Dmitry V . Levin < ldv @ altlinux . org >
* 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_SCSI_SG_H
# include <inttypes.h>
# include <stdio.h>
# include <sys / ioctl.h>
# include <sys / uio.h>
# include <scsi / sg.h>
int
main ( void )
{
ioctl ( - 1 , SG_IO , 0 ) ;
printf ( " ioctl(-1, SG_IO, NULL) = -1 EBADF (%m) \n " ) ;
2017-03-16 13:46:36 +00:00
TAIL_ALLOC_OBJECT_CONST_PTR ( struct sg_io_hdr , sg_io ) ;
2017-01-09 00:22:42 +00:00
fill_memory ( sg_io , sizeof ( * sg_io ) ) ;
const void * const efault = sg_io + 1 ;
ioctl ( - 1 , SG_IO , efault ) ;
printf ( " ioctl(-1, SG_IO, %p) = -1 EBADF (%m) \n " , efault ) ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, [%u]) = -1 EBADF (%m) \n " , sg_io - > interface_id ) ;
2017-03-16 13:46:36 +00:00
TAIL_ALLOC_OBJECT_CONST_PTR ( unsigned int , piid ) ;
2017-01-09 00:22:42 +00:00
* piid = ( unsigned char ) ' S ' ;
ioctl ( - 1 , SG_IO , piid ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S', %p}) = -1 EBADF (%m) \n " , piid + 1 ) ;
sg_io - > interface_id = ( unsigned char ) ' S ' ;
sg_io - > dxfer_direction = - 2 ;
sg_io - > flags = - 1U ;
sg_io - > info = - 1U ;
sg_io - > dxferp = ( void * ) ( unsigned long ) 0xfacefeedfffffff1ULL ;
sg_io - > cmdp = ( void * ) ( unsigned long ) 0xfacefeedfffffff2ULL ;
sg_io - > sbp = ( void * ) ( unsigned long ) 0xfacefeedfffffff3ULL ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_TO_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT "
" |SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER "
" |SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8 "
" , dxferp=%p "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8 "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
sg_io - > dxferp ,
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
sg_io - > dxfer_direction = - 3 ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_FROM_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT "
" |SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER "
" |SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8 "
" , dxferp=%p "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8 "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
sg_io - > dxferp ,
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
const struct iovec iov [ ] = {
{
. iov_base = ( void * ) efault - 2 ,
. iov_len = 2
} , {
. iov_base = ( void * ) efault - 3 ,
. iov_len = 4
}
} ;
struct iovec * const t_iov = tail_memdup ( iov , sizeof ( iov ) ) ;
sg_io - > flags = 0x24 ;
sg_io - > info = 1 ;
sg_io - > dxfer_direction = - 2 ;
sg_io - > iovec_count = ARRAY_SIZE ( iov ) ;
sg_io - > dxfer_len = iov [ 0 ] . iov_len + iov [ 1 ] . iov_len - 1 ;
sg_io - > dxferp = t_iov ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_TO_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_MMAP_IO|SG_FLAG_Q_AT_HEAD "
" , dxferp=[{iov_base= \" \\ %o \\ %o \" , iov_len=%u} "
" , {iov_base= \" \\ %o \\ %o \\ %o \" , iov_len=%u}] "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( iov [ 0 ] . iov_base + 0 ) ,
* ( unsigned char * ) ( iov [ 0 ] . iov_base + 1 ) ,
2017-01-09 00:22:42 +00:00
( unsigned int ) iov [ 0 ] . iov_len ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 0 ) ,
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 1 ) ,
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 2 ) ,
2017-01-09 00:22:42 +00:00
( unsigned int ) iov [ 1 ] . iov_len ,
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
sg_io - > flags = 0x11 ;
sg_io - > dxfer_direction = - 3 ;
sg_io - > resid = sg_io - > dxfer_len + 1 ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_FROM_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_DIRECT_IO|SG_FLAG_Q_AT_TAIL "
" , dxferp=[{iov_base= \" \\ %o \\ %o \" , iov_len=%u} "
" , {iov_base= \" \\ %o \\ %o \\ %o \" , iov_len=%u}] "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( iov [ 0 ] . iov_base + 0 ) ,
* ( unsigned char * ) ( iov [ 0 ] . iov_base + 1 ) ,
2017-01-09 00:22:42 +00:00
( unsigned int ) iov [ 0 ] . iov_len ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 0 ) ,
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 1 ) ,
* ( unsigned char * ) ( iov [ 1 ] . iov_base + 2 ) ,
2017-01-09 00:22:42 +00:00
( unsigned int ) iov [ 1 ] . iov_len ,
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
sg_io - > flags = 0x10000 ;
sg_io - > info = 0xdeadbeef ;
sg_io - > iovec_count = 0 ;
sg_io - > dxfer_len = 5 ;
sg_io - > resid = 1 ;
sg_io - > dxferp = ( void * ) efault - ( sg_io - > dxfer_len - sg_io - > resid ) ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_FROM_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_NO_DXFER "
" , dxferp= \" \\ x%x \\ x%x \\ x%x \\ x%x \" "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8 "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( sg_io - > dxferp + 0 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 1 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 2 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 3 ) ,
2017-01-09 00:22:42 +00:00
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
sg_io - > flags = 2 ;
sg_io - > dxfer_direction = - 4 ;
sg_io - > dxfer_len = 3 ;
sg_io - > resid = 1 ;
sg_io - > dxferp = ( void * ) efault - sg_io - > dxfer_len ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_TO_FROM_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=SG_FLAG_UNUSED_LUN_INHIBIT "
" , dxferp= \" \\ x%x \\ x%x \\ x%x \" => dxferp= \" \\ x%x \\ x%x \" "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8 "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( sg_io - > dxferp + 0 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 1 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 2 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 0 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 1 ) ,
2017-01-09 00:22:42 +00:00
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
sg_io - > flags = 0 ;
sg_io - > resid = sg_io - > dxfer_len ;
ioctl ( - 1 , SG_IO , sg_io ) ;
printf ( " ioctl(-1, SG_IO, {interface_id='S' "
" , dxfer_direction=SG_DXFER_TO_FROM_DEV "
" , cmd_len=%u "
" , cmdp=%p "
" , mx_sb_len=%u "
" , iovec_count=%u "
" , dxfer_len=%u "
" , timeout=%u "
" , flags=0 "
" , dxferp= \" \\ x%x \\ x%x \\ x%x \" "
" , status=%#x "
" , masked_status=%#x "
" , msg_status=%#x "
" , sb_len_wr=%u "
" , sbp=%p "
" , host_status=%#x "
" , driver_status=%#x "
" , resid=%d "
" , duration=%u "
" , info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8 "
" }) = -1 EBADF (%m) \n " ,
sg_io - > cmd_len ,
sg_io - > cmdp ,
sg_io - > mx_sb_len ,
sg_io - > iovec_count ,
sg_io - > dxfer_len ,
sg_io - > timeout ,
2017-06-17 22:23:09 +00:00
* ( unsigned char * ) ( sg_io - > dxferp + 0 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 1 ) ,
* ( unsigned char * ) ( sg_io - > dxferp + 2 ) ,
2017-01-09 00:22:42 +00:00
sg_io - > status ,
sg_io - > masked_status ,
sg_io - > msg_status ,
sg_io - > sb_len_wr ,
sg_io - > sbp ,
sg_io - > host_status ,
sg_io - > driver_status ,
sg_io - > resid ,
sg_io - > duration ) ;
puts ( " +++ exited with 0 +++ " ) ;
return 0 ;
}
# else
SKIP_MAIN_UNDEFINED ( " HAVE_SCSI_SG_H " )
# endif