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