syscall_linux.go (81868B)
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 "slices" 17 "strconv" 18 "syscall" 19 "time" 20 "unsafe" 21 ) 22 23 /* 24 * Wrapped 25 */ 26 27 func Access(path string, mode uint32) (err error) { 28 return Faccessat(AT_FDCWD, path, mode, 0) 29 } 30 31 func Chmod(path string, mode uint32) (err error) { 32 return Fchmodat(AT_FDCWD, path, mode, 0) 33 } 34 35 func Chown(path string, uid int, gid int) (err error) { 36 return Fchownat(AT_FDCWD, path, uid, gid, 0) 37 } 38 39 func Creat(path string, mode uint32) (fd int, err error) { 40 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 41 } 42 43 func EpollCreate(size int) (fd int, err error) { 44 if size <= 0 { 45 return -1, EINVAL 46 } 47 return EpollCreate1(0) 48 } 49 50 //sys FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) 51 //sys fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) 52 53 func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (err error) { 54 if pathname == "" { 55 return fanotifyMark(fd, flags, mask, dirFd, nil) 56 } 57 p, err := BytePtrFromString(pathname) 58 if err != nil { 59 return err 60 } 61 return fanotifyMark(fd, flags, mask, dirFd, p) 62 } 63 64 //sys fchmodat(dirfd int, path string, mode uint32) (err error) 65 //sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) 66 67 func Fchmodat(dirfd int, path string, mode uint32, flags int) error { 68 // Linux fchmodat doesn't support the flags parameter, but fchmodat2 does. 69 // Try fchmodat2 if flags are specified. 70 if flags != 0 { 71 err := fchmodat2(dirfd, path, mode, flags) 72 if err == ENOSYS { 73 // fchmodat2 isn't available. If the flags are known to be valid, 74 // return EOPNOTSUPP to indicate that fchmodat doesn't support them. 75 if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 { 76 return EINVAL 77 } else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 { 78 return EOPNOTSUPP 79 } 80 } 81 return err 82 } 83 return fchmodat(dirfd, path, mode) 84 } 85 86 func InotifyInit() (fd int, err error) { 87 return InotifyInit1(0) 88 } 89 90 //sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL 91 //sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL 92 93 // ioctl itself should not be exposed directly, but additional get/set functions 94 // for specific types are permissible. These are defined in ioctl.go and 95 // ioctl_linux.go. 96 // 97 // The third argument to ioctl is often a pointer but sometimes an integer. 98 // Callers should use ioctlPtr when the third argument is a pointer and ioctl 99 // when the third argument is an integer. 100 // 101 // TODO: some existing code incorrectly uses ioctl when it should use ioctlPtr. 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 openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) 128 129 func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { 130 return openat2(dirfd, path, how, SizeofOpenHow) 131 } 132 133 func Pipe(p []int) error { 134 return Pipe2(p, 0) 135 } 136 137 //sysnb pipe2(p *[2]_C_int, flags int) (err error) 138 139 func Pipe2(p []int, flags int) error { 140 if len(p) != 2 { 141 return EINVAL 142 } 143 var pp [2]_C_int 144 err := pipe2(&pp, flags) 145 if err == nil { 146 p[0] = int(pp[0]) 147 p[1] = int(pp[1]) 148 } 149 return err 150 } 151 152 //sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) 153 154 func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { 155 if len(fds) == 0 { 156 return ppoll(nil, 0, timeout, sigmask) 157 } 158 return ppoll(&fds[0], len(fds), timeout, sigmask) 159 } 160 161 func Poll(fds []PollFd, timeout int) (n int, err error) { 162 var ts *Timespec 163 if timeout >= 0 { 164 ts = new(Timespec) 165 *ts = NsecToTimespec(int64(timeout) * 1e6) 166 } 167 return Ppoll(fds, ts, nil) 168 } 169 170 //sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error) 171 172 func Readlink(path string, buf []byte) (n int, err error) { 173 return Readlinkat(AT_FDCWD, path, buf) 174 } 175 176 func Rename(oldpath string, newpath string) (err error) { 177 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath) 178 } 179 180 func Rmdir(path string) error { 181 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR) 182 } 183 184 //sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error) 185 186 func Symlink(oldpath string, newpath string) (err error) { 187 return Symlinkat(oldpath, AT_FDCWD, newpath) 188 } 189 190 func Unlink(path string) error { 191 return Unlinkat(AT_FDCWD, path, 0) 192 } 193 194 //sys Unlinkat(dirfd int, path string, flags int) (err error) 195 196 func Utimes(path string, tv []Timeval) error { 197 if tv == nil { 198 err := utimensat(AT_FDCWD, path, nil, 0) 199 if err != ENOSYS { 200 return err 201 } 202 return utimes(path, nil) 203 } 204 if len(tv) != 2 { 205 return EINVAL 206 } 207 var ts [2]Timespec 208 ts[0] = NsecToTimespec(TimevalToNsec(tv[0])) 209 ts[1] = NsecToTimespec(TimevalToNsec(tv[1])) 210 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 211 if err != ENOSYS { 212 return err 213 } 214 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 215 } 216 217 //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) 218 219 func UtimesNano(path string, ts []Timespec) error { 220 return UtimesNanoAt(AT_FDCWD, path, ts, 0) 221 } 222 223 func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error { 224 if ts == nil { 225 return utimensat(dirfd, path, nil, flags) 226 } 227 if len(ts) != 2 { 228 return EINVAL 229 } 230 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) 231 } 232 233 func Futimesat(dirfd int, path string, tv []Timeval) error { 234 if tv == nil { 235 return futimesat(dirfd, path, nil) 236 } 237 if len(tv) != 2 { 238 return EINVAL 239 } 240 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 241 } 242 243 func Futimes(fd int, tv []Timeval) (err error) { 244 // Believe it or not, this is the best we can do on Linux 245 // (and is what glibc does). 246 return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv) 247 } 248 249 const ImplementsGetwd = true 250 251 //sys Getcwd(buf []byte) (n int, err error) 252 253 func Getwd() (wd string, err error) { 254 var buf [PathMax]byte 255 n, err := Getcwd(buf[0:]) 256 if err != nil { 257 return "", err 258 } 259 // Getcwd returns the number of bytes written to buf, including the NUL. 260 if n < 1 || n > len(buf) || buf[n-1] != 0 { 261 return "", EINVAL 262 } 263 // In some cases, Linux can return a path that starts with the 264 // "(unreachable)" prefix, which can potentially be a valid relative 265 // path. To work around that, return ENOENT if path is not absolute. 266 if buf[0] != '/' { 267 return "", ENOENT 268 } 269 270 return string(buf[0 : n-1]), nil 271 } 272 273 func Getgroups() (gids []int, err error) { 274 n, err := getgroups(0, nil) 275 if err != nil { 276 return nil, err 277 } 278 if n == 0 { 279 return nil, nil 280 } 281 282 // Sanity check group count. Max is 1<<16 on Linux. 283 if n < 0 || n > 1<<20 { 284 return nil, EINVAL 285 } 286 287 a := make([]_Gid_t, n) 288 n, err = getgroups(n, &a[0]) 289 if err != nil { 290 return nil, err 291 } 292 gids = make([]int, n) 293 for i, v := range a[0:n] { 294 gids[i] = int(v) 295 } 296 return 297 } 298 299 func Setgroups(gids []int) (err error) { 300 if len(gids) == 0 { 301 return setgroups(0, nil) 302 } 303 304 a := make([]_Gid_t, len(gids)) 305 for i, v := range gids { 306 a[i] = _Gid_t(v) 307 } 308 return setgroups(len(a), &a[0]) 309 } 310 311 type WaitStatus uint32 312 313 // Wait status is 7 bits at bottom, either 0 (exited), 314 // 0x7F (stopped), or a signal number that caused an exit. 315 // The 0x80 bit is whether there was a core dump. 316 // An extra number (exit code, signal causing a stop) 317 // is in the high bits. At least that's the idea. 318 // There are various irregularities. For example, the 319 // "continued" status is 0xFFFF, distinguishing itself 320 // from stopped via the core dump bit. 321 322 const ( 323 mask = 0x7F 324 core = 0x80 325 exited = 0x00 326 stopped = 0x7F 327 shift = 8 328 ) 329 330 func (w WaitStatus) Exited() bool { return w&mask == exited } 331 332 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 333 334 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 335 336 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 337 338 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 339 340 func (w WaitStatus) ExitStatus() int { 341 if !w.Exited() { 342 return -1 343 } 344 return int(w>>shift) & 0xFF 345 } 346 347 func (w WaitStatus) Signal() syscall.Signal { 348 if !w.Signaled() { 349 return -1 350 } 351 return syscall.Signal(w & mask) 352 } 353 354 func (w WaitStatus) StopSignal() syscall.Signal { 355 if !w.Stopped() { 356 return -1 357 } 358 return syscall.Signal(w>>shift) & 0xFF 359 } 360 361 func (w WaitStatus) TrapCause() int { 362 if w.StopSignal() != SIGTRAP { 363 return -1 364 } 365 return int(w>>shift) >> 8 366 } 367 368 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 369 370 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 371 var status _C_int 372 wpid, err = wait4(pid, &status, options, rusage) 373 if wstatus != nil { 374 *wstatus = WaitStatus(status) 375 } 376 return 377 } 378 379 //sys Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) 380 381 func Mkfifo(path string, mode uint32) error { 382 return Mknod(path, mode|S_IFIFO, 0) 383 } 384 385 func Mkfifoat(dirfd int, path string, mode uint32) error { 386 return Mknodat(dirfd, path, mode|S_IFIFO, 0) 387 } 388 389 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { 390 if sa.Port < 0 || sa.Port > 0xFFFF { 391 return nil, 0, EINVAL 392 } 393 sa.raw.Family = AF_INET 394 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 395 p[0] = byte(sa.Port >> 8) 396 p[1] = byte(sa.Port) 397 sa.raw.Addr = sa.Addr 398 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil 399 } 400 401 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { 402 if sa.Port < 0 || sa.Port > 0xFFFF { 403 return nil, 0, EINVAL 404 } 405 sa.raw.Family = AF_INET6 406 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) 407 p[0] = byte(sa.Port >> 8) 408 p[1] = byte(sa.Port) 409 sa.raw.Scope_id = sa.ZoneId 410 sa.raw.Addr = sa.Addr 411 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil 412 } 413 414 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { 415 name := sa.Name 416 n := len(name) 417 if n >= len(sa.raw.Path) { 418 return nil, 0, EINVAL 419 } 420 sa.raw.Family = AF_UNIX 421 for i := range n { 422 sa.raw.Path[i] = int8(name[i]) 423 } 424 // length is family (uint16), name, NUL. 425 sl := _Socklen(2) 426 if n > 0 { 427 sl += _Socklen(n) + 1 428 } 429 if sa.raw.Path[0] == '@' || (sa.raw.Path[0] == 0 && sl > 3) { 430 // Check sl > 3 so we don't change unnamed socket behavior. 431 sa.raw.Path[0] = 0 432 // Don't count trailing NUL for abstract address. 433 sl-- 434 } 435 436 return unsafe.Pointer(&sa.raw), sl, nil 437 } 438 439 // SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets. 440 type SockaddrLinklayer struct { 441 Protocol uint16 442 Ifindex int 443 Hatype uint16 444 Pkttype uint8 445 Halen uint8 446 Addr [8]byte 447 raw RawSockaddrLinklayer 448 } 449 450 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { 451 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 452 return nil, 0, EINVAL 453 } 454 sa.raw.Family = AF_PACKET 455 sa.raw.Protocol = sa.Protocol 456 sa.raw.Ifindex = int32(sa.Ifindex) 457 sa.raw.Hatype = sa.Hatype 458 sa.raw.Pkttype = sa.Pkttype 459 sa.raw.Halen = sa.Halen 460 sa.raw.Addr = sa.Addr 461 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil 462 } 463 464 // SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets. 465 type SockaddrNetlink struct { 466 Family uint16 467 Pad uint16 468 Pid uint32 469 Groups uint32 470 raw RawSockaddrNetlink 471 } 472 473 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { 474 sa.raw.Family = AF_NETLINK 475 sa.raw.Pad = sa.Pad 476 sa.raw.Pid = sa.Pid 477 sa.raw.Groups = sa.Groups 478 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil 479 } 480 481 // SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets 482 // using the HCI protocol. 483 type SockaddrHCI struct { 484 Dev uint16 485 Channel uint16 486 raw RawSockaddrHCI 487 } 488 489 func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) { 490 sa.raw.Family = AF_BLUETOOTH 491 sa.raw.Dev = sa.Dev 492 sa.raw.Channel = sa.Channel 493 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil 494 } 495 496 // SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets 497 // using the L2CAP protocol. 498 type SockaddrL2 struct { 499 PSM uint16 500 CID uint16 501 Addr [6]uint8 502 AddrType uint8 503 raw RawSockaddrL2 504 } 505 506 func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) { 507 sa.raw.Family = AF_BLUETOOTH 508 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm)) 509 psm[0] = byte(sa.PSM) 510 psm[1] = byte(sa.PSM >> 8) 511 for i := range len(sa.Addr) { 512 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i] 513 } 514 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid)) 515 cid[0] = byte(sa.CID) 516 cid[1] = byte(sa.CID >> 8) 517 sa.raw.Bdaddr_type = sa.AddrType 518 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil 519 } 520 521 // SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets 522 // using the RFCOMM protocol. 523 // 524 // Server example: 525 // 526 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 527 // _ = unix.Bind(fd, &unix.SockaddrRFCOMM{ 528 // Channel: 1, 529 // Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00 530 // }) 531 // _ = Listen(fd, 1) 532 // nfd, sa, _ := Accept(fd) 533 // fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd) 534 // Read(nfd, buf) 535 // 536 // Client example: 537 // 538 // fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) 539 // _ = Connect(fd, &SockaddrRFCOMM{ 540 // Channel: 1, 541 // Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11 542 // }) 543 // Write(fd, []byte(`hello`)) 544 type SockaddrRFCOMM struct { 545 // Addr represents a bluetooth address, byte ordering is little-endian. 546 Addr [6]uint8 547 548 // Channel is a designated bluetooth channel, only 1-30 are available for use. 549 // Since Linux 2.6.7 and further zero value is the first available channel. 550 Channel uint8 551 552 raw RawSockaddrRFCOMM 553 } 554 555 func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) { 556 sa.raw.Family = AF_BLUETOOTH 557 sa.raw.Channel = sa.Channel 558 sa.raw.Bdaddr = sa.Addr 559 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil 560 } 561 562 // SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets. 563 // The RxID and TxID fields are used for transport protocol addressing in 564 // (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with 565 // zero values for CAN_RAW and CAN_BCM sockets as they have no meaning. 566 // 567 // The SockaddrCAN struct must be bound to the socket file descriptor 568 // using Bind before the CAN socket can be used. 569 // 570 // // Read one raw CAN frame 571 // fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW) 572 // addr := &SockaddrCAN{Ifindex: index} 573 // Bind(fd, addr) 574 // frame := make([]byte, 16) 575 // Read(fd, frame) 576 // 577 // The full SocketCAN documentation can be found in the linux kernel 578 // archives at: https://www.kernel.org/doc/Documentation/networking/can.txt 579 type SockaddrCAN struct { 580 Ifindex int 581 RxID uint32 582 TxID uint32 583 raw RawSockaddrCAN 584 } 585 586 func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) { 587 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 588 return nil, 0, EINVAL 589 } 590 sa.raw.Family = AF_CAN 591 sa.raw.Ifindex = int32(sa.Ifindex) 592 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 593 for i := range 4 { 594 sa.raw.Addr[i] = rx[i] 595 } 596 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 597 for i := range 4 { 598 sa.raw.Addr[i+4] = tx[i] 599 } 600 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil 601 } 602 603 // SockaddrCANJ1939 implements the Sockaddr interface for AF_CAN using J1939 604 // protocol (https://en.wikipedia.org/wiki/SAE_J1939). For more information 605 // on the purposes of the fields, check the official linux kernel documentation 606 // available here: https://www.kernel.org/doc/Documentation/networking/j1939.rst 607 type SockaddrCANJ1939 struct { 608 Ifindex int 609 Name uint64 610 PGN uint32 611 Addr uint8 612 raw RawSockaddrCAN 613 } 614 615 func (sa *SockaddrCANJ1939) sockaddr() (unsafe.Pointer, _Socklen, error) { 616 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 617 return nil, 0, EINVAL 618 } 619 sa.raw.Family = AF_CAN 620 sa.raw.Ifindex = int32(sa.Ifindex) 621 n := (*[8]byte)(unsafe.Pointer(&sa.Name)) 622 for i := range 8 { 623 sa.raw.Addr[i] = n[i] 624 } 625 p := (*[4]byte)(unsafe.Pointer(&sa.PGN)) 626 for i := range 4 { 627 sa.raw.Addr[i+8] = p[i] 628 } 629 sa.raw.Addr[12] = sa.Addr 630 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil 631 } 632 633 // SockaddrALG implements the Sockaddr interface for AF_ALG type sockets. 634 // SockaddrALG enables userspace access to the Linux kernel's cryptography 635 // subsystem. The Type and Name fields specify which type of hash or cipher 636 // should be used with a given socket. 637 // 638 // To create a file descriptor that provides access to a hash or cipher, both 639 // Bind and Accept must be used. Once the setup process is complete, input 640 // data can be written to the socket, processed by the kernel, and then read 641 // back as hash output or ciphertext. 642 // 643 // Here is an example of using an AF_ALG socket with SHA1 hashing. 644 // The initial socket setup process is as follows: 645 // 646 // // Open a socket to perform SHA1 hashing. 647 // fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0) 648 // addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"} 649 // unix.Bind(fd, addr) 650 // // Note: unix.Accept does not work at this time; must invoke accept() 651 // // manually using unix.Syscall. 652 // hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0) 653 // 654 // Once a file descriptor has been returned from Accept, it may be used to 655 // perform SHA1 hashing. The descriptor is not safe for concurrent use, but 656 // may be re-used repeatedly with subsequent Write and Read operations. 657 // 658 // When hashing a small byte slice or string, a single Write and Read may 659 // be used: 660 // 661 // // Assume hashfd is already configured using the setup process. 662 // hash := os.NewFile(hashfd, "sha1") 663 // // Hash an input string and read the results. Each Write discards 664 // // previous hash state. Read always reads the current state. 665 // b := make([]byte, 20) 666 // for i := 0; i < 2; i++ { 667 // io.WriteString(hash, "Hello, world.") 668 // hash.Read(b) 669 // fmt.Println(hex.EncodeToString(b)) 670 // } 671 // // Output: 672 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 673 // // 2ae01472317d1935a84797ec1983ae243fc6aa28 674 // 675 // For hashing larger byte slices, or byte streams such as those read from 676 // a file or socket, use Sendto with MSG_MORE to instruct the kernel to update 677 // the hash digest instead of creating a new one for a given chunk and finalizing it. 678 // 679 // // Assume hashfd and addr are already configured using the setup process. 680 // hash := os.NewFile(hashfd, "sha1") 681 // // Hash the contents of a file. 682 // f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz") 683 // b := make([]byte, 4096) 684 // for { 685 // n, err := f.Read(b) 686 // if err == io.EOF { 687 // break 688 // } 689 // unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr) 690 // } 691 // hash.Read(b) 692 // fmt.Println(hex.EncodeToString(b)) 693 // // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5 694 // 695 // For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html. 696 type SockaddrALG struct { 697 Type string 698 Name string 699 Feature uint32 700 Mask uint32 701 raw RawSockaddrALG 702 } 703 704 func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) { 705 // Leave room for NUL byte terminator. 706 if len(sa.Type) > len(sa.raw.Type)-1 { 707 return nil, 0, EINVAL 708 } 709 if len(sa.Name) > len(sa.raw.Name)-1 { 710 return nil, 0, EINVAL 711 } 712 713 sa.raw.Family = AF_ALG 714 sa.raw.Feat = sa.Feature 715 sa.raw.Mask = sa.Mask 716 717 copy(sa.raw.Type[:], sa.Type) 718 copy(sa.raw.Name[:], sa.Name) 719 720 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil 721 } 722 723 // SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets. 724 // SockaddrVM provides access to Linux VM sockets: a mechanism that enables 725 // bidirectional communication between a hypervisor and its guest virtual 726 // machines. 727 type SockaddrVM struct { 728 // CID and Port specify a context ID and port address for a VM socket. 729 // Guests have a unique CID, and hosts may have a well-known CID of: 730 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process. 731 // - VMADDR_CID_LOCAL: refers to local communication (loopback). 732 // - VMADDR_CID_HOST: refers to other processes on the host. 733 CID uint32 734 Port uint32 735 Flags uint8 736 raw RawSockaddrVM 737 } 738 739 func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) { 740 sa.raw.Family = AF_VSOCK 741 sa.raw.Port = sa.Port 742 sa.raw.Cid = sa.CID 743 sa.raw.Flags = sa.Flags 744 745 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil 746 } 747 748 type SockaddrXDP struct { 749 Flags uint16 750 Ifindex uint32 751 QueueID uint32 752 SharedUmemFD uint32 753 raw RawSockaddrXDP 754 } 755 756 func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) { 757 sa.raw.Family = AF_XDP 758 sa.raw.Flags = sa.Flags 759 sa.raw.Ifindex = sa.Ifindex 760 sa.raw.Queue_id = sa.QueueID 761 sa.raw.Shared_umem_fd = sa.SharedUmemFD 762 763 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil 764 } 765 766 // This constant mirrors the #define of PX_PROTO_OE in 767 // linux/if_pppox.h. We're defining this by hand here instead of 768 // autogenerating through mkerrors.sh because including 769 // linux/if_pppox.h causes some declaration conflicts with other 770 // includes (linux/if_pppox.h includes linux/in.h, which conflicts 771 // with netinet/in.h). Given that we only need a single zero constant 772 // out of that file, it's cleaner to just define it by hand here. 773 const px_proto_oe = 0 774 775 type SockaddrPPPoE struct { 776 SID uint16 777 Remote []byte 778 Dev string 779 raw RawSockaddrPPPoX 780 } 781 782 func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) { 783 if len(sa.Remote) != 6 { 784 return nil, 0, EINVAL 785 } 786 if len(sa.Dev) > IFNAMSIZ-1 { 787 return nil, 0, EINVAL 788 } 789 790 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX 791 // This next field is in host-endian byte order. We can't use the 792 // same unsafe pointer cast as above, because this value is not 793 // 32-bit aligned and some architectures don't allow unaligned 794 // access. 795 // 796 // However, the value of px_proto_oe is 0, so we can use 797 // encoding/binary helpers to write the bytes without worrying 798 // about the ordering. 799 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe) 800 // This field is deliberately big-endian, unlike the previous 801 // one. The kernel expects SID to be in network byte order. 802 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID) 803 copy(sa.raw[8:14], sa.Remote) 804 clear(sa.raw[14 : 14+IFNAMSIZ]) 805 copy(sa.raw[14:], sa.Dev) 806 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil 807 } 808 809 // SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets. 810 // For more information on TIPC, see: http://tipc.sourceforge.net/. 811 type SockaddrTIPC struct { 812 // Scope is the publication scopes when binding service/service range. 813 // Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE. 814 Scope int 815 816 // Addr is the type of address used to manipulate a socket. Addr must be 817 // one of: 818 // - *TIPCSocketAddr: "id" variant in the C addr union 819 // - *TIPCServiceRange: "nameseq" variant in the C addr union 820 // - *TIPCServiceName: "name" variant in the C addr union 821 // 822 // If nil, EINVAL will be returned when the structure is used. 823 Addr TIPCAddr 824 825 raw RawSockaddrTIPC 826 } 827 828 // TIPCAddr is implemented by types that can be used as an address for 829 // SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange, 830 // and *TIPCServiceName. 831 type TIPCAddr interface { 832 tipcAddrtype() uint8 833 tipcAddr() [12]byte 834 } 835 836 func (sa *TIPCSocketAddr) tipcAddr() [12]byte { 837 var out [12]byte 838 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:]) 839 return out 840 } 841 842 func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR } 843 844 func (sa *TIPCServiceRange) tipcAddr() [12]byte { 845 var out [12]byte 846 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:]) 847 return out 848 } 849 850 func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE } 851 852 func (sa *TIPCServiceName) tipcAddr() [12]byte { 853 var out [12]byte 854 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:]) 855 return out 856 } 857 858 func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR } 859 860 func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { 861 if sa.Addr == nil { 862 return nil, 0, EINVAL 863 } 864 sa.raw.Family = AF_TIPC 865 sa.raw.Scope = int8(sa.Scope) 866 sa.raw.Addrtype = sa.Addr.tipcAddrtype() 867 sa.raw.Addr = sa.Addr.tipcAddr() 868 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil 869 } 870 871 // SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. 872 type SockaddrL2TPIP struct { 873 Addr [4]byte 874 ConnId uint32 875 raw RawSockaddrL2TPIP 876 } 877 878 func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { 879 sa.raw.Family = AF_INET 880 sa.raw.Conn_id = sa.ConnId 881 sa.raw.Addr = sa.Addr 882 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil 883 } 884 885 // SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets. 886 type SockaddrL2TPIP6 struct { 887 Addr [16]byte 888 ZoneId uint32 889 ConnId uint32 890 raw RawSockaddrL2TPIP6 891 } 892 893 func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) { 894 sa.raw.Family = AF_INET6 895 sa.raw.Conn_id = sa.ConnId 896 sa.raw.Scope_id = sa.ZoneId 897 sa.raw.Addr = sa.Addr 898 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil 899 } 900 901 // SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets. 902 type SockaddrIUCV struct { 903 UserID string 904 Name string 905 raw RawSockaddrIUCV 906 } 907 908 func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { 909 sa.raw.Family = AF_IUCV 910 // These are EBCDIC encoded by the kernel, but we still need to pad them 911 // with blanks. Initializing with blanks allows the caller to feed in either 912 // a padded or an unpadded string. 913 for i := range 8 { 914 sa.raw.Nodeid[i] = ' ' 915 sa.raw.User_id[i] = ' ' 916 sa.raw.Name[i] = ' ' 917 } 918 if len(sa.UserID) > 8 || len(sa.Name) > 8 { 919 return nil, 0, EINVAL 920 } 921 for i, b := range []byte(sa.UserID[:]) { 922 sa.raw.User_id[i] = int8(b) 923 } 924 for i, b := range []byte(sa.Name[:]) { 925 sa.raw.Name[i] = int8(b) 926 } 927 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil 928 } 929 930 type SockaddrNFC struct { 931 DeviceIdx uint32 932 TargetIdx uint32 933 NFCProtocol uint32 934 raw RawSockaddrNFC 935 } 936 937 func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) { 938 sa.raw.Sa_family = AF_NFC 939 sa.raw.Dev_idx = sa.DeviceIdx 940 sa.raw.Target_idx = sa.TargetIdx 941 sa.raw.Nfc_protocol = sa.NFCProtocol 942 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil 943 } 944 945 type SockaddrNFCLLCP struct { 946 DeviceIdx uint32 947 TargetIdx uint32 948 NFCProtocol uint32 949 DestinationSAP uint8 950 SourceSAP uint8 951 ServiceName string 952 raw RawSockaddrNFCLLCP 953 } 954 955 func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) { 956 sa.raw.Sa_family = AF_NFC 957 sa.raw.Dev_idx = sa.DeviceIdx 958 sa.raw.Target_idx = sa.TargetIdx 959 sa.raw.Nfc_protocol = sa.NFCProtocol 960 sa.raw.Dsap = sa.DestinationSAP 961 sa.raw.Ssap = sa.SourceSAP 962 if len(sa.ServiceName) > len(sa.raw.Service_name) { 963 return nil, 0, EINVAL 964 } 965 copy(sa.raw.Service_name[:], sa.ServiceName) 966 sa.raw.SetServiceNameLen(len(sa.ServiceName)) 967 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil 968 } 969 970 var socketProtocol = func(fd int) (int, error) { 971 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) 972 } 973 974 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 975 switch rsa.Addr.Family { 976 case AF_NETLINK: 977 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 978 sa := new(SockaddrNetlink) 979 sa.Family = pp.Family 980 sa.Pad = pp.Pad 981 sa.Pid = pp.Pid 982 sa.Groups = pp.Groups 983 return sa, nil 984 985 case AF_PACKET: 986 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 987 sa := new(SockaddrLinklayer) 988 sa.Protocol = pp.Protocol 989 sa.Ifindex = int(pp.Ifindex) 990 sa.Hatype = pp.Hatype 991 sa.Pkttype = pp.Pkttype 992 sa.Halen = pp.Halen 993 sa.Addr = pp.Addr 994 return sa, nil 995 996 case AF_UNIX: 997 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 998 sa := new(SockaddrUnix) 999 if pp.Path[0] == 0 { 1000 // "Abstract" Unix domain socket. 1001 // Rewrite leading NUL as @ for textual display. 1002 // (This is the standard convention.) 1003 // Not friendly to overwrite in place, 1004 // but the callers below don't care. 1005 pp.Path[0] = '@' 1006 } 1007 1008 // Assume path ends at NUL. 1009 // This is not technically the Linux semantics for 1010 // abstract Unix domain sockets--they are supposed 1011 // to be uninterpreted fixed-size binary blobs--but 1012 // everyone uses this convention. 1013 n := 0 1014 for n < len(pp.Path) && pp.Path[n] != 0 { 1015 n++ 1016 } 1017 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) 1018 return sa, nil 1019 1020 case AF_INET: 1021 proto, err := socketProtocol(fd) 1022 if err != nil { 1023 return nil, err 1024 } 1025 1026 switch proto { 1027 case IPPROTO_L2TP: 1028 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) 1029 sa := new(SockaddrL2TPIP) 1030 sa.ConnId = pp.Conn_id 1031 sa.Addr = pp.Addr 1032 return sa, nil 1033 default: 1034 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 1035 sa := new(SockaddrInet4) 1036 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1037 sa.Port = int(p[0])<<8 + int(p[1]) 1038 sa.Addr = pp.Addr 1039 return sa, nil 1040 } 1041 1042 case AF_INET6: 1043 proto, err := socketProtocol(fd) 1044 if err != nil { 1045 return nil, err 1046 } 1047 1048 switch proto { 1049 case IPPROTO_L2TP: 1050 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) 1051 sa := new(SockaddrL2TPIP6) 1052 sa.ConnId = pp.Conn_id 1053 sa.ZoneId = pp.Scope_id 1054 sa.Addr = pp.Addr 1055 return sa, nil 1056 default: 1057 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 1058 sa := new(SockaddrInet6) 1059 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1060 sa.Port = int(p[0])<<8 + int(p[1]) 1061 sa.ZoneId = pp.Scope_id 1062 sa.Addr = pp.Addr 1063 return sa, nil 1064 } 1065 1066 case AF_VSOCK: 1067 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) 1068 sa := &SockaddrVM{ 1069 CID: pp.Cid, 1070 Port: pp.Port, 1071 Flags: pp.Flags, 1072 } 1073 return sa, nil 1074 case AF_BLUETOOTH: 1075 proto, err := socketProtocol(fd) 1076 if err != nil { 1077 return nil, err 1078 } 1079 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections 1080 switch proto { 1081 case BTPROTO_L2CAP: 1082 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa)) 1083 sa := &SockaddrL2{ 1084 PSM: pp.Psm, 1085 CID: pp.Cid, 1086 Addr: pp.Bdaddr, 1087 AddrType: pp.Bdaddr_type, 1088 } 1089 return sa, nil 1090 case BTPROTO_RFCOMM: 1091 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa)) 1092 sa := &SockaddrRFCOMM{ 1093 Channel: pp.Channel, 1094 Addr: pp.Bdaddr, 1095 } 1096 return sa, nil 1097 } 1098 case AF_XDP: 1099 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa)) 1100 sa := &SockaddrXDP{ 1101 Flags: pp.Flags, 1102 Ifindex: pp.Ifindex, 1103 QueueID: pp.Queue_id, 1104 SharedUmemFD: pp.Shared_umem_fd, 1105 } 1106 return sa, nil 1107 case AF_PPPOX: 1108 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) 1109 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { 1110 return nil, EINVAL 1111 } 1112 sa := &SockaddrPPPoE{ 1113 SID: binary.BigEndian.Uint16(pp[6:8]), 1114 Remote: pp[8:14], 1115 } 1116 for i := 14; i < 14+IFNAMSIZ; i++ { 1117 if pp[i] == 0 { 1118 sa.Dev = string(pp[14:i]) 1119 break 1120 } 1121 } 1122 return sa, nil 1123 case AF_TIPC: 1124 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa)) 1125 1126 sa := &SockaddrTIPC{ 1127 Scope: int(pp.Scope), 1128 } 1129 1130 // Determine which union variant is present in pp.Addr by checking 1131 // pp.Addrtype. 1132 switch pp.Addrtype { 1133 case TIPC_SERVICE_RANGE: 1134 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr)) 1135 case TIPC_SERVICE_ADDR: 1136 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr)) 1137 case TIPC_SOCKET_ADDR: 1138 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr)) 1139 default: 1140 return nil, EINVAL 1141 } 1142 1143 return sa, nil 1144 case AF_IUCV: 1145 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa)) 1146 1147 var user [8]byte 1148 var name [8]byte 1149 1150 for i := range 8 { 1151 user[i] = byte(pp.User_id[i]) 1152 name[i] = byte(pp.Name[i]) 1153 } 1154 1155 sa := &SockaddrIUCV{ 1156 UserID: string(user[:]), 1157 Name: string(name[:]), 1158 } 1159 return sa, nil 1160 1161 case AF_CAN: 1162 proto, err := socketProtocol(fd) 1163 if err != nil { 1164 return nil, err 1165 } 1166 1167 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa)) 1168 1169 switch proto { 1170 case CAN_J1939: 1171 sa := &SockaddrCANJ1939{ 1172 Ifindex: int(pp.Ifindex), 1173 } 1174 name := (*[8]byte)(unsafe.Pointer(&sa.Name)) 1175 for i := range 8 { 1176 name[i] = pp.Addr[i] 1177 } 1178 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) 1179 for i := range 4 { 1180 pgn[i] = pp.Addr[i+8] 1181 } 1182 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) 1183 addr[0] = pp.Addr[12] 1184 return sa, nil 1185 default: 1186 sa := &SockaddrCAN{ 1187 Ifindex: int(pp.Ifindex), 1188 } 1189 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 1190 for i := range 4 { 1191 rx[i] = pp.Addr[i] 1192 } 1193 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 1194 for i := range 4 { 1195 tx[i] = pp.Addr[i+4] 1196 } 1197 return sa, nil 1198 } 1199 case AF_NFC: 1200 proto, err := socketProtocol(fd) 1201 if err != nil { 1202 return nil, err 1203 } 1204 switch proto { 1205 case NFC_SOCKPROTO_RAW: 1206 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa)) 1207 sa := &SockaddrNFC{ 1208 DeviceIdx: pp.Dev_idx, 1209 TargetIdx: pp.Target_idx, 1210 NFCProtocol: pp.Nfc_protocol, 1211 } 1212 return sa, nil 1213 case NFC_SOCKPROTO_LLCP: 1214 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa)) 1215 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) { 1216 return nil, EINVAL 1217 } 1218 sa := &SockaddrNFCLLCP{ 1219 DeviceIdx: pp.Dev_idx, 1220 TargetIdx: pp.Target_idx, 1221 NFCProtocol: pp.Nfc_protocol, 1222 DestinationSAP: pp.Dsap, 1223 SourceSAP: pp.Ssap, 1224 ServiceName: string(pp.Service_name[:pp.Service_name_len]), 1225 } 1226 return sa, nil 1227 default: 1228 return nil, EINVAL 1229 } 1230 } 1231 return nil, EAFNOSUPPORT 1232 } 1233 1234 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 1235 var rsa RawSockaddrAny 1236 var len _Socklen = SizeofSockaddrAny 1237 nfd, err = accept4(fd, &rsa, &len, 0) 1238 if err != nil { 1239 return 1240 } 1241 sa, err = anyToSockaddr(fd, &rsa) 1242 if err != nil { 1243 Close(nfd) 1244 nfd = 0 1245 } 1246 return 1247 } 1248 1249 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 1250 var rsa RawSockaddrAny 1251 var len _Socklen = SizeofSockaddrAny 1252 nfd, err = accept4(fd, &rsa, &len, flags) 1253 if err != nil { 1254 return 1255 } 1256 if len > SizeofSockaddrAny { 1257 panic("RawSockaddrAny too small") 1258 } 1259 sa, err = anyToSockaddr(fd, &rsa) 1260 if err != nil { 1261 Close(nfd) 1262 nfd = 0 1263 } 1264 return 1265 } 1266 1267 func Getsockname(fd int) (sa Sockaddr, err error) { 1268 var rsa RawSockaddrAny 1269 var len _Socklen = SizeofSockaddrAny 1270 if err = getsockname(fd, &rsa, &len); err != nil { 1271 return 1272 } 1273 return anyToSockaddr(fd, &rsa) 1274 } 1275 1276 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 1277 var value IPMreqn 1278 vallen := _Socklen(SizeofIPMreqn) 1279 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1280 return &value, err 1281 } 1282 1283 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 1284 var value Ucred 1285 vallen := _Socklen(SizeofUcred) 1286 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1287 return &value, err 1288 } 1289 1290 func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { 1291 var value TCPInfo 1292 vallen := _Socklen(SizeofTCPInfo) 1293 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1294 return &value, err 1295 } 1296 1297 // GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas" 1298 // algorithm. 1299 // 1300 // The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1301 // 1302 // algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1303 func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) { 1304 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1305 vallen := _Socklen(SizeofTCPCCInfo) 1306 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1307 out := (*TCPVegasInfo)(unsafe.Pointer(&value[0])) 1308 return out, err 1309 } 1310 1311 // GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp" 1312 // algorithm. 1313 // 1314 // The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1315 // 1316 // algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1317 func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) { 1318 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1319 vallen := _Socklen(SizeofTCPCCInfo) 1320 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1321 out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0])) 1322 return out, err 1323 } 1324 1325 // GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr" 1326 // algorithm. 1327 // 1328 // The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1329 // 1330 // algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1331 func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) { 1332 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1333 vallen := _Socklen(SizeofTCPCCInfo) 1334 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1335 out := (*TCPBBRInfo)(unsafe.Pointer(&value[0])) 1336 return out, err 1337 } 1338 1339 // GetsockoptString returns the string value of the socket option opt for the 1340 // socket associated with fd at the given socket level. 1341 func GetsockoptString(fd, level, opt int) (string, error) { 1342 buf := make([]byte, 256) 1343 vallen := _Socklen(len(buf)) 1344 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1345 if err != nil { 1346 if err == ERANGE { 1347 buf = make([]byte, vallen) 1348 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1349 } 1350 if err != nil { 1351 return "", err 1352 } 1353 } 1354 return ByteSliceToString(buf[:vallen]), nil 1355 } 1356 1357 func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) { 1358 var value TpacketStats 1359 vallen := _Socklen(SizeofTpacketStats) 1360 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1361 return &value, err 1362 } 1363 1364 func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) { 1365 var value TpacketStatsV3 1366 vallen := _Socklen(SizeofTpacketStatsV3) 1367 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1368 return &value, err 1369 } 1370 1371 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 1372 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1373 } 1374 1375 func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error { 1376 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1377 } 1378 1379 // SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a 1380 // socket to filter incoming packets. See 'man 7 socket' for usage information. 1381 func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error { 1382 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) 1383 } 1384 1385 func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error { 1386 var p unsafe.Pointer 1387 if len(filter) > 0 { 1388 p = unsafe.Pointer(&filter[0]) 1389 } 1390 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) 1391 } 1392 1393 func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error { 1394 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1395 } 1396 1397 func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { 1398 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1399 } 1400 1401 func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) { 1402 if len(o) == 0 { 1403 return EINVAL 1404 } 1405 return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o))) 1406 } 1407 1408 func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error { 1409 return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s)) 1410 } 1411 1412 // Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) 1413 1414 // KeyctlInt calls keyctl commands in which each argument is an int. 1415 // These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK, 1416 // KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT, 1417 // KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT, 1418 // KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT. 1419 //sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL 1420 1421 // KeyctlBuffer calls keyctl commands in which the third and fourth 1422 // arguments are a buffer and its length, respectively. 1423 // These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE. 1424 //sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL 1425 1426 // KeyctlString calls keyctl commands which return a string. 1427 // These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY. 1428 func KeyctlString(cmd int, id int) (string, error) { 1429 // We must loop as the string data may change in between the syscalls. 1430 // We could allocate a large buffer here to reduce the chance that the 1431 // syscall needs to be called twice; however, this is unnecessary as 1432 // the performance loss is negligible. 1433 var buffer []byte 1434 for { 1435 // Try to fill the buffer with data 1436 length, err := KeyctlBuffer(cmd, id, buffer, 0) 1437 if err != nil { 1438 return "", err 1439 } 1440 1441 // Check if the data was written 1442 if length <= len(buffer) { 1443 // Exclude the null terminator 1444 return string(buffer[:length-1]), nil 1445 } 1446 1447 // Make a bigger buffer if needed 1448 buffer = make([]byte, length) 1449 } 1450 } 1451 1452 // Keyctl commands with special signatures. 1453 1454 // KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command. 1455 // See the full documentation at: 1456 // http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html 1457 func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) { 1458 createInt := 0 1459 if create { 1460 createInt = 1 1461 } 1462 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0) 1463 } 1464 1465 // KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the 1466 // key handle permission mask as described in the "keyctl setperm" section of 1467 // http://man7.org/linux/man-pages/man1/keyctl.1.html. 1468 // See the full documentation at: 1469 // http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html 1470 func KeyctlSetperm(id int, perm uint32) error { 1471 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0) 1472 return err 1473 } 1474 1475 //sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL 1476 1477 // KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command. 1478 // See the full documentation at: 1479 // http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html 1480 func KeyctlJoinSessionKeyring(name string) (ringid int, err error) { 1481 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name) 1482 } 1483 1484 //sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL 1485 1486 // KeyctlSearch implements the KEYCTL_SEARCH command. 1487 // See the full documentation at: 1488 // http://man7.org/linux/man-pages/man3/keyctl_search.3.html 1489 func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) { 1490 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid) 1491 } 1492 1493 //sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL 1494 1495 // KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This 1496 // command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice 1497 // of Iovec (each of which represents a buffer) instead of a single buffer. 1498 // See the full documentation at: 1499 // http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html 1500 func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error { 1501 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid) 1502 } 1503 1504 //sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL 1505 1506 // KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command 1507 // computes a Diffie-Hellman shared secret based on the provide params. The 1508 // secret is written to the provided buffer and the returned size is the number 1509 // of bytes written (returning an error if there is insufficient space in the 1510 // buffer). If a nil buffer is passed in, this function returns the minimum 1511 // buffer length needed to store the appropriate data. Note that this differs 1512 // from KEYCTL_READ's behavior which always returns the requested payload size. 1513 // See the full documentation at: 1514 // http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html 1515 func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { 1516 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) 1517 } 1518 1519 // KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This 1520 // command limits the set of keys that can be linked to the keyring, regardless 1521 // of keyring permissions. The command requires the "setattr" permission. 1522 // 1523 // When called with an empty keyType the command locks the keyring, preventing 1524 // any further keys from being linked to the keyring. 1525 // 1526 // The "asymmetric" keyType defines restrictions requiring key payloads to be 1527 // DER encoded X.509 certificates signed by keys in another keyring. Restrictions 1528 // for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted", 1529 // "key_or_keyring:<key>", and "key_or_keyring:<key>:chain". 1530 // 1531 // As of Linux 4.12, only the "asymmetric" keyType defines type-specific 1532 // restrictions. 1533 // 1534 // See the full documentation at: 1535 // http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html 1536 // http://man7.org/linux/man-pages/man2/keyctl.2.html 1537 func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error { 1538 if keyType == "" { 1539 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) 1540 } 1541 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) 1542 } 1543 1544 //sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL 1545 //sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL 1546 1547 func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { 1548 var msg Msghdr 1549 msg.Name = (*byte)(unsafe.Pointer(rsa)) 1550 msg.Namelen = uint32(SizeofSockaddrAny) 1551 var dummy byte 1552 if len(oob) > 0 { 1553 if emptyIovecs(iov) { 1554 var sockType int 1555 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1556 if err != nil { 1557 return 1558 } 1559 // receive at least one normal byte 1560 if sockType != SOCK_DGRAM { 1561 var iova [1]Iovec 1562 iova[0].Base = &dummy 1563 iova[0].SetLen(1) 1564 iov = iova[:] 1565 } 1566 } 1567 msg.Control = &oob[0] 1568 msg.SetControllen(len(oob)) 1569 } 1570 if len(iov) > 0 { 1571 msg.Iov = &iov[0] 1572 msg.SetIovlen(len(iov)) 1573 } 1574 if n, err = recvmsg(fd, &msg, flags); err != nil { 1575 return 1576 } 1577 oobn = int(msg.Controllen) 1578 recvflags = int(msg.Flags) 1579 return 1580 } 1581 1582 func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { 1583 var msg Msghdr 1584 msg.Name = (*byte)(ptr) 1585 msg.Namelen = uint32(salen) 1586 var dummy byte 1587 var empty bool 1588 if len(oob) > 0 { 1589 empty = emptyIovecs(iov) 1590 if empty { 1591 var sockType int 1592 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1593 if err != nil { 1594 return 0, err 1595 } 1596 // send at least one normal byte 1597 if sockType != SOCK_DGRAM { 1598 var iova [1]Iovec 1599 iova[0].Base = &dummy 1600 iova[0].SetLen(1) 1601 iov = iova[:] 1602 } 1603 } 1604 msg.Control = &oob[0] 1605 msg.SetControllen(len(oob)) 1606 } 1607 if len(iov) > 0 { 1608 msg.Iov = &iov[0] 1609 msg.SetIovlen(len(iov)) 1610 } 1611 if n, err = sendmsg(fd, &msg, flags); err != nil { 1612 return 0, err 1613 } 1614 if len(oob) > 0 && empty { 1615 n = 0 1616 } 1617 return n, nil 1618 } 1619 1620 // BindToDevice binds the socket associated with fd to device. 1621 func BindToDevice(fd int, device string) (err error) { 1622 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 1623 } 1624 1625 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 1626 //sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE 1627 1628 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 1629 // The peek requests are machine-size oriented, so we wrap it 1630 // to retrieve arbitrary-length data. 1631 1632 // The ptrace syscall differs from glibc's ptrace. 1633 // Peeks returns the word in *data, not as the return value. 1634 1635 var buf [SizeofPtr]byte 1636 1637 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 1638 // access (PEEKUSER warns that it might), but if we don't 1639 // align our reads, we might straddle an unmapped page 1640 // boundary and not get the bytes leading up to the page 1641 // boundary. 1642 n := 0 1643 if addr%SizeofPtr != 0 { 1644 err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) 1645 if err != nil { 1646 return 0, err 1647 } 1648 n += copy(out, buf[addr%SizeofPtr:]) 1649 out = out[n:] 1650 } 1651 1652 // Remainder. 1653 for len(out) > 0 { 1654 // We use an internal buffer to guarantee alignment. 1655 // It's not documented if this is necessary, but we're paranoid. 1656 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) 1657 if err != nil { 1658 return n, err 1659 } 1660 copied := copy(out, buf[0:]) 1661 n += copied 1662 out = out[copied:] 1663 } 1664 1665 return n, nil 1666 } 1667 1668 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 1669 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 1670 } 1671 1672 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 1673 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 1674 } 1675 1676 func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) { 1677 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out) 1678 } 1679 1680 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 1681 // As for ptracePeek, we need to align our accesses to deal 1682 // with the possibility of straddling an invalid page. 1683 1684 // Leading edge. 1685 n := 0 1686 if addr%SizeofPtr != 0 { 1687 var buf [SizeofPtr]byte 1688 err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) 1689 if err != nil { 1690 return 0, err 1691 } 1692 n += copy(buf[addr%SizeofPtr:], data) 1693 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1694 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word) 1695 if err != nil { 1696 return 0, err 1697 } 1698 data = data[n:] 1699 } 1700 1701 // Interior. 1702 for len(data) > SizeofPtr { 1703 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 1704 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1705 if err != nil { 1706 return n, err 1707 } 1708 n += SizeofPtr 1709 data = data[SizeofPtr:] 1710 } 1711 1712 // Trailing edge. 1713 if len(data) > 0 { 1714 var buf [SizeofPtr]byte 1715 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) 1716 if err != nil { 1717 return n, err 1718 } 1719 copy(buf[0:], data) 1720 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1721 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1722 if err != nil { 1723 return n, err 1724 } 1725 n += len(data) 1726 } 1727 1728 return n, nil 1729 } 1730 1731 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 1732 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 1733 } 1734 1735 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 1736 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 1737 } 1738 1739 func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { 1740 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) 1741 } 1742 1743 // elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so 1744 // x/sys/unix doesn't need to depend on debug/elf and thus 1745 // compress/zlib, debug/dwarf, and other packages. 1746 const elfNT_PRSTATUS = 1 1747 1748 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 1749 var iov Iovec 1750 iov.Base = (*byte)(unsafe.Pointer(regsout)) 1751 iov.SetLen(int(unsafe.Sizeof(*regsout))) 1752 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) 1753 } 1754 1755 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 1756 var iov Iovec 1757 iov.Base = (*byte)(unsafe.Pointer(regs)) 1758 iov.SetLen(int(unsafe.Sizeof(*regs))) 1759 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) 1760 } 1761 1762 func PtraceSetOptions(pid int, options int) (err error) { 1763 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 1764 } 1765 1766 func PtraceGetEventMsg(pid int) (msg uint, err error) { 1767 var data _C_long 1768 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data)) 1769 msg = uint(data) 1770 return 1771 } 1772 1773 func PtraceCont(pid int, signal int) (err error) { 1774 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 1775 } 1776 1777 func PtraceSyscall(pid int, signal int) (err error) { 1778 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 1779 } 1780 1781 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 1782 1783 func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) } 1784 1785 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 1786 1787 func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) } 1788 1789 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 1790 1791 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 1792 1793 func Reboot(cmd int) (err error) { 1794 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 1795 } 1796 1797 func direntIno(buf []byte) (uint64, bool) { 1798 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 1799 } 1800 1801 func direntReclen(buf []byte) (uint64, bool) { 1802 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 1803 } 1804 1805 func direntNamlen(buf []byte) (uint64, bool) { 1806 reclen, ok := direntReclen(buf) 1807 if !ok { 1808 return 0, false 1809 } 1810 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 1811 } 1812 1813 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 1814 1815 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 1816 // Certain file systems get rather angry and EINVAL if you give 1817 // them an empty string of data, rather than NULL. 1818 if data == "" { 1819 return mount(source, target, fstype, flags, nil) 1820 } 1821 datap, err := BytePtrFromString(data) 1822 if err != nil { 1823 return err 1824 } 1825 return mount(source, target, fstype, flags, datap) 1826 } 1827 1828 //sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR 1829 1830 // MountSetattr is a wrapper for mount_setattr(2). 1831 // https://man7.org/linux/man-pages/man2/mount_setattr.2.html 1832 // 1833 // Requires kernel >= 5.12. 1834 func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error { 1835 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr)) 1836 } 1837 1838 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 1839 if raceenabled { 1840 raceReleaseMerge(unsafe.Pointer(&ioSync)) 1841 } 1842 return sendfile(outfd, infd, offset, count) 1843 } 1844 1845 // Sendto 1846 // Recvfrom 1847 // Socketpair 1848 1849 /* 1850 * Direct access 1851 */ 1852 //sys Acct(path string) (err error) 1853 //sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) 1854 //sys Adjtimex(buf *Timex) (state int, err error) 1855 //sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error) 1856 //sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) 1857 //sys Chdir(path string) (err error) 1858 //sys Chroot(path string) (err error) 1859 //sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error) 1860 //sys ClockGetres(clockid int32, res *Timespec) (err error) 1861 //sys ClockGettime(clockid int32, time *Timespec) (err error) 1862 //sys ClockSettime(clockid int32, time *Timespec) (err error) 1863 //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) 1864 //sys Close(fd int) (err error) 1865 //sys CloseRange(first uint, last uint, flags uint) (err error) 1866 //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 1867 //sys DeleteModule(name string, flags int) (err error) 1868 //sys Dup(oldfd int) (fd int, err error) 1869 1870 func Dup2(oldfd, newfd int) error { 1871 return Dup3(oldfd, newfd, 0) 1872 } 1873 1874 //sys Dup3(oldfd int, newfd int, flags int) (err error) 1875 //sysnb EpollCreate1(flag int) (fd int, err error) 1876 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 1877 //sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 1878 //sys Exit(code int) = SYS_EXIT_GROUP 1879 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 1880 //sys Fchdir(fd int) (err error) 1881 //sys Fchmod(fd int, mode uint32) (err error) 1882 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 1883 //sys Fdatasync(fd int) (err error) 1884 //sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) 1885 //sys FinitModule(fd int, params string, flags int) (err error) 1886 //sys Flistxattr(fd int, dest []byte) (sz int, err error) 1887 //sys Flock(fd int, how int) (err error) 1888 //sys Fremovexattr(fd int, attr string) (err error) 1889 //sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) 1890 //sys Fsync(fd int) (err error) 1891 //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) 1892 //sys Fsopen(fsName string, flags int) (fd int, err error) 1893 //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) 1894 1895 //sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) 1896 1897 func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { 1898 var keyp *byte 1899 if keyp, err = BytePtrFromString(key); err != nil { 1900 return 1901 } 1902 return fsconfig(fd, cmd, keyp, value, aux) 1903 } 1904 1905 // FsconfigSetFlag is equivalent to fsconfig(2) called 1906 // with cmd == FSCONFIG_SET_FLAG. 1907 // 1908 // fd is the filesystem context to act upon. 1909 // key the parameter key to set. 1910 func FsconfigSetFlag(fd int, key string) (err error) { 1911 return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) 1912 } 1913 1914 // FsconfigSetString is equivalent to fsconfig(2) called 1915 // with cmd == FSCONFIG_SET_STRING. 1916 // 1917 // fd is the filesystem context to act upon. 1918 // key the parameter key to set. 1919 // value is the parameter value to set. 1920 func FsconfigSetString(fd int, key string, value string) (err error) { 1921 var valuep *byte 1922 if valuep, err = BytePtrFromString(value); err != nil { 1923 return 1924 } 1925 return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) 1926 } 1927 1928 // FsconfigSetBinary is equivalent to fsconfig(2) called 1929 // with cmd == FSCONFIG_SET_BINARY. 1930 // 1931 // fd is the filesystem context to act upon. 1932 // key the parameter key to set. 1933 // value is the parameter value to set. 1934 func FsconfigSetBinary(fd int, key string, value []byte) (err error) { 1935 if len(value) == 0 { 1936 return EINVAL 1937 } 1938 return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) 1939 } 1940 1941 // FsconfigSetPath is equivalent to fsconfig(2) called 1942 // with cmd == FSCONFIG_SET_PATH. 1943 // 1944 // fd is the filesystem context to act upon. 1945 // key the parameter key to set. 1946 // path is a non-empty path for specified key. 1947 // atfd is a file descriptor at which to start lookup from or AT_FDCWD. 1948 func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { 1949 var valuep *byte 1950 if valuep, err = BytePtrFromString(path); err != nil { 1951 return 1952 } 1953 return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) 1954 } 1955 1956 // FsconfigSetPathEmpty is equivalent to fsconfig(2) called 1957 // with cmd == FSCONFIG_SET_PATH_EMPTY. The same as 1958 // FconfigSetPath but with AT_PATH_EMPTY implied. 1959 func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { 1960 var valuep *byte 1961 if valuep, err = BytePtrFromString(path); err != nil { 1962 return 1963 } 1964 return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) 1965 } 1966 1967 // FsconfigSetFd is equivalent to fsconfig(2) called 1968 // with cmd == FSCONFIG_SET_FD. 1969 // 1970 // fd is the filesystem context to act upon. 1971 // key the parameter key to set. 1972 // value is a file descriptor to be assigned to specified key. 1973 func FsconfigSetFd(fd int, key string, value int) (err error) { 1974 return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) 1975 } 1976 1977 // FsconfigCreate is equivalent to fsconfig(2) called 1978 // with cmd == FSCONFIG_CMD_CREATE. 1979 // 1980 // fd is the filesystem context to act upon. 1981 func FsconfigCreate(fd int) (err error) { 1982 return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) 1983 } 1984 1985 // FsconfigReconfigure is equivalent to fsconfig(2) called 1986 // with cmd == FSCONFIG_CMD_RECONFIGURE. 1987 // 1988 // fd is the filesystem context to act upon. 1989 func FsconfigReconfigure(fd int) (err error) { 1990 return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) 1991 } 1992 1993 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 1994 //sysnb Getpgid(pid int) (pgid int, err error) 1995 1996 func Getpgrp() (pid int) { 1997 pid, _ = Getpgid(0) 1998 return 1999 } 2000 2001 //sysnb Getpid() (pid int) 2002 //sysnb Getppid() (ppid int) 2003 //sys Getpriority(which int, who int) (prio int, err error) 2004 2005 func Getrandom(buf []byte, flags int) (n int, err error) { 2006 vdsoRet, supported := vgetrandom(buf, uint32(flags)) 2007 if supported { 2008 if vdsoRet < 0 { 2009 return 0, errnoErr(syscall.Errno(-vdsoRet)) 2010 } 2011 return vdsoRet, nil 2012 } 2013 var p *byte 2014 if len(buf) > 0 { 2015 p = &buf[0] 2016 } 2017 r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags)) 2018 if e != 0 { 2019 return 0, errnoErr(e) 2020 } 2021 return int(r), nil 2022 } 2023 2024 //sysnb Getrusage(who int, rusage *Rusage) (err error) 2025 //sysnb Getsid(pid int) (sid int, err error) 2026 //sysnb Gettid() (tid int) 2027 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 2028 //sys InitModule(moduleImage []byte, params string) (err error) 2029 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 2030 //sysnb InotifyInit1(flags int) (fd int, err error) 2031 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 2032 //sysnb Kill(pid int, sig syscall.Signal) (err error) 2033 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 2034 //sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error) 2035 //sys Listxattr(path string, dest []byte) (sz int, err error) 2036 //sys Llistxattr(path string, dest []byte) (sz int, err error) 2037 //sys Lremovexattr(path string, attr string) (err error) 2038 //sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) 2039 //sys MemfdCreate(name string, flags int) (fd int, err error) 2040 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 2041 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 2042 //sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error) 2043 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 2044 //sys OpenTree(dfd int, fileName string, flags uint) (r int, err error) 2045 //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) 2046 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 2047 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) 2048 //sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) 2049 //sys read(fd int, p []byte) (n int, err error) 2050 //sys Removexattr(path string, attr string) (err error) 2051 //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) 2052 //sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) 2053 //sys Setdomainname(p []byte) (err error) 2054 //sys Sethostname(p []byte) (err error) 2055 //sysnb Setpgid(pid int, pgid int) (err error) 2056 //sysnb Setsid() (pid int, err error) 2057 //sysnb Settimeofday(tv *Timeval) (err error) 2058 //sys Setns(fd int, nstype int) (err error) 2059 2060 //go:linkname syscall_prlimit syscall.prlimit 2061 func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error 2062 2063 func Prlimit(pid, resource int, newlimit, old *Rlimit) error { 2064 // Just call the syscall version, because as of Go 1.21 2065 // it will affect starting a new process. 2066 return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old)) 2067 } 2068 2069 // PrctlRetInt performs a prctl operation specified by option and further 2070 // optional arguments arg2 through arg5 depending on option. It returns a 2071 // non-negative integer that is returned by the prctl syscall. 2072 func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) { 2073 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) 2074 if err != 0 { 2075 return 0, err 2076 } 2077 return int(ret), nil 2078 } 2079 2080 func Setuid(uid int) (err error) { 2081 return syscall.Setuid(uid) 2082 } 2083 2084 func Setgid(gid int) (err error) { 2085 return syscall.Setgid(gid) 2086 } 2087 2088 func Setreuid(ruid, euid int) (err error) { 2089 return syscall.Setreuid(ruid, euid) 2090 } 2091 2092 func Setregid(rgid, egid int) (err error) { 2093 return syscall.Setregid(rgid, egid) 2094 } 2095 2096 func Setresuid(ruid, euid, suid int) (err error) { 2097 return syscall.Setresuid(ruid, euid, suid) 2098 } 2099 2100 func Setresgid(rgid, egid, sgid int) (err error) { 2101 return syscall.Setresgid(rgid, egid, sgid) 2102 } 2103 2104 // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. 2105 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability. 2106 // If the call fails due to other reasons, current fsgid will be returned. 2107 func SetfsgidRetGid(gid int) (int, error) { 2108 return setfsgid(gid) 2109 } 2110 2111 // SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set. 2112 // setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability 2113 // If the call fails due to other reasons, current fsuid will be returned. 2114 func SetfsuidRetUid(uid int) (int, error) { 2115 return setfsuid(uid) 2116 } 2117 2118 func Setfsgid(gid int) error { 2119 _, err := setfsgid(gid) 2120 return err 2121 } 2122 2123 func Setfsuid(uid int) error { 2124 _, err := setfsuid(uid) 2125 return err 2126 } 2127 2128 func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { 2129 return signalfd(fd, sigmask, _C__NSIG/8, flags) 2130 } 2131 2132 //sys Setpriority(which int, who int, prio int) (err error) 2133 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) 2134 //sys signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4 2135 //sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) 2136 //sys Sync() 2137 //sys Syncfs(fd int) (err error) 2138 //sysnb Sysinfo(info *Sysinfo_t) (err error) 2139 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 2140 //sysnb TimerfdCreate(clockid int, flags int) (fd int, err error) 2141 //sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error) 2142 //sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) 2143 //sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) 2144 //sysnb Times(tms *Tms) (ticks uintptr, err error) 2145 //sysnb Umask(mask int) (oldmask int) 2146 //sysnb Uname(buf *Utsname) (err error) 2147 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 2148 //sys Unshare(flags int) (err error) 2149 //sys write(fd int, p []byte) (n int, err error) 2150 //sys exitThread(code int) (err error) = SYS_EXIT 2151 //sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV 2152 //sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV 2153 //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV 2154 //sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV 2155 //sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 2156 //sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 2157 2158 // minIovec is the size of the small initial allocation used by 2159 // Readv, Writev, etc. 2160 // 2161 // This small allocation gets stack allocated, which lets the 2162 // common use case of len(iovs) <= minIovs avoid more expensive 2163 // heap allocations. 2164 const minIovec = 8 2165 2166 // appendBytes converts bs to Iovecs and appends them to vecs. 2167 func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { 2168 for _, b := range bs { 2169 var v Iovec 2170 v.SetLen(len(b)) 2171 if len(b) > 0 { 2172 v.Base = &b[0] 2173 } else { 2174 v.Base = (*byte)(unsafe.Pointer(&_zero)) 2175 } 2176 vecs = append(vecs, v) 2177 } 2178 return vecs 2179 } 2180 2181 // offs2lohi splits offs into its low and high order bits. 2182 func offs2lohi(offs int64) (lo, hi uintptr) { 2183 const longBits = SizeofLong * 8 2184 return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet 2185 } 2186 2187 func Readv(fd int, iovs [][]byte) (n int, err error) { 2188 iovecs := make([]Iovec, 0, minIovec) 2189 iovecs = appendBytes(iovecs, iovs) 2190 n, err = readv(fd, iovecs) 2191 readvRacedetect(iovecs, n, err) 2192 return n, err 2193 } 2194 2195 func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { 2196 iovecs := make([]Iovec, 0, minIovec) 2197 iovecs = appendBytes(iovecs, iovs) 2198 lo, hi := offs2lohi(offset) 2199 n, err = preadv(fd, iovecs, lo, hi) 2200 readvRacedetect(iovecs, n, err) 2201 return n, err 2202 } 2203 2204 func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2205 iovecs := make([]Iovec, 0, minIovec) 2206 iovecs = appendBytes(iovecs, iovs) 2207 lo, hi := offs2lohi(offset) 2208 n, err = preadv2(fd, iovecs, lo, hi, flags) 2209 readvRacedetect(iovecs, n, err) 2210 return n, err 2211 } 2212 2213 func readvRacedetect(iovecs []Iovec, n int, err error) { 2214 if !raceenabled { 2215 return 2216 } 2217 for i := 0; n > 0 && i < len(iovecs); i++ { 2218 m := min(int(iovecs[i].Len), n) 2219 n -= m 2220 if m > 0 { 2221 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) 2222 } 2223 } 2224 if err == nil { 2225 raceAcquire(unsafe.Pointer(&ioSync)) 2226 } 2227 } 2228 2229 func Writev(fd int, iovs [][]byte) (n int, err error) { 2230 iovecs := make([]Iovec, 0, minIovec) 2231 iovecs = appendBytes(iovecs, iovs) 2232 if raceenabled { 2233 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2234 } 2235 n, err = writev(fd, iovecs) 2236 writevRacedetect(iovecs, n) 2237 return n, err 2238 } 2239 2240 func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { 2241 iovecs := make([]Iovec, 0, minIovec) 2242 iovecs = appendBytes(iovecs, iovs) 2243 if raceenabled { 2244 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2245 } 2246 lo, hi := offs2lohi(offset) 2247 n, err = pwritev(fd, iovecs, lo, hi) 2248 writevRacedetect(iovecs, n) 2249 return n, err 2250 } 2251 2252 func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2253 iovecs := make([]Iovec, 0, minIovec) 2254 iovecs = appendBytes(iovecs, iovs) 2255 if raceenabled { 2256 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2257 } 2258 lo, hi := offs2lohi(offset) 2259 n, err = pwritev2(fd, iovecs, lo, hi, flags) 2260 writevRacedetect(iovecs, n) 2261 return n, err 2262 } 2263 2264 func writevRacedetect(iovecs []Iovec, n int) { 2265 if !raceenabled { 2266 return 2267 } 2268 for i := 0; n > 0 && i < len(iovecs); i++ { 2269 m := min(int(iovecs[i].Len), n) 2270 n -= m 2271 if m > 0 { 2272 raceReadRange(unsafe.Pointer(iovecs[i].Base), m) 2273 } 2274 } 2275 } 2276 2277 // mmap varies by architecture; see syscall_linux_*.go. 2278 //sys munmap(addr uintptr, length uintptr) (err error) 2279 //sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) 2280 //sys Madvise(b []byte, advice int) (err error) 2281 //sys Mprotect(b []byte, prot int) (err error) 2282 //sys Mlock(b []byte) (err error) 2283 //sys Mlockall(flags int) (err error) 2284 //sys Msync(b []byte, flags int) (err error) 2285 //sys Munlock(b []byte) (err error) 2286 //sys Munlockall() (err error) 2287 2288 const ( 2289 mremapFixed = MREMAP_FIXED 2290 mremapDontunmap = MREMAP_DONTUNMAP 2291 mremapMaymove = MREMAP_MAYMOVE 2292 ) 2293 2294 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, 2295 // using the specified flags. 2296 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { 2297 var p unsafe.Pointer 2298 if len(iovs) > 0 { 2299 p = unsafe.Pointer(&iovs[0]) 2300 } 2301 2302 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0) 2303 if errno != 0 { 2304 return 0, syscall.Errno(errno) 2305 } 2306 2307 return int(n), nil 2308 } 2309 2310 func isGroupMember(gid int) bool { 2311 groups, err := Getgroups() 2312 if err != nil { 2313 return false 2314 } 2315 2316 return slices.Contains(groups, gid) 2317 } 2318 2319 func isCapDacOverrideSet() bool { 2320 hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3} 2321 data := [2]CapUserData{} 2322 err := Capget(&hdr, &data[0]) 2323 2324 return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0 2325 } 2326 2327 //sys faccessat(dirfd int, path string, mode uint32) (err error) 2328 //sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) 2329 2330 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 2331 if flags == 0 { 2332 return faccessat(dirfd, path, mode) 2333 } 2334 2335 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM { 2336 return err 2337 } 2338 2339 // The Linux kernel faccessat system call does not take any flags. 2340 // The glibc faccessat implements the flags itself; see 2341 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 2342 // Because people naturally expect syscall.Faccessat to act 2343 // like C faccessat, we do the same. 2344 2345 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { 2346 return EINVAL 2347 } 2348 2349 var st Stat_t 2350 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { 2351 return err 2352 } 2353 2354 mode &= 7 2355 if mode == 0 { 2356 return nil 2357 } 2358 2359 var uid int 2360 if flags&AT_EACCESS != 0 { 2361 uid = Geteuid() 2362 if uid != 0 && isCapDacOverrideSet() { 2363 // If CAP_DAC_OVERRIDE is set, file access check is 2364 // done by the kernel in the same way as for root 2365 // (see generic_permission() in the Linux sources). 2366 uid = 0 2367 } 2368 } else { 2369 uid = Getuid() 2370 } 2371 2372 if uid == 0 { 2373 if mode&1 == 0 { 2374 // Root can read and write any file. 2375 return nil 2376 } 2377 if st.Mode&0111 != 0 { 2378 // Root can execute any file that anybody can execute. 2379 return nil 2380 } 2381 return EACCES 2382 } 2383 2384 var fmode uint32 2385 if uint32(uid) == st.Uid { 2386 fmode = (st.Mode >> 6) & 7 2387 } else { 2388 var gid int 2389 if flags&AT_EACCESS != 0 { 2390 gid = Getegid() 2391 } else { 2392 gid = Getgid() 2393 } 2394 2395 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) { 2396 fmode = (st.Mode >> 3) & 7 2397 } else { 2398 fmode = st.Mode & 7 2399 } 2400 } 2401 2402 if fmode&mode == mode { 2403 return nil 2404 } 2405 2406 return EACCES 2407 } 2408 2409 //sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT 2410 //sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT 2411 2412 // fileHandle is the argument to nameToHandleAt and openByHandleAt. We 2413 // originally tried to generate it via unix/linux/types.go with "type 2414 // fileHandle C.struct_file_handle" but that generated empty structs 2415 // for mips64 and mips64le. Instead, hard code it for now (it's the 2416 // same everywhere else) until the mips64 generator issue is fixed. 2417 type fileHandle struct { 2418 Bytes uint32 2419 Type int32 2420 } 2421 2422 // FileHandle represents the C struct file_handle used by 2423 // name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see 2424 // OpenByHandleAt). 2425 type FileHandle struct { 2426 *fileHandle 2427 } 2428 2429 // NewFileHandle constructs a FileHandle. 2430 func NewFileHandle(handleType int32, handle []byte) FileHandle { 2431 const hdrSize = unsafe.Sizeof(fileHandle{}) 2432 buf := make([]byte, hdrSize+uintptr(len(handle))) 2433 copy(buf[hdrSize:], handle) 2434 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2435 fh.Type = handleType 2436 fh.Bytes = uint32(len(handle)) 2437 return FileHandle{fh} 2438 } 2439 2440 func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) } 2441 func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type } 2442 func (fh *FileHandle) Bytes() []byte { 2443 n := fh.Size() 2444 if n == 0 { 2445 return nil 2446 } 2447 return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n) 2448 } 2449 2450 // NameToHandleAt wraps the name_to_handle_at system call; it obtains 2451 // a handle for a path name. 2452 func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) { 2453 var mid _C_int 2454 // Try first with a small buffer, assuming the handle will 2455 // only be 32 bytes. 2456 size := uint32(32 + unsafe.Sizeof(fileHandle{})) 2457 didResize := false 2458 for { 2459 buf := make([]byte, size) 2460 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2461 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{})) 2462 err = nameToHandleAt(dirfd, path, fh, &mid, flags) 2463 if err == EOVERFLOW { 2464 if didResize { 2465 // We shouldn't need to resize more than once 2466 return 2467 } 2468 didResize = true 2469 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{})) 2470 continue 2471 } 2472 if err != nil { 2473 return 2474 } 2475 return FileHandle{fh}, int(mid), nil 2476 } 2477 } 2478 2479 // OpenByHandleAt wraps the open_by_handle_at system call; it opens a 2480 // file via a handle as previously returned by NameToHandleAt. 2481 func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) { 2482 return openByHandleAt(mountFD, handle.fileHandle, flags) 2483 } 2484 2485 // Klogset wraps the sys_syslog system call; it sets console_loglevel to 2486 // the value specified by arg and passes a dummy pointer to bufp. 2487 func Klogset(typ int, arg int) (err error) { 2488 var p unsafe.Pointer 2489 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg)) 2490 if errno != 0 { 2491 return errnoErr(errno) 2492 } 2493 return nil 2494 } 2495 2496 // RemoteIovec is Iovec with the pointer replaced with an integer. 2497 // It is used for ProcessVMReadv and ProcessVMWritev, where the pointer 2498 // refers to a location in a different process' address space, which 2499 // would confuse the Go garbage collector. 2500 type RemoteIovec struct { 2501 Base uintptr 2502 Len int 2503 } 2504 2505 //sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV 2506 //sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV 2507 2508 //sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN 2509 //sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD 2510 //sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL 2511 2512 //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) 2513 //sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) 2514 //sys shmdt(addr uintptr) (err error) 2515 //sys shmget(key int, size int, flag int) (id int, err error) 2516 2517 //sys getitimer(which int, currValue *Itimerval) (err error) 2518 //sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) 2519 2520 // MakeItimerval creates an Itimerval from interval and value durations. 2521 func MakeItimerval(interval, value time.Duration) Itimerval { 2522 return Itimerval{ 2523 Interval: NsecToTimeval(interval.Nanoseconds()), 2524 Value: NsecToTimeval(value.Nanoseconds()), 2525 } 2526 } 2527 2528 // A value which may be passed to the which parameter for Getitimer and 2529 // Setitimer. 2530 type ItimerWhich int 2531 2532 // Possible which values for Getitimer and Setitimer. 2533 const ( 2534 ItimerReal ItimerWhich = ITIMER_REAL 2535 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL 2536 ItimerProf ItimerWhich = ITIMER_PROF 2537 ) 2538 2539 // Getitimer wraps getitimer(2) to return the current value of the timer 2540 // specified by which. 2541 func Getitimer(which ItimerWhich) (Itimerval, error) { 2542 var it Itimerval 2543 if err := getitimer(int(which), &it); err != nil { 2544 return Itimerval{}, err 2545 } 2546 2547 return it, nil 2548 } 2549 2550 // Setitimer wraps setitimer(2) to arm or disarm the timer specified by which. 2551 // It returns the previous value of the timer. 2552 // 2553 // If the Itimerval argument is the zero value, the timer will be disarmed. 2554 func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) { 2555 var prev Itimerval 2556 if err := setitimer(int(which), &it, &prev); err != nil { 2557 return Itimerval{}, err 2558 } 2559 2560 return prev, nil 2561 } 2562 2563 //sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK 2564 2565 func PthreadSigmask(how int, set, oldset *Sigset_t) error { 2566 if oldset != nil { 2567 // Explicitly clear in case Sigset_t is larger than _C__NSIG. 2568 *oldset = Sigset_t{} 2569 } 2570 return rtSigprocmask(how, set, oldset, _C__NSIG/8) 2571 } 2572 2573 //sysnb getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) 2574 //sysnb getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) 2575 2576 func Getresuid() (ruid, euid, suid int) { 2577 var r, e, s _C_int 2578 getresuid(&r, &e, &s) 2579 return int(r), int(e), int(s) 2580 } 2581 2582 func Getresgid() (rgid, egid, sgid int) { 2583 var r, e, s _C_int 2584 getresgid(&r, &e, &s) 2585 return int(r), int(e), int(s) 2586 } 2587 2588 // Pselect is a wrapper around the Linux pselect6 system call. 2589 // This version does not modify the timeout argument. 2590 func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { 2591 // Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES, 2592 // The Linux pselect6() system call modifies its timeout argument. 2593 // [Not modifying the argument] is the behavior required by POSIX.1-2001. 2594 var mutableTimeout *Timespec 2595 if timeout != nil { 2596 mutableTimeout = new(Timespec) 2597 *mutableTimeout = *timeout 2598 } 2599 2600 // The final argument of the pselect6() system call is not a 2601 // sigset_t * pointer, but is instead a structure 2602 var kernelMask *sigset_argpack 2603 if sigmask != nil { 2604 wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize 2605 2606 // A sigset stores one bit per signal, 2607 // offset by 1 (because signal 0 does not exist). 2608 // So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉. 2609 sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits) 2610 2611 sigsetBytes := uintptr(sigsetWords * (wordBits / 8)) 2612 kernelMask = &sigset_argpack{ 2613 ss: sigmask, 2614 ssLen: sigsetBytes, 2615 } 2616 } 2617 2618 return pselect6(nfd, r, w, e, mutableTimeout, kernelMask) 2619 } 2620 2621 //sys schedSetattr(pid int, attr *SchedAttr, flags uint) (err error) 2622 //sys schedGetattr(pid int, attr *SchedAttr, size uint, flags uint) (err error) 2623 2624 // SchedSetAttr is a wrapper for sched_setattr(2) syscall. 2625 // https://man7.org/linux/man-pages/man2/sched_setattr.2.html 2626 func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error { 2627 if attr == nil { 2628 return EINVAL 2629 } 2630 attr.Size = SizeofSchedAttr 2631 return schedSetattr(pid, attr, flags) 2632 } 2633 2634 // SchedGetAttr is a wrapper for sched_getattr(2) syscall. 2635 // https://man7.org/linux/man-pages/man2/sched_getattr.2.html 2636 func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { 2637 attr := &SchedAttr{} 2638 if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil { 2639 return nil, err 2640 } 2641 return attr, nil 2642 } 2643 2644 //sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) 2645 //sys Mseal(b []byte, flags uint) (err error) 2646 2647 //sys setMemPolicy(mode int, mask *CPUSet, size int) (err error) = SYS_SET_MEMPOLICY 2648 2649 func SetMemPolicy(mode int, mask *CPUSet) error { 2650 return setMemPolicy(mode, mask, _CPU_SETSIZE) 2651 }