From: Dmitry V. Levin Date: Mon, 9 Jan 2017 00:22:42 +0000 (+0000) Subject: tests: check decoding of ioctl SG_IO v3 commands X-Git-Tag: v4.16~58 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6b39e463b60396b09f512a516940ddfb893cfa2e;p=strace tests: check decoding of ioctl SG_IO v3 commands * tests/ioctl_sg_io_v3.c: New file. * tests/ioctl_sg_io_v3.test: New test. * tests/.gitignore: Add ioctl_sg_io_v3. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add ioctl_sg_io_v3.test. --- diff --git a/tests/.gitignore b/tests/.gitignore index b164078a..98d5d6b7 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -124,6 +124,7 @@ ioctl_loop-v ioctl_mtd ioctl_rtc ioctl_rtc-v +ioctl_sg_io_v3 ioctl_sg_io_v4 ioctl_sock_gifconf ioctl_uffdio diff --git a/tests/Makefile.am b/tests/Makefile.am index 66c8e1b9..151773b8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -185,6 +185,7 @@ check_PROGRAMS = \ ioctl_mtd \ ioctl_rtc \ ioctl_rtc-v \ + ioctl_sg_io_v3 \ ioctl_sg_io_v4 \ ioctl_sock_gifconf \ ioctl_uffdio \ @@ -585,6 +586,7 @@ DECODER_TESTS = \ ioctl_mtd.test \ ioctl_rtc.test \ ioctl_rtc-v.test \ + ioctl_sg_io_v3.test \ ioctl_sg_io_v4.test \ ioctl_sock_gifconf.test \ ioctl_uffdio.test \ diff --git a/tests/ioctl_sg_io_v3.c b/tests/ioctl_sg_io_v3.c new file mode 100644 index 00000000..ef25795b --- /dev/null +++ b/tests/ioctl_sg_io_v3.c @@ -0,0 +1,418 @@ +/* + * Check decoding of ioctl SG_IO v3 commands. + * + * Copyright (c) 2017 Dmitry V. Levin + * 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 +# include +# include +# include +# include + +int +main(void) +{ + ioctl(-1, SG_IO, 0); + printf("ioctl(-1, SG_IO, NULL) = -1 EBADF (%m)\n"); + + struct sg_io_hdr *const sg_io = tail_alloc(sizeof(*sg_io)); + 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); + + unsigned int *const piid = tail_alloc(sizeof(*piid)); + *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, + * (unsigned char *) (iov[0].iov_base + 0), + * (unsigned char *) (iov[0].iov_base + 1), + (unsigned int) iov[0].iov_len, + * (unsigned char *) (iov[1].iov_base + 0), + * (unsigned char *) (iov[1].iov_base + 1), + * (unsigned char *) (iov[1].iov_base + 2), + (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, + * (unsigned char *) (iov[0].iov_base + 0), + * (unsigned char *) (iov[0].iov_base + 1), + (unsigned int) iov[0].iov_len, + * (unsigned char *) (iov[1].iov_base + 0), + * (unsigned char *) (iov[1].iov_base + 1), + * (unsigned char *) (iov[1].iov_base + 2), + (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, + * (unsigned char *) (sg_io->dxferp + 0), + * (unsigned char *) (sg_io->dxferp + 1), + * (unsigned char *) (sg_io->dxferp + 2), + * (unsigned char *) (sg_io->dxferp + 3), + 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, + * (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), + 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, + * (unsigned char *) (sg_io->dxferp + 0), + * (unsigned char *) (sg_io->dxferp + 1), + * (unsigned char *) (sg_io->dxferp + 2), + 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 diff --git a/tests/ioctl_sg_io_v3.test b/tests/ioctl_sg_io_v3.test new file mode 100755 index 00000000..dacacdf4 --- /dev/null +++ b/tests/ioctl_sg_io_v3.test @@ -0,0 +1,4 @@ +#!/bin/sh + +# Check decoding of ioctl SG_IO v3 commands. +. "${srcdir=.}/ioctl.test"