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 }