(root)/
strace-6.5/
tests/
ioctl_sg_io_v3.c
       1  /*
       2   * Check decoding of ioctl SG_IO v3 commands.
       3   *
       4   * Copyright (c) 2017-2021 Dmitry V. Levin <ldv@strace.io>
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  
      12  #ifdef HAVE_SCSI_SG_H
      13  
      14  # include <inttypes.h>
      15  # include <stdio.h>
      16  # include <sys/ioctl.h>
      17  # include <sys/uio.h>
      18  # include <scsi/sg.h>
      19  
      20  int
      21  main(void)
      22  {
      23  	ioctl(-1, SG_IO, 0);
      24  	printf("ioctl(-1, SG_IO, NULL) = -1 EBADF (%m)\n");
      25  
      26  	TAIL_ALLOC_OBJECT_CONST_PTR(struct sg_io_hdr, sg_io);
      27  	fill_memory(sg_io, sizeof(*sg_io));
      28  
      29  	const void *const efault = sg_io + 1;
      30  	ioctl(-1, SG_IO, efault);
      31  	printf("ioctl(-1, SG_IO, %p) = -1 EBADF (%m)\n", efault);
      32  
      33  	ioctl(-1, SG_IO, sg_io);
      34  	printf("ioctl(-1, SG_IO, [%u]) = -1 EBADF (%m)\n", sg_io->interface_id);
      35  
      36  	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, piid);
      37  	*piid = (unsigned char) 'S';
      38  	ioctl(-1, SG_IO, piid);
      39  	printf("ioctl(-1, SG_IO, {interface_id='S', %p}) = -1 EBADF (%m)\n", piid + 1);
      40  
      41  	sg_io->interface_id = (unsigned char) 'S';
      42  	sg_io->dxfer_direction = -2;
      43  	sg_io->flags = -1U;
      44  	sg_io->info = -1U;
      45  	sg_io->dxferp = (void *) (unsigned long) 0xfacefeedfffffff1ULL;
      46  	sg_io->cmdp = (void *) (unsigned long) 0xfacefeedfffffff2ULL;
      47  	sg_io->sbp = (void *) (unsigned long) 0xfacefeedfffffff3ULL;
      48  
      49  	ioctl(-1, SG_IO, sg_io);
      50  	printf("ioctl(-1, SG_IO, {interface_id='S'"
      51  	       ", dxfer_direction=SG_DXFER_TO_DEV"
      52  	       ", cmd_len=%u"
      53  	       ", cmdp=%p"
      54  	       ", mx_sb_len=%u"
      55  	       ", iovec_count=%u"
      56  	       ", dxfer_len=%u"
      57  	       ", timeout=%u"
      58  	       ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT"
      59  	       "|SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER"
      60  	       "|SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8"
      61  	       ", dxferp=%p"
      62  	       ", status=%#x"
      63  	       ", masked_status=%#x"
      64  	       ", msg_status=%#x"
      65  	       ", sb_len_wr=%u"
      66  	       ", sbp=%p"
      67  	       ", host_status=%#x"
      68  	       ", driver_status=%#x"
      69  	       ", resid=%d"
      70  	       ", duration=%u"
      71  	       ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8"
      72  	       "}) = -1 EBADF (%m)\n",
      73  	       sg_io->cmd_len,
      74  	       sg_io->cmdp,
      75  	       sg_io->mx_sb_len,
      76  	       sg_io->iovec_count,
      77  	       sg_io->dxfer_len,
      78  	       sg_io->timeout,
      79  	       sg_io->dxferp,
      80  	       sg_io->status,
      81  	       sg_io->masked_status,
      82  	       sg_io->msg_status,
      83  	       sg_io->sb_len_wr,
      84  	       sg_io->sbp,
      85  	       sg_io->host_status,
      86  	       sg_io->driver_status,
      87  	       sg_io->resid,
      88  	       sg_io->duration);
      89  
      90  	sg_io->dxfer_direction = -3;
      91  
      92  	ioctl(-1, SG_IO, sg_io);
      93  	printf("ioctl(-1, SG_IO, {interface_id='S'"
      94  	       ", dxfer_direction=SG_DXFER_FROM_DEV"
      95  	       ", cmd_len=%u"
      96  	       ", cmdp=%p"
      97  	       ", mx_sb_len=%u"
      98  	       ", iovec_count=%u"
      99  	       ", dxfer_len=%u"
     100  	       ", timeout=%u"
     101  	       ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_UNUSED_LUN_INHIBIT"
     102  	       "|SG_FLAG_MMAP_IO|SG_FLAG_NO_DXFER"
     103  	       "|SG_FLAG_Q_AT_TAIL|SG_FLAG_Q_AT_HEAD|0xfffeffc8"
     104  	       ", dxferp=%p"
     105  	       ", status=%#x"
     106  	       ", masked_status=%#x"
     107  	       ", msg_status=%#x"
     108  	       ", sb_len_wr=%u"
     109  	       ", sbp=%p"
     110  	       ", host_status=%#x"
     111  	       ", driver_status=%#x"
     112  	       ", resid=%d"
     113  	       ", duration=%u"
     114  	       ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xfffffff8"
     115  	       "}) = -1 EBADF (%m)\n",
     116  	       sg_io->cmd_len,
     117  	       sg_io->cmdp,
     118  	       sg_io->mx_sb_len,
     119  	       sg_io->iovec_count,
     120  	       sg_io->dxfer_len,
     121  	       sg_io->timeout,
     122  	       sg_io->dxferp,
     123  	       sg_io->status,
     124  	       sg_io->masked_status,
     125  	       sg_io->msg_status,
     126  	       sg_io->sb_len_wr,
     127  	       sg_io->sbp,
     128  	       sg_io->host_status,
     129  	       sg_io->driver_status,
     130  	       sg_io->resid,
     131  	       sg_io->duration);
     132  
     133  	const struct iovec iov[] = {
     134  		{
     135  			.iov_base = (void *) efault - 2,
     136  			.iov_len = 2
     137  		}, {
     138  			.iov_base = (void *) efault - 3,
     139  			.iov_len = 4
     140  		}
     141  	};
     142  	struct iovec *const t_iov = tail_memdup(iov, sizeof(iov));
     143  
     144  	sg_io->flags = 0x24;
     145  	sg_io->info = 1;
     146  	sg_io->dxfer_direction = -2;
     147  
     148  	sg_io->iovec_count = ARRAY_SIZE(iov);
     149  	sg_io->dxfer_len = iov[0].iov_len + iov[1].iov_len - 1;
     150  	sg_io->dxferp = t_iov;
     151  
     152  	ioctl(-1, SG_IO, sg_io);
     153  	printf("ioctl(-1, SG_IO, {interface_id='S'"
     154  	       ", dxfer_direction=SG_DXFER_TO_DEV"
     155  	       ", cmd_len=%u"
     156  	       ", cmdp=%p"
     157  	       ", mx_sb_len=%u"
     158  	       ", iovec_count=%u"
     159  	       ", dxfer_len=%u"
     160  	       ", timeout=%u"
     161  	       ", flags=SG_FLAG_MMAP_IO|SG_FLAG_Q_AT_HEAD"
     162  	       ", dxferp=[{iov_base=\"\\%o\\%o\", iov_len=%u}"
     163  	       ", {iov_base=\"\\%o\\%o\\%o\", iov_len=%u}]"
     164  	       ", status=%#x"
     165  	       ", masked_status=%#x"
     166  	       ", msg_status=%#x"
     167  	       ", sb_len_wr=%u"
     168  	       ", sbp=%p"
     169  	       ", host_status=%#x"
     170  	       ", driver_status=%#x"
     171  	       ", resid=%d"
     172  	       ", duration=%u"
     173  	       ", info=SG_INFO_CHECK"
     174  	       "}) = -1 EBADF (%m)\n",
     175  	       sg_io->cmd_len,
     176  	       sg_io->cmdp,
     177  	       sg_io->mx_sb_len,
     178  	       sg_io->iovec_count,
     179  	       sg_io->dxfer_len,
     180  	       sg_io->timeout,
     181  	       *(unsigned char *) (iov[0].iov_base + 0),
     182  	       *(unsigned char *) (iov[0].iov_base + 1),
     183  	       (unsigned int) iov[0].iov_len,
     184  	       *(unsigned char *) (iov[1].iov_base + 0),
     185  	       *(unsigned char *) (iov[1].iov_base + 1),
     186  	       *(unsigned char *) (iov[1].iov_base + 2),
     187  	       (unsigned int) iov[1].iov_len,
     188  	       sg_io->status,
     189  	       sg_io->masked_status,
     190  	       sg_io->msg_status,
     191  	       sg_io->sb_len_wr,
     192  	       sg_io->sbp,
     193  	       sg_io->host_status,
     194  	       sg_io->driver_status,
     195  	       sg_io->resid,
     196  	       sg_io->duration);
     197  
     198  	sg_io->flags = 0x11;
     199  	sg_io->dxfer_direction = -3;
     200  	sg_io->resid = sg_io->dxfer_len + 1;
     201  
     202  	ioctl(-1, SG_IO, sg_io);
     203  	printf("ioctl(-1, SG_IO, {interface_id='S'"
     204  	       ", dxfer_direction=SG_DXFER_FROM_DEV"
     205  	       ", cmd_len=%u"
     206  	       ", cmdp=%p"
     207  	       ", mx_sb_len=%u"
     208  	       ", iovec_count=%u"
     209  	       ", dxfer_len=%u"
     210  	       ", timeout=%u"
     211  	       ", flags=SG_FLAG_DIRECT_IO|SG_FLAG_Q_AT_TAIL"
     212  	       ", dxferp=[{iov_base=\"\\%o\\%o\", iov_len=%u}"
     213  	       ", {iov_base=\"\\%o\\%o\\%o\", iov_len=%u}]"
     214  	       ", status=%#x"
     215  	       ", masked_status=%#x"
     216  	       ", msg_status=%#x"
     217  	       ", sb_len_wr=%u"
     218  	       ", sbp=%p"
     219  	       ", host_status=%#x"
     220  	       ", driver_status=%#x"
     221  	       ", resid=%d"
     222  	       ", duration=%u"
     223  	       ", info=SG_INFO_CHECK"
     224  	       "}) = -1 EBADF (%m)\n",
     225  	       sg_io->cmd_len,
     226  	       sg_io->cmdp,
     227  	       sg_io->mx_sb_len,
     228  	       sg_io->iovec_count,
     229  	       sg_io->dxfer_len,
     230  	       sg_io->timeout,
     231  	       *(unsigned char *) (iov[0].iov_base + 0),
     232  	       *(unsigned char *) (iov[0].iov_base + 1),
     233  	       (unsigned int) iov[0].iov_len,
     234  	       *(unsigned char *) (iov[1].iov_base + 0),
     235  	       *(unsigned char *) (iov[1].iov_base + 1),
     236  	       *(unsigned char *) (iov[1].iov_base + 2),
     237  	       (unsigned int) iov[1].iov_len,
     238  	       sg_io->status,
     239  	       sg_io->masked_status,
     240  	       sg_io->msg_status,
     241  	       sg_io->sb_len_wr,
     242  	       sg_io->sbp,
     243  	       sg_io->host_status,
     244  	       sg_io->driver_status,
     245  	       sg_io->resid,
     246  	       sg_io->duration);
     247  
     248  	sg_io->flags = 0x10000;
     249  	sg_io->info = 0xdeadbeef;
     250  	sg_io->iovec_count = 0;
     251  	sg_io->dxfer_len = 5;
     252  	sg_io->resid = 1;
     253  	sg_io->dxferp = (void *) efault - (sg_io->dxfer_len - sg_io->resid);
     254  
     255  	ioctl(-1, SG_IO, sg_io);
     256  	printf("ioctl(-1, SG_IO, {interface_id='S'"
     257  	       ", dxfer_direction=SG_DXFER_FROM_DEV"
     258  	       ", cmd_len=%u"
     259  	       ", cmdp=%p"
     260  	       ", mx_sb_len=%u"
     261  	       ", iovec_count=%u"
     262  	       ", dxfer_len=%u"
     263  	       ", timeout=%u"
     264  	       ", flags=SG_FLAG_NO_DXFER"
     265  	       ", dxferp=\"\\x%x\\x%x\\x%x\\x%x\""
     266  	       ", status=%#x"
     267  	       ", masked_status=%#x"
     268  	       ", msg_status=%#x"
     269  	       ", sb_len_wr=%u"
     270  	       ", sbp=%p"
     271  	       ", host_status=%#x"
     272  	       ", driver_status=%#x"
     273  	       ", resid=%d"
     274  	       ", duration=%u"
     275  	       ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
     276  	       "}) = -1 EBADF (%m)\n",
     277  	       sg_io->cmd_len,
     278  	       sg_io->cmdp,
     279  	       sg_io->mx_sb_len,
     280  	       sg_io->iovec_count,
     281  	       sg_io->dxfer_len,
     282  	       sg_io->timeout,
     283  	       *(unsigned char *) (sg_io->dxferp + 0),
     284  	       *(unsigned char *) (sg_io->dxferp + 1),
     285  	       *(unsigned char *) (sg_io->dxferp + 2),
     286  	       *(unsigned char *) (sg_io->dxferp + 3),
     287  	       sg_io->status,
     288  	       sg_io->masked_status,
     289  	       sg_io->msg_status,
     290  	       sg_io->sb_len_wr,
     291  	       sg_io->sbp,
     292  	       sg_io->host_status,
     293  	       sg_io->driver_status,
     294  	       sg_io->resid,
     295  	       sg_io->duration);
     296  
     297  	sg_io->flags = 2;
     298  	sg_io->dxfer_direction = -4;
     299  	sg_io->dxfer_len = 3;
     300  	sg_io->resid = 1;
     301  	sg_io->dxferp = (void *) efault - sg_io->dxfer_len;
     302  
     303  	ioctl(-1, SG_IO, sg_io);
     304  	printf("ioctl(-1, SG_IO, {interface_id='S'"
     305  	       ", dxfer_direction=SG_DXFER_TO_FROM_DEV"
     306  	       ", cmd_len=%u"
     307  	       ", cmdp=%p"
     308  	       ", mx_sb_len=%u"
     309  	       ", iovec_count=%u"
     310  	       ", dxfer_len=%u"
     311  	       ", timeout=%u"
     312  	       ", flags=SG_FLAG_UNUSED_LUN_INHIBIT"
     313  	       ", dxferp=\"\\x%x\\x%x\\x%x\" => dxferp=\"\\x%x\\x%x\""
     314  	       ", status=%#x"
     315  	       ", masked_status=%#x"
     316  	       ", msg_status=%#x"
     317  	       ", sb_len_wr=%u"
     318  	       ", sbp=%p"
     319  	       ", host_status=%#x"
     320  	       ", driver_status=%#x"
     321  	       ", resid=%d"
     322  	       ", duration=%u"
     323  	       ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
     324  	       "}) = -1 EBADF (%m)\n",
     325  	       sg_io->cmd_len,
     326  	       sg_io->cmdp,
     327  	       sg_io->mx_sb_len,
     328  	       sg_io->iovec_count,
     329  	       sg_io->dxfer_len,
     330  	       sg_io->timeout,
     331  	       *(unsigned char *) (sg_io->dxferp + 0),
     332  	       *(unsigned char *) (sg_io->dxferp + 1),
     333  	       *(unsigned char *) (sg_io->dxferp + 2),
     334  	       *(unsigned char *) (sg_io->dxferp + 0),
     335  	       *(unsigned char *) (sg_io->dxferp + 1),
     336  	       sg_io->status,
     337  	       sg_io->masked_status,
     338  	       sg_io->msg_status,
     339  	       sg_io->sb_len_wr,
     340  	       sg_io->sbp,
     341  	       sg_io->host_status,
     342  	       sg_io->driver_status,
     343  	       sg_io->resid,
     344  	       sg_io->duration);
     345  
     346  	sg_io->flags = 0;
     347  	sg_io->resid = sg_io->dxfer_len;
     348  
     349  	ioctl(-1, SG_IO, sg_io);
     350  	printf("ioctl(-1, SG_IO, {interface_id='S'"
     351  	       ", dxfer_direction=SG_DXFER_TO_FROM_DEV"
     352  	       ", cmd_len=%u"
     353  	       ", cmdp=%p"
     354  	       ", mx_sb_len=%u"
     355  	       ", iovec_count=%u"
     356  	       ", dxfer_len=%u"
     357  	       ", timeout=%u"
     358  	       ", flags=0"
     359  	       ", dxferp=\"\\x%x\\x%x\\x%x\""
     360  	       ", status=%#x"
     361  	       ", masked_status=%#x"
     362  	       ", msg_status=%#x"
     363  	       ", sb_len_wr=%u"
     364  	       ", sbp=%p"
     365  	       ", host_status=%#x"
     366  	       ", driver_status=%#x"
     367  	       ", resid=%d"
     368  	       ", duration=%u"
     369  	       ", info=SG_INFO_CHECK|SG_INFO_DIRECT_IO|SG_INFO_MIXED_IO|0xdeadbee8"
     370  	       "}) = -1 EBADF (%m)\n",
     371  	       sg_io->cmd_len,
     372  	       sg_io->cmdp,
     373  	       sg_io->mx_sb_len,
     374  	       sg_io->iovec_count,
     375  	       sg_io->dxfer_len,
     376  	       sg_io->timeout,
     377  	       *(unsigned char *) (sg_io->dxferp + 0),
     378  	       *(unsigned char *) (sg_io->dxferp + 1),
     379  	       *(unsigned char *) (sg_io->dxferp + 2),
     380  	       sg_io->status,
     381  	       sg_io->masked_status,
     382  	       sg_io->msg_status,
     383  	       sg_io->sb_len_wr,
     384  	       sg_io->sbp,
     385  	       sg_io->host_status,
     386  	       sg_io->driver_status,
     387  	       sg_io->resid,
     388  	       sg_io->duration);
     389  
     390  	puts("+++ exited with 0 +++");
     391  	return 0;
     392  }
     393  
     394  #else
     395  
     396  SKIP_MAIN_UNDEFINED("HAVE_SCSI_SG_H")
     397  
     398  #endif