2 * Check decoding of ioctl SG_IO v3 commands.
4 * Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 # include <inttypes.h>
36 # include <sys/ioctl.h>
44 printf("ioctl(-1, SG_IO, NULL) = -1 EBADF (%m)\n");
46 TAIL_ALLOC_OBJECT_CONST_PTR(struct sg_io_hdr, sg_io);
47 fill_memory(sg_io, sizeof(*sg_io));
49 const void *const efault = sg_io + 1;
50 ioctl(-1, SG_IO, efault);
51 printf("ioctl(-1, SG_IO, %p) = -1 EBADF (%m)\n", efault);
53 ioctl(-1, SG_IO, sg_io);
54 printf("ioctl(-1, SG_IO, [%u]) = -1 EBADF (%m)\n", sg_io->interface_id);
56 TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, piid);
57 *piid = (unsigned char) 'S';
58 ioctl(-1, SG_IO, piid);
59 printf("ioctl(-1, SG_IO, {interface_id='S', %p}) = -1 EBADF (%m)\n", piid + 1);
61 sg_io->interface_id = (unsigned char) 'S';
62 sg_io->dxfer_direction = -2;
65 sg_io->dxferp = (void *) (unsigned long) 0xfacefeedfffffff1ULL;
66 sg_io->cmdp = (void *) (unsigned long) 0xfacefeedfffffff2ULL;
67 sg_io->sbp = (void *) (unsigned long) 0xfacefeedfffffff3ULL;
69 ioctl(-1, SG_IO, sg_io);
70 printf("ioctl(-1, SG_IO, {interface_id='S'"
71 ", dxfer_direction=SG_DXFER_TO_DEV"
78 ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT"
79 "|SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER"
80 "|SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8"
91 ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8"
92 "}) = -1 EBADF (%m)\n",
101 sg_io->masked_status,
106 sg_io->driver_status,
110 sg_io->dxfer_direction = -3;
112 ioctl(-1, SG_IO, sg_io);
113 printf("ioctl(-1, SG_IO, {interface_id='S'"
114 ", dxfer_direction=SG_DXFER_FROM_DEV"
121 ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT"
122 "|SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER"
123 "|SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8"
126 ", masked_status=%#x"
131 ", driver_status=%#x"
134 ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8"
135 "}) = -1 EBADF (%m)\n",
144 sg_io->masked_status,
149 sg_io->driver_status,
153 const struct iovec iov[] = {
155 .iov_base = (void *) efault - 2,
158 .iov_base = (void *) efault - 3,
162 struct iovec *const t_iov = tail_memdup(iov, sizeof(iov));
166 sg_io->dxfer_direction = -2;
168 sg_io->iovec_count = ARRAY_SIZE(iov);
169 sg_io->dxfer_len = iov[0].iov_len + iov[1].iov_len - 1;
170 sg_io->dxferp = t_iov;
172 ioctl(-1, SG_IO, sg_io);
173 printf("ioctl(-1, SG_IO, {interface_id='S'"
174 ", dxfer_direction=SG_DXFER_TO_DEV"
181 ", flags=SG_FLAG_MMAP_IO|SG_FLAG_Q_AT_HEAD"
182 ", dxferp=[{iov_base=\"\\%o\\%o\", iov_len=%u}"
183 ", {iov_base=\"\\%o\\%o\\%o\", iov_len=%u}]"
185 ", masked_status=%#x"
190 ", driver_status=%#x"
193 ", info=SG_INFO_CHECK"
194 "}) = -1 EBADF (%m)\n",
201 * (unsigned char *) (iov[0].iov_base + 0),
202 * (unsigned char *) (iov[0].iov_base + 1),
203 (unsigned int) iov[0].iov_len,
204 * (unsigned char *) (iov[1].iov_base + 0),
205 * (unsigned char *) (iov[1].iov_base + 1),
206 * (unsigned char *) (iov[1].iov_base + 2),
207 (unsigned int) iov[1].iov_len,
209 sg_io->masked_status,
214 sg_io->driver_status,
219 sg_io->dxfer_direction = -3;
220 sg_io->resid = sg_io->dxfer_len + 1;
222 ioctl(-1, SG_IO, sg_io);
223 printf("ioctl(-1, SG_IO, {interface_id='S'"
224 ", dxfer_direction=SG_DXFER_FROM_DEV"
231 ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_Q_AT_TAIL"
232 ", dxferp=[{iov_base=\"\\%o\\%o\", iov_len=%u}"
233 ", {iov_base=\"\\%o\\%o\\%o\", iov_len=%u}]"
235 ", masked_status=%#x"
240 ", driver_status=%#x"
243 ", info=SG_INFO_CHECK"
244 "}) = -1 EBADF (%m)\n",
251 * (unsigned char *) (iov[0].iov_base + 0),
252 * (unsigned char *) (iov[0].iov_base + 1),
253 (unsigned int) iov[0].iov_len,
254 * (unsigned char *) (iov[1].iov_base + 0),
255 * (unsigned char *) (iov[1].iov_base + 1),
256 * (unsigned char *) (iov[1].iov_base + 2),
257 (unsigned int) iov[1].iov_len,
259 sg_io->masked_status,
264 sg_io->driver_status,
268 sg_io->flags = 0x10000;
269 sg_io->info = 0xdeadbeef;
270 sg_io->iovec_count = 0;
271 sg_io->dxfer_len = 5;
273 sg_io->dxferp = (void *) efault - (sg_io->dxfer_len - sg_io->resid);
275 ioctl(-1, SG_IO, sg_io);
276 printf("ioctl(-1, SG_IO, {interface_id='S'"
277 ", dxfer_direction=SG_DXFER_FROM_DEV"
284 ", flags=SG_FLAG_NO_DXFER"
285 ", dxferp=\"\\x%x\\x%x\\x%x\\x%x\""
287 ", masked_status=%#x"
292 ", driver_status=%#x"
295 ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
296 "}) = -1 EBADF (%m)\n",
303 * (unsigned char *) (sg_io->dxferp + 0),
304 * (unsigned char *) (sg_io->dxferp + 1),
305 * (unsigned char *) (sg_io->dxferp + 2),
306 * (unsigned char *) (sg_io->dxferp + 3),
308 sg_io->masked_status,
313 sg_io->driver_status,
318 sg_io->dxfer_direction = -4;
319 sg_io->dxfer_len = 3;
321 sg_io->dxferp = (void *) efault - sg_io->dxfer_len;
323 ioctl(-1, SG_IO, sg_io);
324 printf("ioctl(-1, SG_IO, {interface_id='S'"
325 ", dxfer_direction=SG_DXFER_TO_FROM_DEV"
332 ", flags=SG_FLAG_UNUSED_LUN_INHIBIT"
333 ", dxferp=\"\\x%x\\x%x\\x%x\" => dxferp=\"\\x%x\\x%x\""
335 ", masked_status=%#x"
340 ", driver_status=%#x"
343 ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
344 "}) = -1 EBADF (%m)\n",
351 * (unsigned char *) (sg_io->dxferp + 0),
352 * (unsigned char *) (sg_io->dxferp + 1),
353 * (unsigned char *) (sg_io->dxferp + 2),
354 * (unsigned char *) (sg_io->dxferp + 0),
355 * (unsigned char *) (sg_io->dxferp + 1),
357 sg_io->masked_status,
362 sg_io->driver_status,
367 sg_io->resid = sg_io->dxfer_len;
369 ioctl(-1, SG_IO, sg_io);
370 printf("ioctl(-1, SG_IO, {interface_id='S'"
371 ", dxfer_direction=SG_DXFER_TO_FROM_DEV"
379 ", dxferp=\"\\x%x\\x%x\\x%x\""
381 ", masked_status=%#x"
386 ", driver_status=%#x"
389 ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
390 "}) = -1 EBADF (%m)\n",
397 * (unsigned char *) (sg_io->dxferp + 0),
398 * (unsigned char *) (sg_io->dxferp + 1),
399 * (unsigned char *) (sg_io->dxferp + 2),
401 sg_io->masked_status,
406 sg_io->driver_status,
410 puts("+++ exited with 0 +++");
416 SKIP_MAIN_UNDEFINED("HAVE_SCSI_SG_H")