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