github.com/go-xe2/third@v1.0.3/golang.org/x/sys/unix/syscall_linux.go (about) 1 // Copyright 2009 The Go 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 // Linux system calls. 6 // This file is compiled as ordinary Go code, 7 // but it is also input to mksyscall, 8 // which parses the //sys lines and generates system call stubs. 9 // Note that sometimes we use a lowercase //sys name and 10 // wrap it in our own nicer implementation. 11 12 package unix 13 14 import ( 15 "encoding/binary" 16 "net" 17 "syscall" 18 "unsafe" 19 ) 20 21 /* 22 * Wrapped 23 */ 24 25 func Access(path string, mode uint32) (err error) { 26 return Faccessat(AT_FDCWD, path, mode, 0) 27 } 28 29 func Chmod(path string, mode uint32) (err error) { 30 return Fchmodat(AT_FDCWD, path, mode, 0) 31 } 32 33 func Chown(path string, uid int, gid int) (err error) { 34 return Fchownat(AT_FDCWD, path, uid, gid, 0) 35 } 36 37 func Creat(path string, mode uint32) (fd int, err error) { 38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 39 } 40 41 //sys fchmodat(dirfd int, path string, mode uint32) (err error) 42 43 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { 44 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior 45 // and check the flags. Otherwise the mode would be applied to the symlink 46 // destination which is not what the user expects. 47 if flags&^AT_SYMLINK_NOFOLLOW != 0 { 48 return EINVAL 49 } else if flags&AT_SYMLINK_NOFOLLOW != 0 { 50 return EOPNOTSUPP 51 } 52 return fchmodat(dirfd, path, mode) 53 } 54 55 //sys ioctl(fd int, req uint, arg uintptr) (err error) 56 57 // ioctl itself should not be exposed directly, but additional get/set 58 // functions for specific types are permissible. 59 60 // IoctlSetPointerInt performs an ioctl operation which sets an 61 // integer value on fd, using the specified request number. The ioctl 62 // argument is called with a pointer to the integer value, rather than 63 // passing the integer value directly. 64 func IoctlSetPointerInt(fd int, req uint, value int) error { 65 v := int32(value) 66 return ioctl(fd, req, uintptr(unsafe.Pointer(&v))) 67 } 68 69 // IoctlSetInt performs an ioctl operation which sets an integer value 70 // on fd, using the specified request number. 71 func IoctlSetInt(fd int, req uint, value int) error { 72 return ioctl(fd, req, uintptr(value)) 73 } 74 75 func ioctlSetWinsize(fd int, req uint, value *Winsize) error { 76 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) 77 } 78 79 func ioctlSetTermios(fd int, req uint, value *Termios) error { 80 return ioctl(fd, req, uintptr(unsafe.Pointer(value))) 81 } 82 83 // IoctlGetInt performs an ioctl operation which gets an integer value 84 // from fd, using the specified request number. 85 func IoctlGetInt(fd int, req uint) (int, error) { 86 var value int 87 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) 88 return value, err 89 } 90 91 func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { 92 var value Winsize 93 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) 94 return &value, err 95 } 96 97 func IoctlGetTermios(fd int, req uint) (*Termios, error) { 98 var value Termios 99 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) 100 return &value, err 101 } 102 103 //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) 104 105 func Link(oldpath string, newpath string) (err error) { 106 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) 107 } 108 109 func Mkdir(path string, mode uint32) (err error) { 110 return Mkdirat(AT_FDCWD, path, mode) 111 } 112 113 func Mknod(path string, mode uint32, dev int) (err error) { 114 return Mknodat(AT_FDCWD, path, mode, dev) 115 } 116 117 func Open(path string, mode int, perm uint32) (fd int, err error) { 118 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm) 119 } 120 121 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 122 123 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { 124 return openat(dirfd, path, flags|O_LARGEFILE, mode) 125 } 126 127 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) 128 129 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { 130 if len(fds) == 0 { 131 return ppoll(nil, 0, timeout, sigmask) 132 } 133 return ppoll(&fds[0], len(fds), timeout, sigmask) 134 } 135 136 //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) 137 138 func Readlink(path string, buf []byte) (n int, err error) { 139 return Readlinkat(AT_FDCWD, path, buf) 140 } 141 142 func Rename(oldpath string, newpath string) (err error) { 143 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath) 144 } 145 146 func Rmdir(path string) error { 147 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR) 148 } 149 150 //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) 151 152 func Symlink(oldpath string, newpath string) (err error) { 153 return Symlinkat(oldpath, AT_FDCWD, newpath) 154 } 155 156 func Unlink(path string) error { 157 return Unlinkat(AT_FDCWD, path, 0) 158 } 159 160 //sys Unlinkat(dirfd int, path string, flags int) (err error) 161 162 func Utimes(path string, tv []Timeval) error { 163 if tv == nil { 164 err := utimensat(AT_FDCWD, path, nil, 0) 165 if err != ENOSYS { 166 return err 167 } 168 return utimes(path, nil) 169 } 170 if len(tv) != 2 { 171 return EINVAL 172 } 173 var ts [2]Timespec 174 ts[0] = NsecToTimespec(TimevalToNsec(tv[0])) 175 ts[1] = NsecToTimespec(TimevalToNsec(tv[1])) 176 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 177 if err != ENOSYS { 178 return err 179 } 180 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 181 } 182 183 //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) 184 185 func UtimesNano(path string, ts []Timespec) error { 186 if ts == nil { 187 err := utimensat(AT_FDCWD, path, nil, 0) 188 if err != ENOSYS { 189 return err 190 } 191 return utimes(path, nil) 192 } 193 if len(ts) != 2 { 194 return EINVAL 195 } 196 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 197 if err != ENOSYS { 198 return err 199 } 200 // If the utimensat syscall isn't available (utimensat was added to Linux 201 // in 2.6.22, Released, 8 July 2007) then fall back to utimes 202 var tv [2]Timeval 203 for i := 0; i < 2; i++ { 204 tv[i] = NsecToTimeval(TimespecToNsec(ts[i])) 205 } 206 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 207 } 208 209 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { 210 if ts == nil { 211 return utimensat(dirfd, path, nil, flags) 212 } 213 if len(ts) != 2 { 214 return EINVAL 215 } 216 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) 217 } 218 219 func Futimesat(dirfd int, path string, tv []Timeval) error { 220 if tv == nil { 221 return futimesat(dirfd, path, nil) 222 } 223 if len(tv) != 2 { 224 return EINVAL 225 } 226 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 227 } 228 229 func Futimes(fd int, tv []Timeval) (err error) { 230 // Believe it or not, this is the best we can do on Linux 231 // (and is what glibc does). 232 return Utimes("/proc/self/fd/"+itoa(fd), tv) 233 } 234 235 const ImplementsGetwd = true 236 237 //sys Getcwd(buf []byte) (n int, err error) 238 239 func Getwd() (wd string, err error) { 240 var buf [PathMax]byte 241 n, err := Getcwd(buf[0:]) 242 if err != nil { 243 return "", err 244 } 245 // Getcwd returns the number of bytes written to buf, including the NUL. 246 if n < 1 || n > len(buf) || buf[n-1] != 0 { 247 return "", EINVAL 248 } 249 return string(buf[0 : n-1]), nil 250 } 251 252 func Getgroups() (gids []int, err error) { 253 n, err := getgroups(0, nil) 254 if err != nil { 255 return nil, err 256 } 257 if n == 0 { 258 return nil, nil 259 } 260 261 // Sanity check group count. Max is 1<<16 on Linux. 262 if n < 0 || n > 1<<20 { 263 return nil, EINVAL 264 } 265 266 a := make([]_Gid_t, n) 267 n, err = getgroups(n, &a[0]) 268 if err != nil { 269 return nil, err 270 } 271 gids = make([]int, n) 272 for i, v := range a[0:n] { 273 gids[i] = int(v) 274 } 275 return 276 } 277 278 func Setgroups(gids []int) (err error) { 279 if len(gids) == 0 { 280 return setgroups(0, nil) 281 } 282 283 a := make([]_Gid_t, len(gids)) 284 for i, v := range gids { 285 a[i] = _Gid_t(v) 286 } 287 return setgroups(len(a), &a[0]) 288 } 289 290 type WaitStatus uint32 291 292 // Wait status is 7 bits at bottom, either 0 (exited), 293 // 0x7F (stopped), or a signal number that caused an exit. 294 // The 0x80 bit is whether there was a core dump. 295 // An extra number (exit code, signal causing a stop) 296 // is in the high bits. At least that's the idea. 297 // There are various irregularities. For example, the 298 // "continued" status is 0xFFFF, distinguishing itself 299 // from stopped via the core dump bit. 300 301 const ( 302 mask = 0x7F 303 core = 0x80 304 exited = 0x00 305 stopped = 0x7F 306 shift = 8 307 ) 308 309 func (w WaitStatus) Exited() bool { return w&mask == exited } 310 311 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 312 313 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 314 315 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 316 317 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 318 319 func (w WaitStatus) ExitStatus() int { 320 if !w.Exited() { 321 return -1 322 } 323 return int(w>>shift) & 0xFF 324 } 325 326 func (w WaitStatus) Signal() syscall.Signal { 327 if !w.Signaled() { 328 return -1 329 } 330 return syscall.Signal(w & mask) 331 } 332 333 func (w WaitStatus) StopSignal() syscall.Signal { 334 if !w.Stopped() { 335 return -1 336 } 337 return syscall.Signal(w>>shift) & 0xFF 338 } 339 340 func (w WaitStatus) TrapCause() int { 341 if w.StopSignal() != SIGTRAP { 342 return -1 343 } 344 return int(w>>shift) >> 8 345 } 346 347 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 348 349 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 350 var status _C_int 351 wpid, err = wait4(pid, &status, options, rusage) 352 if wstatus != nil { 353 *wstatus = WaitStatus(status) 354 } 355 return 356 } 357 358 func Mkfifo(path string, mode uint32) error { 359 return Mknod(path, mode|S_IFIFO, 0) 360 } 361 362 func Mkfifoat(dirfd int, path string, mode uint32) error { 363 return Mknodat(dirfd, path, mode|S_IFIFO, 0) 364 } 365 366 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 367 if sa.Port < 0 || sa.Port > 0xFFFF { 368 return nil, 0, EINVAL 369 } 370 sa.raw.Family = AF_INET 371 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 372 p[0] = byte(sa.Port >> 8) 373 p[1] = byte(sa.Port) 374 for i := 0; i < len(sa.Addr); i++ { 375 sa.raw.Addr[i] = sa.Addr[i] 376 } 377 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 378 } 379 380 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 381 if sa.Port < 0 || sa.Port > 0xFFFF { 382 return nil, 0, EINVAL 383 } 384 sa.raw.Family = AF_INET6 385 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 386 p[0] = byte(sa.Port >> 8) 387 p[1] = byte(sa.Port) 388 sa.raw.Scope_id = sa.ZoneId 389 for i := 0; i < len(sa.Addr); i++ { 390 sa.raw.Addr[i] = sa.Addr[i] 391 } 392 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 393 } 394 395 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 396 name := sa.Name 397 n := len(name) 398 if n >= len(sa.raw.Path) { 399 return nil, 0, EINVAL 400 } 401 sa.raw.Family = AF_UNIX 402 for i := 0; i < n; i++ { 403 sa.raw.Path[i] = int8(name[i]) 404 } 405 // length is family (uint16), name, NUL. 406 sl := _Socklen(2) 407 if n > 0 { 408 sl += _Socklen(n) + 1 409 } 410 if sa.raw.Path[0] == '@' { 411 sa.raw.Path[0] = 0 412 // Don't count trailing NUL for abstract address. 413 sl-- 414 } 415 416 return unsafe.Pointer(&sa.raw), sl, nil 417 } 418 419 // SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets. 420 type SockaddrLinklayer struct { 421 Protocol uint16 422 Ifindex int 423 Hatype uint16 424 Pkttype uint8 425 Halen uint8 426 Addr [8]byte 427 raw RawSockaddrLinklayer 428 } 429 430 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { 431 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 432 return nil, 0, EINVAL 433 } 434 sa.raw.Family = AF_PACKET 435 sa.raw.Protocol = sa.Protocol 436 sa.raw.Ifindex = int32(sa.Ifindex) 437 sa.raw.Hatype = sa.Hatype 438 sa.raw.Pkttype = sa.Pkttype 439 sa.raw.Halen = sa.Halen 440 for i := 0; i < len(sa.Addr); i++ { 441 sa.raw.Addr[i] = sa.Addr[i] 442 } 443 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil 444 } 445 446 // SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets. 447 type SockaddrNetlink struct { 448 Family uint16 449 Pad uint16 450 Pid uint32 451 Groups uint32 452 raw RawSockaddrNetlink 453 } 454 455 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { 456 sa.raw.Family = AF_NETLINK 457 sa.raw.Pad = sa.Pad 458 sa.raw.Pid = sa.Pid 459 sa.raw.Groups = sa.Groups 460 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil 461 } 462 463 // SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets 464 // using the HCI protocol. 465 type SockaddrHCI struct { 466 Dev uint16 467 Channel uint16 468 raw RawSockaddrHCI 469 } 470 471 func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) { 472 sa.raw.Family = AF_BLUETOOTH 473 sa.raw.Dev = sa.Dev 474 sa.raw.Channel = sa.Channel 475 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil 476 } 477 478 // SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets 479 // using the L2CAP protocol. 480 type SockaddrL2 struct { 481 PSM uint16 482 CID uint16 483 Addr [6]uint8 484 AddrType uint8 485 raw RawSockaddrL2 486 } 487 488 func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { 489 sa.raw.Family = AF_BLUETOOTH 490 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) 491 psm[0] = byte(sa.PSM) 492 psm[1] = byte(sa.PSM >> 8) 493 for i := 0; i < len(sa.Addr); i++ { 494 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] 495 } 496 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) 497 cid[0] = byte(sa.CID) 498 cid[1] = byte(sa.CID >> 8) 499 sa.raw.Bdaddr_type = sa.AddrType 500 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil 501 } 502 503 // SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets 504 // using the RFCOMM protocol. 505 // 506 // Server example: 507 // 508 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 509 // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ 510 // Channel: 1, 511 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 512 // }) 513 // _ = Listen(fd, 1) 514 // nfd, sa, _ := Accept(fd) 515 // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) 516 // Read(nfd, buf) 517 // 518 // Client example: 519 // 520 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 521 // _ = Connect(fd, &SockaddrRFCOMM{ 522 // Channel: 1, 523 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 524 // }) 525 // Write(fd, []byte(`hello`)) 526 type SockaddrRFCOMM struct { 527 // Addr represents a bluetooth address, byte ordering is little-endian. 528 Addr [6]uint8 529 530 // Channel is a designated bluetooth channel, only 1-30 are available for use. 531 // Since Linux 2.6.7 and further zero value is the first available channel. 532 Channel uint8 533 534 raw RawSockaddrRFCOMM 535 } 536 537 func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) { 538 sa.raw.Family = AF_BLUETOOTH 539 sa.raw.Channel = sa.Channel 540 sa.raw.Bdaddr = sa.Addr 541 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil 542 } 543 544 // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. 545 // The RxID and TxID fields are used for transport protocol addressing in 546 // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with 547 // zero values for CAN_RAW and CAN_BCM sockets as they have no meaning. 548 // 549 // The SockaddrCAN struct must be bound to the socket file descriptor 550 // using Bind before the CAN socket can be used. 551 // 552 // // Read one raw CAN frame 553 // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) 554 // addr := &SockaddrCAN{Ifindex: index} 555 // Bind(fd, addr) 556 // frame := make([]byte, 16) 557 // Read(fd, frame) 558 // 559 // The full SocketCAN documentation can be found in the linux kernel 560 // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt 561 type SockaddrCAN struct { 562 Ifindex int 563 RxID uint32 564 TxID uint32 565 raw RawSockaddrCAN 566 } 567 568 func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { 569 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 570 return nil, 0, EINVAL 571 } 572 sa.raw.Family = AF_CAN 573 sa.raw.Ifindex = int32(sa.Ifindex) 574 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 575 for i := 0; i < 4; i++ { 576 sa.raw.Addr[i] = rx[i] 577 } 578 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 579 for i := 0; i < 4; i++ { 580 sa.raw.Addr[i+4] = tx[i] 581 } 582 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil 583 } 584 585 // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. 586 // SockaddrALG enables userspace access to the Linux kernel's cryptography 587 // subsystem. The Type and Name fields specify which type of hash or cipher 588 // should be used with a given socket. 589 // 590 // To create a file descriptor that provides access to a hash or cipher, both 591 // Bind and Accept must be used. Once the setup process is complete, input 592 // data can be written to the socket, processed by the kernel, and then read 593 // back as hash output or ciphertext. 594 // 595 // Here is an example of using an AF_ALG socket with SHA1 hashing. 596 // The initial socket setup process is as follows: 597 // 598 // // Open a socket to perform SHA1 hashing. 599 // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) 600 // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} 601 // unix.Bind(fd, addr) 602 // // Note: unix.Accept does not work at this time; must invoke accept() 603 // // manually using unix.Syscall. 604 // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) 605 // 606 // Once a file descriptor has been returned from Accept, it may be used to 607 // perform SHA1 hashing. The descriptor is not safe for concurrent use, but 608 // may be re-used repeatedly with subsequent Write and Read operations. 609 // 610 // When hashing a small byte slice or string, a single Write and Read may 611 // be used: 612 // 613 // // Assume hashfd is already configured using the setup process. 614 // hash := os.NewFile(hashfd, "sha1") 615 // // Hash an input string and read the results. Each Write discards 616 // // previous hash state. Read always reads the current state. 617 // b := make([]byte, 20) 618 // for i := 0; i < 2; i++ { 619 // io.WriteString(hash, "Hello, world.") 620 // hash.Read(b) 621 // fmt.Println(hex.EncodeToString(b)) 622 // } 623 // // Output: 624 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 625 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 626 // 627 // For hashing larger byte slices, or byte streams such as those read from 628 // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update 629 // the hash digest instead of creating a new one for a given chunk and finalizing it. 630 // 631 // // Assume hashfd and addr are already configured using the setup process. 632 // hash := os.NewFile(hashfd, "sha1") 633 // // Hash the contents of a file. 634 // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") 635 // b := make([]byte, 4096) 636 // for { 637 // n, err := f.Read(b) 638 // if err == io.EOF { 639 // break 640 // } 641 // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) 642 // } 643 // hash.Read(b) 644 // fmt.Println(hex.EncodeToString(b)) 645 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 646 // 647 // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. 648 type SockaddrALG struct { 649 Type string 650 Name string 651 Feature uint32 652 Mask uint32 653 raw RawSockaddrALG 654 } 655 656 func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) { 657 // Leave room for NUL byte terminator. 658 if len(sa.Type) > 13 { 659 return nil, 0, EINVAL 660 } 661 if len(sa.Name) > 63 { 662 return nil, 0, EINVAL 663 } 664 665 sa.raw.Family = AF_ALG 666 sa.raw.Feat = sa.Feature 667 sa.raw.Mask = sa.Mask 668 669 typ, err := ByteSliceFromString(sa.Type) 670 if err != nil { 671 return nil, 0, err 672 } 673 name, err := ByteSliceFromString(sa.Name) 674 if err != nil { 675 return nil, 0, err 676 } 677 678 copy(sa.raw.Type[:], typ) 679 copy(sa.raw.Name[:], name) 680 681 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil 682 } 683 684 // SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets. 685 // SockaddrVM provides access to Linux VM sockets: a mechanism that enables 686 // bidirectional communication between a hypervisor and its guest virtual 687 // machines. 688 type SockaddrVM struct { 689 // CID and Port specify a context ID and port address for a VM socket. 690 // Guests have a unique CID, and hosts may have a well-known CID of: 691 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. 692 // - VMADDR_CID_HOST: refers to other processes on the host. 693 CID uint32 694 Port uint32 695 raw RawSockaddrVM 696 } 697 698 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { 699 sa.raw.Family = AF_VSOCK 700 sa.raw.Port = sa.Port 701 sa.raw.Cid = sa.CID 702 703 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil 704 } 705 706 type SockaddrXDP struct { 707 Flags uint16 708 Ifindex uint32 709 QueueID uint32 710 SharedUmemFD uint32 711 raw RawSockaddrXDP 712 } 713 714 func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) { 715 sa.raw.Family = AF_XDP 716 sa.raw.Flags = sa.Flags 717 sa.raw.Ifindex = sa.Ifindex 718 sa.raw.Queue_id = sa.QueueID 719 sa.raw.Shared_umem_fd = sa.SharedUmemFD 720 721 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil 722 } 723 724 // This constant mirrors the #define of PX_PROTO_OE in 725 // linux/if_pppox.h. We're defining this by hand here instead of 726 // autogenerating through mkerrors.sh because including 727 // linux/if_pppox.h causes some declaration conflicts with other 728 // includes (linux/if_pppox.h includes linux/in.h, which conflicts 729 // with netinet/in.h). Given that we only need a single zero constant 730 // out of that file, it's cleaner to just define it by hand here. 731 const px_proto_oe = 0 732 733 type SockaddrPPPoE struct { 734 SID uint16 735 Remote net.HardwareAddr 736 Dev string 737 raw RawSockaddrPPPoX 738 } 739 740 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { 741 if len(sa.Remote) != 6 { 742 return nil, 0, EINVAL 743 } 744 if len(sa.Dev) > IFNAMSIZ-1 { 745 return nil, 0, EINVAL 746 } 747 748 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX 749 // This next field is in host-endian byte order. We can't use the 750 // same unsafe pointer cast as above, because this value is not 751 // 32-bit aligned and some architectures don't allow unaligned 752 // access. 753 // 754 // However, the value of px_proto_oe is 0, so we can use 755 // encoding/binary helpers to write the bytes without worrying 756 // about the ordering. 757 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe) 758 // This field is deliberately big-endian, unlike the previous 759 // one. The kernel expects SID to be in network byte order. 760 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) 761 copy(sa.raw[8:14], sa.Remote) 762 for i := 14; i < 14+IFNAMSIZ; i++ { 763 sa.raw[i] = 0 764 } 765 copy(sa.raw[14:], sa.Dev) 766 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil 767 } 768 769 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 770 switch rsa.Addr.Family { 771 case AF_NETLINK: 772 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 773 sa := new(SockaddrNetlink) 774 sa.Family = pp.Family 775 sa.Pad = pp.Pad 776 sa.Pid = pp.Pid 777 sa.Groups = pp.Groups 778 return sa, nil 779 780 case AF_PACKET: 781 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 782 sa := new(SockaddrLinklayer) 783 sa.Protocol = pp.Protocol 784 sa.Ifindex = int(pp.Ifindex) 785 sa.Hatype = pp.Hatype 786 sa.Pkttype = pp.Pkttype 787 sa.Halen = pp.Halen 788 for i := 0; i < len(sa.Addr); i++ { 789 sa.Addr[i] = pp.Addr[i] 790 } 791 return sa, nil 792 793 case AF_UNIX: 794 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 795 sa := new(SockaddrUnix) 796 if pp.Path[0] == 0 { 797 // "Abstract" Unix domain socket. 798 // Rewrite leading NUL as @ for textual display. 799 // (This is the standard convention.) 800 // Not friendly to overwrite in place, 801 // but the callers below don't care. 802 pp.Path[0] = '@' 803 } 804 805 // Assume path ends at NUL. 806 // This is not technically the Linux semantics for 807 // abstract Unix domain sockets--they are supposed 808 // to be uninterpreted fixed-size binary blobs--but 809 // everyone uses this convention. 810 n := 0 811 for n < len(pp.Path) && pp.Path[n] != 0 { 812 n++ 813 } 814 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 815 sa.Name = string(bytes) 816 return sa, nil 817 818 case AF_INET: 819 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 820 sa := new(SockaddrInet4) 821 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 822 sa.Port = int(p[0])<<8 + int(p[1]) 823 for i := 0; i < len(sa.Addr); i++ { 824 sa.Addr[i] = pp.Addr[i] 825 } 826 return sa, nil 827 828 case AF_INET6: 829 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 830 sa := new(SockaddrInet6) 831 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 832 sa.Port = int(p[0])<<8 + int(p[1]) 833 sa.ZoneId = pp.Scope_id 834 for i := 0; i < len(sa.Addr); i++ { 835 sa.Addr[i] = pp.Addr[i] 836 } 837 return sa, nil 838 839 case AF_VSOCK: 840 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) 841 sa := &SockaddrVM{ 842 CID: pp.Cid, 843 Port: pp.Port, 844 } 845 return sa, nil 846 case AF_BLUETOOTH: 847 proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) 848 if err != nil { 849 return nil, err 850 } 851 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections 852 switch proto { 853 case BTPROTO_L2CAP: 854 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa)) 855 sa := &SockaddrL2{ 856 PSM: pp.Psm, 857 CID: pp.Cid, 858 Addr: pp.Bdaddr, 859 AddrType: pp.Bdaddr_type, 860 } 861 return sa, nil 862 case BTPROTO_RFCOMM: 863 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa)) 864 sa := &SockaddrRFCOMM{ 865 Channel: pp.Channel, 866 Addr: pp.Bdaddr, 867 } 868 return sa, nil 869 } 870 case AF_XDP: 871 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa)) 872 sa := &SockaddrXDP{ 873 Flags: pp.Flags, 874 Ifindex: pp.Ifindex, 875 QueueID: pp.Queue_id, 876 SharedUmemFD: pp.Shared_umem_fd, 877 } 878 return sa, nil 879 case AF_PPPOX: 880 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) 881 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { 882 return nil, EINVAL 883 } 884 sa := &SockaddrPPPoE{ 885 SID: binary.BigEndian.Uint16(pp[6:8]), 886 Remote: net.HardwareAddr(pp[8:14]), 887 } 888 for i := 14; i < 14+IFNAMSIZ; i++ { 889 if pp[i] == 0 { 890 sa.Dev = string(pp[14:i]) 891 break 892 } 893 } 894 return sa, nil 895 } 896 return nil, EAFNOSUPPORT 897 } 898 899 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 900 var rsa RawSockaddrAny 901 var len _Socklen = SizeofSockaddrAny 902 nfd, err = accept(fd, &rsa, &len) 903 if err != nil { 904 return 905 } 906 sa, err = anyToSockaddr(fd, &rsa) 907 if err != nil { 908 Close(nfd) 909 nfd = 0 910 } 911 return 912 } 913 914 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 915 var rsa RawSockaddrAny 916 var len _Socklen = SizeofSockaddrAny 917 nfd, err = accept4(fd, &rsa, &len, flags) 918 if err != nil { 919 return 920 } 921 if len > SizeofSockaddrAny { 922 panic("RawSockaddrAny too small") 923 } 924 sa, err = anyToSockaddr(fd, &rsa) 925 if err != nil { 926 Close(nfd) 927 nfd = 0 928 } 929 return 930 } 931 932 func Getsockname(fd int) (sa Sockaddr, err error) { 933 var rsa RawSockaddrAny 934 var len _Socklen = SizeofSockaddrAny 935 if err = getsockname(fd, &rsa, &len); err != nil { 936 return 937 } 938 return anyToSockaddr(fd, &rsa) 939 } 940 941 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 942 var value IPMreqn 943 vallen := _Socklen(SizeofIPMreqn) 944 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 945 return &value, err 946 } 947 948 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 949 var value Ucred 950 vallen := _Socklen(SizeofUcred) 951 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 952 return &value, err 953 } 954 955 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { 956 var value TCPInfo 957 vallen := _Socklen(SizeofTCPInfo) 958 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 959 return &value, err 960 } 961 962 // GetsockoptString returns the string value of the socket option opt for the 963 // socket associated with fd at the given socket level. 964 func GetsockoptString(fd, level, opt int) (string, error) { 965 buf := make([]byte, 256) 966 vallen := _Socklen(len(buf)) 967 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 968 if err != nil { 969 if err == ERANGE { 970 buf = make([]byte, vallen) 971 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 972 } 973 if err != nil { 974 return "", err 975 } 976 } 977 return string(buf[:vallen-1]), nil 978 } 979 980 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 981 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 982 } 983 984 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) 985 986 // KeyctlInt calls keyctl commands in which each argument is an int. 987 // These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK, 988 // KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT, 989 // KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT, 990 // KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT. 991 //sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL 992 993 // KeyctlBuffer calls keyctl commands in which the third and fourth 994 // arguments are a buffer and its length, respectively. 995 // These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE. 996 //sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL 997 998 // KeyctlString calls keyctl commands which return a string. 999 // These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY. 1000 func KeyctlString(cmd int, id int) (string, error) { 1001 // We must loop as the string data may change in between the syscalls. 1002 // We could allocate a large buffer here to reduce the chance that the 1003 // syscall needs to be called twice; however, this is unnecessary as 1004 // the performance loss is negligible. 1005 var buffer []byte 1006 for { 1007 // Try to fill the buffer with data 1008 length, err := KeyctlBuffer(cmd, id, buffer, 0) 1009 if err != nil { 1010 return "", err 1011 } 1012 1013 // Check if the data was written 1014 if length <= len(buffer) { 1015 // Exclude the null terminator 1016 return string(buffer[:length-1]), nil 1017 } 1018 1019 // Make a bigger buffer if needed 1020 buffer = make([]byte, length) 1021 } 1022 } 1023 1024 // Keyctl commands with special signatures. 1025 1026 // KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command. 1027 // See the full documentation at: 1028 // http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html 1029 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) { 1030 createInt := 0 1031 if create { 1032 createInt = 1 1033 } 1034 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0) 1035 } 1036 1037 // KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the 1038 // key handle permission mask as described in the "keyctl setperm" section of 1039 // http://man7.org/linux/man-pages/man1/keyctl.1.html. 1040 // See the full documentation at: 1041 // http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html 1042 func KeyctlSetperm(id int, perm uint32) error { 1043 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0) 1044 return err 1045 } 1046 1047 //sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL 1048 1049 // KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command. 1050 // See the full documentation at: 1051 // http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html 1052 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) { 1053 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name) 1054 } 1055 1056 //sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL 1057 1058 // KeyctlSearch implements the KEYCTL_SEARCH command. 1059 // See the full documentation at: 1060 // http://man7.org/linux/man-pages/man3/keyctl_search.3.html 1061 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) { 1062 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid) 1063 } 1064 1065 //sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL 1066 1067 // KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This 1068 // command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice 1069 // of Iovec (each of which represents a buffer) instead of a single buffer. 1070 // See the full documentation at: 1071 // http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html 1072 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error { 1073 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid) 1074 } 1075 1076 //sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL 1077 1078 // KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command 1079 // computes a Diffie-Hellman shared secret based on the provide params. The 1080 // secret is written to the provided buffer and the returned size is the number 1081 // of bytes written (returning an error if there is insufficient space in the 1082 // buffer). If a nil buffer is passed in, this function returns the minimum 1083 // buffer length needed to store the appropriate data. Note that this differs 1084 // from KEYCTL_READ's behavior which always returns the requested payload size. 1085 // See the full documentation at: 1086 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html 1087 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { 1088 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) 1089 } 1090 1091 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 1092 var msg Msghdr 1093 var rsa RawSockaddrAny 1094 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 1095 msg.Namelen = uint32(SizeofSockaddrAny) 1096 var iov Iovec 1097 if len(p) > 0 { 1098 iov.Base = &p[0] 1099 iov.SetLen(len(p)) 1100 } 1101 var dummy byte 1102 if len(oob) > 0 { 1103 if len(p) == 0 { 1104 var sockType int 1105 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1106 if err != nil { 1107 return 1108 } 1109 // receive at least one normal byte 1110 if sockType != SOCK_DGRAM { 1111 iov.Base = &dummy 1112 iov.SetLen(1) 1113 } 1114 } 1115 msg.Control = &oob[0] 1116 msg.SetControllen(len(oob)) 1117 } 1118 msg.Iov = &iov 1119 msg.Iovlen = 1 1120 if n, err = recvmsg(fd, &msg, flags); err != nil { 1121 return 1122 } 1123 oobn = int(msg.Controllen) 1124 recvflags = int(msg.Flags) 1125 // source address is only specified if the socket is unconnected 1126 if rsa.Addr.Family != AF_UNSPEC { 1127 from, err = anyToSockaddr(fd, &rsa) 1128 } 1129 return 1130 } 1131 1132 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 1133 _, err = SendmsgN(fd, p, oob, to, flags) 1134 return 1135 } 1136 1137 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 1138 var ptr unsafe.Pointer 1139 var salen _Socklen 1140 if to != nil { 1141 var err error 1142 ptr, salen, err = to.sockaddr() 1143 if err != nil { 1144 return 0, err 1145 } 1146 } 1147 var msg Msghdr 1148 msg.Name = (*byte)(ptr) 1149 msg.Namelen = uint32(salen) 1150 var iov Iovec 1151 if len(p) > 0 { 1152 iov.Base = &p[0] 1153 iov.SetLen(len(p)) 1154 } 1155 var dummy byte 1156 if len(oob) > 0 { 1157 if len(p) == 0 { 1158 var sockType int 1159 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1160 if err != nil { 1161 return 0, err 1162 } 1163 // send at least one normal byte 1164 if sockType != SOCK_DGRAM { 1165 iov.Base = &dummy 1166 iov.SetLen(1) 1167 } 1168 } 1169 msg.Control = &oob[0] 1170 msg.SetControllen(len(oob)) 1171 } 1172 msg.Iov = &iov 1173 msg.Iovlen = 1 1174 if n, err = sendmsg(fd, &msg, flags); err != nil { 1175 return 0, err 1176 } 1177 if len(oob) > 0 && len(p) == 0 { 1178 n = 0 1179 } 1180 return n, nil 1181 } 1182 1183 // BindToDevice binds the socket associated with fd to device. 1184 func BindToDevice(fd int, device string) (err error) { 1185 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 1186 } 1187 1188 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 1189 1190 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 1191 // The peek requests are machine-size oriented, so we wrap it 1192 // to retrieve arbitrary-length data. 1193 1194 // The ptrace syscall differs from glibc's ptrace. 1195 // Peeks returns the word in *data, not as the return value. 1196 1197 var buf [SizeofPtr]byte 1198 1199 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 1200 // access (PEEKUSER warns that it might), but if we don't 1201 // align our reads, we might straddle an unmapped page 1202 // boundary and not get the bytes leading up to the page 1203 // boundary. 1204 n := 0 1205 if addr%SizeofPtr != 0 { 1206 err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 1207 if err != nil { 1208 return 0, err 1209 } 1210 n += copy(out, buf[addr%SizeofPtr:]) 1211 out = out[n:] 1212 } 1213 1214 // Remainder. 1215 for len(out) > 0 { 1216 // We use an internal buffer to guarantee alignment. 1217 // It's not documented if this is necessary, but we're paranoid. 1218 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 1219 if err != nil { 1220 return n, err 1221 } 1222 copied := copy(out, buf[0:]) 1223 n += copied 1224 out = out[copied:] 1225 } 1226 1227 return n, nil 1228 } 1229 1230 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 1231 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 1232 } 1233 1234 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 1235 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 1236 } 1237 1238 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) { 1239 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out) 1240 } 1241 1242 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 1243 // As for ptracePeek, we need to align our accesses to deal 1244 // with the possibility of straddling an invalid page. 1245 1246 // Leading edge. 1247 n := 0 1248 if addr%SizeofPtr != 0 { 1249 var buf [SizeofPtr]byte 1250 err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 1251 if err != nil { 1252 return 0, err 1253 } 1254 n += copy(buf[addr%SizeofPtr:], data) 1255 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1256 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word) 1257 if err != nil { 1258 return 0, err 1259 } 1260 data = data[n:] 1261 } 1262 1263 // Interior. 1264 for len(data) > SizeofPtr { 1265 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 1266 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1267 if err != nil { 1268 return n, err 1269 } 1270 n += SizeofPtr 1271 data = data[SizeofPtr:] 1272 } 1273 1274 // Trailing edge. 1275 if len(data) > 0 { 1276 var buf [SizeofPtr]byte 1277 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 1278 if err != nil { 1279 return n, err 1280 } 1281 copy(buf[0:], data) 1282 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1283 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1284 if err != nil { 1285 return n, err 1286 } 1287 n += len(data) 1288 } 1289 1290 return n, nil 1291 } 1292 1293 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 1294 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 1295 } 1296 1297 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 1298 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 1299 } 1300 1301 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { 1302 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) 1303 } 1304 1305 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 1306 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) 1307 } 1308 1309 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 1310 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) 1311 } 1312 1313 func PtraceSetOptions(pid int, options int) (err error) { 1314 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 1315 } 1316 1317 func PtraceGetEventMsg(pid int) (msg uint, err error) { 1318 var data _C_long 1319 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) 1320 msg = uint(data) 1321 return 1322 } 1323 1324 func PtraceCont(pid int, signal int) (err error) { 1325 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 1326 } 1327 1328 func PtraceSyscall(pid int, signal int) (err error) { 1329 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 1330 } 1331 1332 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 1333 1334 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 1335 1336 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 1337 1338 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 1339 1340 func Reboot(cmd int) (err error) { 1341 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 1342 } 1343 1344 func ReadDirent(fd int, buf []byte) (n int, err error) { 1345 return Getdents(fd, buf) 1346 } 1347 1348 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 1349 1350 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 1351 // Certain file systems get rather angry and EINVAL if you give 1352 // them an empty string of data, rather than NULL. 1353 if data == "" { 1354 return mount(source, target, fstype, flags, nil) 1355 } 1356 datap, err := BytePtrFromString(data) 1357 if err != nil { 1358 return err 1359 } 1360 return mount(source, target, fstype, flags, datap) 1361 } 1362 1363 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 1364 if raceenabled { 1365 raceReleaseMerge(unsafe.Pointer(&ioSync)) 1366 } 1367 return sendfile(outfd, infd, offset, count) 1368 } 1369 1370 // Sendto 1371 // Recvfrom 1372 // Socketpair 1373 1374 /* 1375 * Direct access 1376 */ 1377 //sys Acct(path string) (err error) 1378 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) 1379 //sys Adjtimex(buf *Timex) (state int, err error) 1380 //sys Chdir(path string) (err error) 1381 //sys Chroot(path string) (err error) 1382 //sys ClockGetres(clockid int32, res *Timespec) (err error) 1383 //sys ClockGettime(clockid int32, time *Timespec) (err error) 1384 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) 1385 //sys Close(fd int) (err error) 1386 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 1387 //sys DeleteModule(name string, flags int) (err error) 1388 //sys Dup(oldfd int) (fd int, err error) 1389 //sys Dup3(oldfd int, newfd int, flags int) (err error) 1390 //sysnb EpollCreate1(flag int) (fd int, err error) 1391 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 1392 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 1393 //sys Exit(code int) = SYS_EXIT_GROUP 1394 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 1395 //sys Fchdir(fd int) (err error) 1396 //sys Fchmod(fd int, mode uint32) (err error) 1397 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 1398 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 1399 //sys Fdatasync(fd int) (err error) 1400 //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) 1401 //sys FinitModule(fd int, params string, flags int) (err error) 1402 //sys Flistxattr(fd int, dest []byte) (sz int, err error) 1403 //sys Flock(fd int, how int) (err error) 1404 //sys Fremovexattr(fd int, attr string) (err error) 1405 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) 1406 //sys Fsync(fd int) (err error) 1407 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 1408 //sysnb Getpgid(pid int) (pgid int, err error) 1409 1410 func Getpgrp() (pid int) { 1411 pid, _ = Getpgid(0) 1412 return 1413 } 1414 1415 //sysnb Getpid() (pid int) 1416 //sysnb Getppid() (ppid int) 1417 //sys Getpriority(which int, who int) (prio int, err error) 1418 //sys Getrandom(buf []byte, flags int) (n int, err error) 1419 //sysnb Getrusage(who int, rusage *Rusage) (err error) 1420 //sysnb Getsid(pid int) (sid int, err error) 1421 //sysnb Gettid() (tid int) 1422 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 1423 //sys InitModule(moduleImage []byte, params string) (err error) 1424 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 1425 //sysnb InotifyInit1(flags int) (fd int, err error) 1426 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 1427 //sysnb Kill(pid int, sig syscall.Signal) (err error) 1428 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 1429 //sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error) 1430 //sys Listxattr(path string, dest []byte) (sz int, err error) 1431 //sys Llistxattr(path string, dest []byte) (sz int, err error) 1432 //sys Lremovexattr(path string, attr string) (err error) 1433 //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) 1434 //sys MemfdCreate(name string, flags int) (fd int, err error) 1435 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 1436 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 1437 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 1438 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) 1439 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 1440 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 1441 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) 1442 //sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 1443 //sys read(fd int, p []byte) (n int, err error) 1444 //sys Removexattr(path string, attr string) (err error) 1445 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) 1446 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) 1447 //sys Setdomainname(p []byte) (err error) 1448 //sys Sethostname(p []byte) (err error) 1449 //sysnb Setpgid(pid int, pgid int) (err error) 1450 //sysnb Setsid() (pid int, err error) 1451 //sysnb Settimeofday(tv *Timeval) (err error) 1452 //sys Setns(fd int, nstype int) (err error) 1453 1454 // issue 1435. 1455 // On linux Setuid and Setgid only affects the current thread, not the process. 1456 // This does not match what most callers expect so we must return an error 1457 // here rather than letting the caller think that the call succeeded. 1458 1459 func Setuid(uid int) (err error) { 1460 return EOPNOTSUPP 1461 } 1462 1463 func Setgid(uid int) (err error) { 1464 return EOPNOTSUPP 1465 } 1466 1467 //sys Setpriority(which int, who int, prio int) (err error) 1468 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) 1469 //sys Signalfd(fd int, mask *Sigset_t, flags int) = SYS_SIGNALFD4 1470 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) 1471 //sys Sync() 1472 //sys Syncfs(fd int) (err error) 1473 //sysnb Sysinfo(info *Sysinfo_t) (err error) 1474 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 1475 //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) 1476 //sysnb Times(tms *Tms) (ticks uintptr, err error) 1477 //sysnb Umask(mask int) (oldmask int) 1478 //sysnb Uname(buf *Utsname) (err error) 1479 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 1480 //sys Unshare(flags int) (err error) 1481 //sys write(fd int, p []byte) (n int, err error) 1482 //sys exitThread(code int) (err error) = SYS_EXIT 1483 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ 1484 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE 1485 1486 // mmap varies by architecture; see syscall_linux_*.go. 1487 //sys munmap(addr uintptr, length uintptr) (err error) 1488 1489 var mapper = &mmapper{ 1490 active: make(map[*byte][]byte), 1491 mmap: mmap, 1492 munmap: munmap, 1493 } 1494 1495 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 1496 return mapper.Mmap(fd, offset, length, prot, flags) 1497 } 1498 1499 func Munmap(b []byte) (err error) { 1500 return mapper.Munmap(b) 1501 } 1502 1503 //sys Madvise(b []byte, advice int) (err error) 1504 //sys Mprotect(b []byte, prot int) (err error) 1505 //sys Mlock(b []byte) (err error) 1506 //sys Mlockall(flags int) (err error) 1507 //sys Msync(b []byte, flags int) (err error) 1508 //sys Munlock(b []byte) (err error) 1509 //sys Munlockall() (err error) 1510 1511 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, 1512 // using the specified flags. 1513 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { 1514 var p unsafe.Pointer 1515 if len(iovs) > 0 { 1516 p = unsafe.Pointer(&iovs[0]) 1517 } 1518 1519 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0) 1520 if errno != 0 { 1521 return 0, syscall.Errno(errno) 1522 } 1523 1524 return int(n), nil 1525 } 1526 1527 //sys faccessat(dirfd int, path string, mode uint32) (err error) 1528 1529 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 1530 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { 1531 return EINVAL 1532 } 1533 1534 // The Linux kernel faccessat system call does not take any flags. 1535 // The glibc faccessat implements the flags itself; see 1536 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 1537 // Because people naturally expect syscall.Faccessat to act 1538 // like C faccessat, we do the same. 1539 1540 if flags == 0 { 1541 return faccessat(dirfd, path, mode) 1542 } 1543 1544 var st Stat_t 1545 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { 1546 return err 1547 } 1548 1549 mode &= 7 1550 if mode == 0 { 1551 return nil 1552 } 1553 1554 var uid int 1555 if flags&AT_EACCESS != 0 { 1556 uid = Geteuid() 1557 } else { 1558 uid = Getuid() 1559 } 1560 1561 if uid == 0 { 1562 if mode&1 == 0 { 1563 // Root can read and write any file. 1564 return nil 1565 } 1566 if st.Mode&0111 != 0 { 1567 // Root can execute any file that anybody can execute. 1568 return nil 1569 } 1570 return EACCES 1571 } 1572 1573 var fmode uint32 1574 if uint32(uid) == st.Uid { 1575 fmode = (st.Mode >> 6) & 7 1576 } else { 1577 var gid int 1578 if flags&AT_EACCESS != 0 { 1579 gid = Getegid() 1580 } else { 1581 gid = Getgid() 1582 } 1583 1584 if uint32(gid) == st.Gid { 1585 fmode = (st.Mode >> 3) & 7 1586 } else { 1587 fmode = st.Mode & 7 1588 } 1589 } 1590 1591 if fmode&mode == mode { 1592 return nil 1593 } 1594 1595 return EACCES 1596 } 1597 1598 /* 1599 * Unimplemented 1600 */ 1601 // AfsSyscall 1602 // Alarm 1603 // ArchPrctl 1604 // Brk 1605 // Capget 1606 // Capset 1607 // ClockNanosleep 1608 // ClockSettime 1609 // Clone 1610 // EpollCtlOld 1611 // EpollPwait 1612 // EpollWaitOld 1613 // Execve 1614 // Fork 1615 // Futex 1616 // GetKernelSyms 1617 // GetMempolicy 1618 // GetRobustList 1619 // GetThreadArea 1620 // Getitimer 1621 // Getpmsg 1622 // IoCancel 1623 // IoDestroy 1624 // IoGetevents 1625 // IoSetup 1626 // IoSubmit 1627 // IoprioGet 1628 // IoprioSet 1629 // KexecLoad 1630 // LookupDcookie 1631 // Mbind 1632 // MigratePages 1633 // Mincore 1634 // ModifyLdt 1635 // Mount 1636 // MovePages 1637 // MqGetsetattr 1638 // MqNotify 1639 // MqOpen 1640 // MqTimedreceive 1641 // MqTimedsend 1642 // MqUnlink 1643 // Mremap 1644 // Msgctl 1645 // Msgget 1646 // Msgrcv 1647 // Msgsnd 1648 // Nfsservctl 1649 // Personality 1650 // Pselect6 1651 // Ptrace 1652 // Putpmsg 1653 // Quotactl 1654 // Readahead 1655 // Readv 1656 // RemapFilePages 1657 // RestartSyscall 1658 // RtSigaction 1659 // RtSigpending 1660 // RtSigprocmask 1661 // RtSigqueueinfo 1662 // RtSigreturn 1663 // RtSigsuspend 1664 // RtSigtimedwait 1665 // SchedGetPriorityMax 1666 // SchedGetPriorityMin 1667 // SchedGetparam 1668 // SchedGetscheduler 1669 // SchedRrGetInterval 1670 // SchedSetparam 1671 // SchedYield 1672 // Security 1673 // Semctl 1674 // Semget 1675 // Semop 1676 // Semtimedop 1677 // SetMempolicy 1678 // SetRobustList 1679 // SetThreadArea 1680 // SetTidAddress 1681 // Shmat 1682 // Shmctl 1683 // Shmdt 1684 // Shmget 1685 // Sigaltstack 1686 // Swapoff 1687 // Swapon 1688 // Sysfs 1689 // TimerCreate 1690 // TimerDelete 1691 // TimerGetoverrun 1692 // TimerGettime 1693 // TimerSettime 1694 // Timerfd 1695 // Tkill (obsolete) 1696 // Tuxcall 1697 // Umount2 1698 // Uselib 1699 // Utimensat 1700 // Vfork 1701 // Vhangup 1702 // Vserver 1703 // Waitid 1704 // _Sysctl