1 /* 2 * Check decoding of SCSI ioctl commands. 3 * 4 * Copyright (c) 2017 Dmitry V. Levin <ldv (at) altlinux.org> 5 * Copyright (c) 2017-2018 The strace developers. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "tests.h" 32 33 #ifdef HAVE_SCSI_SG_H 34 35 # include <stdio.h> 36 # include <sys/ioctl.h> 37 # include <scsi/sg.h> 38 # include "xlat/scsi_sg_commands.h" 39 40 # define TEST_NO_ARG(cmd) \ 41 do { \ 42 ioctl(-1, cmd, 0xdeadbeef); \ 43 printf("ioctl(-1, %s) = -1 EBADF (%m)\n", #cmd); \ 44 } while (0) 45 46 # define TEST_NULL_ARG(cmd) \ 47 do { \ 48 ioctl(-1, cmd, 0); \ 49 printf("ioctl(-1, %s, NULL) = -1 EBADF (%m)\n", #cmd); \ 50 } while (0) 51 52 # define TEST_TAKES_INT_BY_VAL(cmd, val) \ 53 do { \ 54 ioctl(-1, cmd, val); \ 55 printf("ioctl(-1, %s, %#x) = -1 EBADF (%m)\n", #cmd, val); \ 56 } while (0) 57 58 # define TEST_TAKES_INT_BY_PTR(cmd, pint) \ 59 do { \ 60 ioctl(-1, cmd, pint); \ 61 printf("ioctl(-1, %s, [%d]) = -1 EBADF (%m)\n", #cmd, *(pint)); \ 62 } while (0) 63 64 # define TEST_RETURNS_INT_BY_PTR(cmd, pint) \ 65 do { \ 66 ioctl(-1, cmd, pint); \ 67 printf("ioctl(-1, %s, %p) = -1 EBADF (%m)\n", #cmd, pint); \ 68 } while (0) 69 70 int 71 main(void) 72 { 73 TAIL_ALLOC_OBJECT_CONST_PTR(int, pint); 74 *pint = (int) 0xfacefeed; 75 76 TEST_NO_ARG(SG_GET_TIMEOUT); 77 78 TEST_NULL_ARG(SG_SET_TIMEOUT); 79 TEST_NULL_ARG(SG_EMULATED_HOST); 80 TEST_NULL_ARG(SG_GET_TRANSFORM); 81 TEST_NULL_ARG(SG_GET_COMMAND_Q); 82 TEST_NULL_ARG(SG_SET_COMMAND_Q); 83 TEST_NULL_ARG(SG_GET_RESERVED_SIZE); 84 TEST_NULL_ARG(SG_SET_RESERVED_SIZE); 85 TEST_NULL_ARG(SG_GET_SCSI_ID); 86 TEST_NULL_ARG(SG_SET_FORCE_LOW_DMA); 87 TEST_NULL_ARG(SG_GET_LOW_DMA); 88 TEST_NULL_ARG(SG_SET_FORCE_PACK_ID); 89 TEST_NULL_ARG(SG_GET_PACK_ID); 90 TEST_NULL_ARG(SG_GET_NUM_WAITING); 91 TEST_NULL_ARG(SG_SET_DEBUG); 92 TEST_NULL_ARG(SG_GET_SG_TABLESIZE); 93 TEST_NULL_ARG(SG_GET_VERSION_NUM); 94 TEST_NULL_ARG(SG_NEXT_CMD_LEN); 95 TEST_NULL_ARG(SG_SCSI_RESET); 96 TEST_NULL_ARG(SG_IO); 97 TEST_NULL_ARG(SG_GET_REQUEST_TABLE); 98 TEST_NULL_ARG(SG_SET_KEEP_ORPHAN); 99 TEST_NULL_ARG(SG_GET_KEEP_ORPHAN); 100 TEST_NULL_ARG(SG_GET_ACCESS_COUNT); 101 102 TEST_TAKES_INT_BY_VAL(SG_SET_TRANSFORM, 0); 103 TEST_TAKES_INT_BY_VAL(SG_SET_TRANSFORM, *pint); 104 105 TEST_TAKES_INT_BY_PTR(SG_NEXT_CMD_LEN, pint); 106 TEST_TAKES_INT_BY_PTR(SG_SET_COMMAND_Q, pint); 107 TEST_TAKES_INT_BY_PTR(SG_SET_DEBUG, pint); 108 TEST_TAKES_INT_BY_PTR(SG_SET_FORCE_LOW_DMA, pint); 109 TEST_TAKES_INT_BY_PTR(SG_SET_FORCE_PACK_ID, pint); 110 TEST_TAKES_INT_BY_PTR(SG_SET_KEEP_ORPHAN, pint); 111 TEST_TAKES_INT_BY_PTR(SG_SET_RESERVED_SIZE, pint); 112 TEST_TAKES_INT_BY_PTR(SG_SET_TIMEOUT, pint); 113 114 TEST_RETURNS_INT_BY_PTR(SG_EMULATED_HOST, pint); 115 TEST_RETURNS_INT_BY_PTR(SG_GET_ACCESS_COUNT, pint); 116 TEST_RETURNS_INT_BY_PTR(SG_GET_COMMAND_Q, pint); 117 TEST_RETURNS_INT_BY_PTR(SG_GET_KEEP_ORPHAN, pint); 118 TEST_RETURNS_INT_BY_PTR(SG_GET_LOW_DMA, pint); 119 TEST_RETURNS_INT_BY_PTR(SG_GET_NUM_WAITING, pint); 120 TEST_RETURNS_INT_BY_PTR(SG_GET_PACK_ID, pint); 121 TEST_RETURNS_INT_BY_PTR(SG_GET_RESERVED_SIZE, pint); 122 TEST_RETURNS_INT_BY_PTR(SG_GET_SG_TABLESIZE, pint); 123 TEST_RETURNS_INT_BY_PTR(SG_GET_TRANSFORM, pint); 124 TEST_RETURNS_INT_BY_PTR(SG_GET_VERSION_NUM, pint); 125 126 ioctl(-1, SG_SCSI_RESET, pint); 127 printf("ioctl(-1, %s, [%#x /* %s_??? */]) = -1 EBADF (%m)\n", 128 "SG_SCSI_RESET", *pint, "SG_SCSI_RESET"); 129 130 *pint = 0x100; 131 ioctl(-1, SG_SCSI_RESET, pint); 132 printf("ioctl(-1, %s, [SG_SCSI_RESET_NO_ESCALATE|SG_SCSI_RESET_NOTHING])" 133 " = -1 EBADF (%m)\n", "SG_SCSI_RESET"); 134 135 *pint = 1; 136 ioctl(-1, SG_SCSI_RESET, pint); 137 printf("ioctl(-1, %s, [SG_SCSI_RESET_DEVICE]) = -1 EBADF (%m)\n", 138 "SG_SCSI_RESET"); 139 140 ioctl(-1, 0x22ff, 0); 141 printf("ioctl(-1, _IOC(%s, 0x22, 0xff, 0), 0) = -1 EBADF (%m)\n", 142 _IOC_NONE ? "0" : "_IOC_NONE"); 143 144 static const unsigned long magic = 145 (unsigned long) 0xdeadbeeffacefeedULL; 146 ioctl(-1, 0x22ff, magic); 147 printf("ioctl(-1, _IOC(%s, 0x22, 0xff, 0), %#lx) = -1 EBADF (%m)\n", 148 _IOC_NONE ? "0" : "_IOC_NONE", magic); 149 150 puts("+++ exited with 0 +++"); 151 return 0; 152 } 153 154 #else 155 156 SKIP_MAIN_UNDEFINED("HAVE_SCSI_SG_H") 157 158 #endif 159