github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+incompatible/pkg/strace/socket.go (about) 1 // Copyright 2018 Google LLC. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package strace 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/u-root/u-root/pkg/strace/internal/abi" 22 "github.com/u-root/u-root/pkg/strace/internal/binary" 23 "golang.org/x/sys/unix" 24 ) 25 26 func cmsghdr(t *Tracer, addr Addr, length uint64, maxBytes uint64) string { 27 if length > maxBytes { 28 return fmt.Sprintf("%#x (error decoding control: invalid length (%d))", addr, length) 29 } 30 31 buf := make([]byte, length) 32 if _, err := t.Read(addr, &buf); err != nil { 33 return fmt.Sprintf("%#x (error decoding control: %v)", addr, err) 34 } 35 36 var strs []string 37 38 for i := 0; i < len(buf); { 39 if i+abi.SizeOfControlMessageHeader > len(buf) { 40 strs = append(strs, "{invalid control message (too short)}") 41 break 42 } 43 44 var h abi.ControlMessageHeader 45 binary.Unmarshal(buf[i:i+abi.SizeOfControlMessageHeader], ByteOrder, &h) 46 47 var skipData bool 48 level := "SOL_SOCKET" 49 if h.Level != unix.SOL_SOCKET { 50 skipData = true 51 level = fmt.Sprint(h.Level) 52 } 53 54 typ, ok := abi.ControlMessageType[h.Type] 55 if !ok { 56 skipData = true 57 typ = fmt.Sprint(h.Type) 58 } 59 60 if h.Length > uint64(len(buf)-i) { 61 strs = append(strs, fmt.Sprintf( 62 "{level=%s, type=%s, length=%d, content extends beyond buffer}", 63 level, 64 typ, 65 h.Length, 66 )) 67 break 68 } 69 70 i += abi.SizeOfControlMessageHeader 71 width := Width 72 length := int(h.Length) - abi.SizeOfControlMessageHeader 73 74 if skipData { 75 strs = append(strs, fmt.Sprintf("{level=%s, type=%s, length=%d}", level, typ, h.Length)) 76 i += AlignUp(length, uint(width)) 77 continue 78 } 79 80 switch h.Type { 81 case unix.SCM_RIGHTS: 82 rightsSize := AlignDown(length, abi.SizeOfControlMessageRight) 83 84 numRights := rightsSize / abi.SizeOfControlMessageRight 85 fds := make(abi.ControlMessageRights, numRights) 86 binary.Unmarshal(buf[i:i+rightsSize], ByteOrder, &fds) 87 88 rights := make([]string, 0, len(fds)) 89 for _, fd := range fds { 90 rights = append(rights, fmt.Sprint(fd)) 91 } 92 93 strs = append(strs, fmt.Sprintf( 94 "{level=%s, type=%s, length=%d, content: %s}", 95 level, 96 typ, 97 h.Length, 98 strings.Join(rights, ","), 99 )) 100 101 case unix.SCM_CREDENTIALS: 102 if length < abi.SizeOfControlMessageCredentials { 103 strs = append(strs, fmt.Sprintf( 104 "{level=%s, type=%s, length=%d, content too short}", 105 level, 106 typ, 107 h.Length, 108 )) 109 break 110 } 111 112 var creds abi.ControlMessageCredentials 113 binary.Unmarshal(buf[i:i+abi.SizeOfControlMessageCredentials], binary.LittleEndian, &creds) 114 115 strs = append(strs, fmt.Sprintf( 116 "{level=%s, type=%s, length=%d, pid: %d, uid: %d, gid: %d}", 117 level, 118 typ, 119 h.Length, 120 creds.PID, 121 creds.UID, 122 creds.GID, 123 )) 124 125 case unix.SO_TIMESTAMP: 126 if length < abi.SizeOfTimeval { 127 strs = append(strs, fmt.Sprintf( 128 "{level=%s, type=%s, length=%d, content too short}", 129 level, 130 typ, 131 h.Length, 132 )) 133 break 134 } 135 136 var tv unix.Timeval 137 binary.Unmarshal(buf[i:i+abi.SizeOfTimeval], ByteOrder, &tv) 138 139 strs = append(strs, fmt.Sprintf( 140 "{level=%s, type=%s, length=%d, Sec: %d, Usec: %d}", 141 level, 142 typ, 143 h.Length, 144 tv.Sec, 145 tv.Usec, 146 )) 147 148 default: 149 panic("unreachable") 150 } 151 i += AlignUp(length, uint(width)) 152 } 153 154 return fmt.Sprintf("%#x %s", addr, strings.Join(strs, ", ")) 155 } 156 157 func msghdr(t *Tracer, addr Addr, printContent bool, maxBytes uint64) string { 158 var msg abi.MessageHeader64 159 if err := ReadMessageHeader64(t, addr, &msg); err != nil { 160 return fmt.Sprintf("%#x (error decoding msghdr: %v)", addr, err) 161 } 162 s := fmt.Sprintf( 163 "%#x {name=%#x, namelen=%d, iovecs=%s", 164 addr, 165 msg.Name, 166 msg.NameLen, 167 iovecs(t, Addr(msg.Iov), int(msg.IovLen), printContent, maxBytes), 168 ) 169 if printContent { 170 s = fmt.Sprintf("%s, control={%s}", s, cmsghdr(t, Addr(msg.Control), msg.ControlLen, maxBytes)) 171 } else { 172 s = fmt.Sprintf("%s, control=%#x, control_len=%d", s, msg.Control, msg.ControlLen) 173 } 174 return fmt.Sprintf("%s, flags=%d}", s, msg.Flags) 175 } 176 177 func sockAddr(t *Tracer, addr Addr, length uint32) string { 178 if addr == 0 { 179 return "null" 180 } 181 182 b, err := CaptureAddress(t, addr, length) 183 if err != nil { 184 return fmt.Sprintf("%#x {error reading address: %v}", addr, err) 185 } 186 187 // Extract address family. 188 if len(b) < 2 { 189 return fmt.Sprintf("%#x {address too short: %d bytes}", addr, len(b)) 190 } 191 family := ByteOrder.Uint16(b) 192 193 familyStr := abi.SocketFamily.Parse(uint64(family)) 194 195 switch family { 196 case unix.AF_INET, unix.AF_INET6, unix.AF_UNIX: 197 fa, err := GetAddress(t, b) 198 if err != nil { 199 return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err) 200 } 201 202 if family == unix.AF_UNIX { 203 return fmt.Sprintf("%#x {Family: %s, Addr: %q}", addr, familyStr, fa.Addr) 204 } 205 206 return fmt.Sprintf("%#x {Family: %s, Addr: %#02x, Port: %d}", addr, familyStr, []byte(fa.Addr), fa.Port) 207 case unix.AF_NETLINK: 208 //sa, err := netlink.ExtractSockAddr(b) 209 //if err != nil { 210 return fmt.Sprintf("%#x {Family: %s, error extracting address: %v}", addr, familyStr, err) 211 //} 212 //return fmt.Sprintf("%#x {Family: %s, PortID: %d, Groups: %d}", addr, familyStr, sa.PortID, sa.Groups) 213 default: 214 return fmt.Sprintf("%#x {Family: %s, family addr format unknown}", addr, familyStr) 215 } 216 } 217 218 func postSockAddr(t *Tracer, addr Addr, lengthPtr Addr) string { 219 if addr == 0 { 220 return "null" 221 } 222 223 if lengthPtr == 0 { 224 return fmt.Sprintf("%#x {length null}", addr) 225 } 226 227 l, err := copySockLen(t, lengthPtr) 228 if err != nil { 229 return fmt.Sprintf("%#x {error reading length: %v}", addr, err) 230 } 231 232 return sockAddr(t, addr, l) 233 } 234 235 func copySockLen(t *Tracer, addr Addr) (uint32, error) { 236 // socklen_t is 32-bits. 237 var l uint32 238 _, err := t.Read(addr, &l) 239 return l, err 240 } 241 242 func sockLenPointer(t *Tracer, addr Addr) string { 243 if addr == 0 { 244 return "null" 245 } 246 l, err := copySockLen(t, addr) 247 if err != nil { 248 return fmt.Sprintf("%#x {error reading length: %v}", addr, err) 249 } 250 return fmt.Sprintf("%#x {length=%v}", addr, l) 251 }