github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/mount/scuzz/sg_linux_test.go (about)

     1  // Copyright 2019 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build amd64
     6  // +build amd64
     7  
     8  package scuzz
     9  
    10  import (
    11  	"testing"
    12  	"unsafe"
    13  )
    14  
    15  // check checks the packetHeader, cdb, and sb.
    16  // The packetHeader check is a bit complex as it contains
    17  // pointers. The pointer values for the original executiion of hdparm
    18  // will not match the values we get for this test. We therefore skip any uintptrs.
    19  func check(t *testing.T, got *packet, want *packet) {
    20  	if got.interfaceID != want.interfaceID {
    21  		t.Errorf("interfaceID: got %v, want %v", got.interfaceID, want.interfaceID)
    22  	}
    23  	if got.direction != want.direction {
    24  		t.Errorf("direction: got %v, want %v", got.direction, want.direction)
    25  	}
    26  	if got.cmdLen != want.cmdLen {
    27  		t.Errorf("cmdLen: got %v, want %v", got.cmdLen, want.cmdLen)
    28  	}
    29  	if got.maxStatusBlockLen != want.maxStatusBlockLen {
    30  		t.Errorf("maxStatusBlockLen: got %v, want %v", got.maxStatusBlockLen, want.maxStatusBlockLen)
    31  	}
    32  	if got.iovCount != want.iovCount {
    33  		t.Errorf("iovCount: got %v, want %v", got.iovCount, want.iovCount)
    34  	}
    35  	if got.dataLen != want.dataLen {
    36  		t.Errorf("dataLen: got %v, want %v", got.dataLen, want.dataLen)
    37  	}
    38  	if got.timeout != want.timeout {
    39  		t.Errorf("timeout: got %v, want %v", got.timeout, want.timeout)
    40  	}
    41  	if got.flags != want.flags {
    42  		t.Errorf("flags: got %v, want %v", got.flags, want.flags)
    43  	}
    44  	if got.packID != want.packID {
    45  		t.Errorf("packID: got %v, want %v", got.packID, want.packID)
    46  	}
    47  	if got.status != want.status {
    48  		t.Errorf("status: got %v, want %v", got.status, want.status)
    49  	}
    50  	if got.maskedStatus != want.maskedStatus {
    51  		t.Errorf("maskedStatus: got %v, want %v", got.maskedStatus, want.maskedStatus)
    52  	}
    53  	if got.msgStatus != want.msgStatus {
    54  		t.Errorf("msgStatus: got %v, want %v", got.msgStatus, want.msgStatus)
    55  	}
    56  	if got.sbLen != want.sbLen {
    57  		t.Errorf("sbLen: got %v, want %v", got.sbLen, want.sbLen)
    58  	}
    59  	if got.hostStatus != want.hostStatus {
    60  		t.Errorf("hostStatus: got %v, want %v", got.hostStatus, want.hostStatus)
    61  	}
    62  	if got.driverStatus != want.driverStatus {
    63  		t.Errorf("driverStatus: got %v, want %v", got.driverStatus, want.driverStatus)
    64  	}
    65  	if got.resID != want.resID {
    66  		t.Errorf("resID: got %v, want %v", got.resID, want.resID)
    67  	}
    68  	if got.duration != want.duration {
    69  		t.Errorf("duration: got %v, want %v", got.duration, want.duration)
    70  	}
    71  	if got.info != want.info {
    72  		t.Errorf("info: got %v, want %v", got.info, want.info)
    73  	}
    74  
    75  	for i := range got.command {
    76  		if got.command[i] != want.command[i] {
    77  			t.Errorf("command[%d]: got %#02x, want %#02x", i, got.command[i], want.command[i])
    78  		}
    79  	}
    80  
    81  	for i := range got.block {
    82  		if got.block[i] != want.block[i] {
    83  			t.Errorf("cblock[%d]: got %#02x, want %#02x", i, got.block[i], want.block[i])
    84  		}
    85  	}
    86  }
    87  
    88  // TestSizes makes sure that everything marshals to the right size.
    89  // The sizes are magic numbers from Linux. Thanks to the compatibility
    90  // guarantee, we know they don't change.
    91  func TestSizes(t *testing.T) {
    92  	hs := unsafe.Sizeof(packetHeader{})
    93  	if hs != hdrSize {
    94  		t.Errorf("PacketHeader.Marshal(): got %d, want %d", hs, hdrSize)
    95  	}
    96  	l := len(&commandDataBlock{})
    97  	if l != cdbSize {
    98  		t.Errorf("commandDataBlock.Marshal(): got %d, want %d", l, cdbSize)
    99  	}
   100  	l = len(&statusBlock{})
   101  	if l != maxStatusBlockLen {
   102  		t.Errorf("sbsize: got %d, want %d", l, maxStatusBlockLen)
   103  	}
   104  }
   105  
   106  func TestUnlock(t *testing.T) {
   107  	Debug = t.Logf
   108  	// This command: ./hdparm --security-unlock 12345678901234567890123456789012 /dev/null
   109  	// yields this header and data to ioctl(fd, SECURITY_UNLOCK, ...)
   110  	// The 'want' data is derived from a modified version of hdparm (github.com/rminnich/hdparmm)
   111  	// which prints the ioctl parameters as initialized go structs.
   112  
   113  	want := &packet{
   114  		packetHeader: packetHeader{
   115  			interfaceID:       'S',
   116  			direction:         -2,
   117  			cmdLen:            16,
   118  			maxStatusBlockLen: 32,
   119  			iovCount:          0,
   120  			dataLen:           512,
   121  			data:              0,
   122  			cdb:               0,
   123  			sb:                0,
   124  			timeout:           15000,
   125  			flags:             0,
   126  			packID:            0,
   127  			usrPtr:            0,
   128  			status:            0,
   129  			maskedStatus:      0,
   130  			msgStatus:         0,
   131  			sbLen:             0,
   132  			hostStatus:        0,
   133  			driverStatus:      0,
   134  			resID:             0,
   135  			duration:          0,
   136  			info:              0,
   137  		},
   138  		command: commandDataBlock{0x85, 0xb, 0x6, 0o0, 0o0, 0o0, 0x1, 0o0, 0o0, 0o0, 0o0, 0o0, 0o0, 0x40, 0xf2, 0o0},
   139  		block: dataBlock{
   140  			0x00, 0x01, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34,
   141  			0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
   142  			0x31, 0x32,
   143  		},
   144  	}
   145  	// sb statusBlock
   146  
   147  	d := &SGDisk{dev: 0x40, Timeout: DefaultTimeout}
   148  	p := d.unlockPacket("12345678901234567890123456789012", true)
   149  	check(t, p, want)
   150  }
   151  
   152  func TestIdentify(t *testing.T) {
   153  	Debug = t.Logf
   154  	// The 'want' data is derived from a modified version of hdparm (github.com/rminnich/hdparmm)
   155  	// which prints the ioctl parameters as initialized go structs.
   156  
   157  	want := &packet{
   158  		packetHeader: packetHeader{
   159  			interfaceID:       'S',
   160  			direction:         -3,
   161  			cmdLen:            16,
   162  			maxStatusBlockLen: 32,
   163  			iovCount:          0,
   164  			dataLen:           512,
   165  			data:              0,
   166  			cdb:               0,
   167  			sb:                0,
   168  			timeout:           15000,
   169  			flags:             0,
   170  			packID:            0,
   171  			usrPtr:            0,
   172  			status:            0,
   173  			maskedStatus:      0,
   174  			msgStatus:         0,
   175  			sbLen:             0,
   176  			hostStatus:        0,
   177  			driverStatus:      0,
   178  			resID:             0,
   179  			duration:          0,
   180  			info:              0,
   181  		},
   182  		command: commandDataBlock{0x85, 0x08, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xec, 0x00},
   183  	}
   184  	// TODO: check status block. Requires a qemu device that supports these operations.
   185  	// sb = statusBlock{0x70, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
   186  
   187  	p := (&SGDisk{dev: 0x40, Timeout: DefaultTimeout}).identifyPacket()
   188  	check(t, p, want)
   189  }