a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
at main 82 kB view raw
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 12package unix 13 14import ( 15 "encoding/binary" 16 "slices" 17 "strconv" 18 "syscall" 19 "time" 20 "unsafe" 21) 22 23/* 24 * Wrapped 25 */ 26 27func Access(path string, mode uint32) (err error) { 28 return Faccessat(AT_FDCWD, path, mode, 0) 29} 30 31func Chmod(path string, mode uint32) (err error) { 32 return Fchmodat(AT_FDCWD, path, mode, 0) 33} 34 35func Chown(path string, uid int, gid int) (err error) { 36 return Fchownat(AT_FDCWD, path, uid, gid, 0) 37} 38 39func Creat(path string, mode uint32) (fd int, err error) { 40 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 41} 42 43func 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 53func 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 67func 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 86func 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 105func Link(oldpath string, newpath string) (err error) { 106 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0) 107} 108 109func Mkdir(path string, mode uint32) (err error) { 110 return Mkdirat(AT_FDCWD, path, mode) 111} 112 113func Mknod(path string, mode uint32, dev int) (err error) { 114 return Mknodat(AT_FDCWD, path, mode, dev) 115} 116 117func 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 123func 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 129func Openat2(dirfd int, path string, how *OpenHow) (fd int, err error) { 130 return openat2(dirfd, path, how, SizeofOpenHow) 131} 132 133func Pipe(p []int) error { 134 return Pipe2(p, 0) 135} 136 137//sysnb pipe2(p *[2]_C_int, flags int) (err error) 138 139func 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 154func 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 161func 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 172func Readlink(path string, buf []byte) (n int, err error) { 173 return Readlinkat(AT_FDCWD, path, buf) 174} 175 176func Rename(oldpath string, newpath string) (err error) { 177 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath) 178} 179 180func 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 186func Symlink(oldpath string, newpath string) (err error) { 187 return Symlinkat(oldpath, AT_FDCWD, newpath) 188} 189 190func 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 196func 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 219func UtimesNano(path string, ts []Timespec) error { 220 return UtimesNanoAt(AT_FDCWD, path, ts, 0) 221} 222 223func 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 233func 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 243func 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 249const ImplementsGetwd = true 250 251//sys Getcwd(buf []byte) (n int, err error) 252 253func 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 273func 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 299func 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 311type 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 322const ( 323 mask = 0x7F 324 core = 0x80 325 exited = 0x00 326 stopped = 0x7F 327 shift = 8 328) 329 330func (w WaitStatus) Exited() bool { return w&mask == exited } 331 332func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 333 334func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 335 336func (w WaitStatus) Continued() bool { return w == 0xFFFF } 337 338func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 339 340func (w WaitStatus) ExitStatus() int { 341 if !w.Exited() { 342 return -1 343 } 344 return int(w>>shift) & 0xFF 345} 346 347func (w WaitStatus) Signal() syscall.Signal { 348 if !w.Signaled() { 349 return -1 350 } 351 return syscall.Signal(w & mask) 352} 353 354func (w WaitStatus) StopSignal() syscall.Signal { 355 if !w.Stopped() { 356 return -1 357 } 358 return syscall.Signal(w>>shift) & 0xFF 359} 360 361func (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 370func 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 381func Mkfifo(path string, mode uint32) error { 382 return Mknod(path, mode|S_IFIFO, 0) 383} 384 385func Mkfifoat(dirfd int, path string, mode uint32) error { 386 return Mknodat(dirfd, path, mode|S_IFIFO, 0) 387} 388 389func (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 401func (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 414func (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. 440type 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 450func (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. 465type SockaddrNetlink struct { 466 Family uint16 467 Pad uint16 468 Pid uint32 469 Groups uint32 470 raw RawSockaddrNetlink 471} 472 473func (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. 483type SockaddrHCI struct { 484 Dev uint16 485 Channel uint16 486 raw RawSockaddrHCI 487} 488 489func (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. 498type SockaddrL2 struct { 499 PSM uint16 500 CID uint16 501 Addr [6]uint8 502 AddrType uint8 503 raw RawSockaddrL2 504} 505 506func (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`)) 544type 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 555func (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 579type SockaddrCAN struct { 580 Ifindex int 581 RxID uint32 582 TxID uint32 583 raw RawSockaddrCAN 584} 585 586func (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 607type SockaddrCANJ1939 struct { 608 Ifindex int 609 Name uint64 610 PGN uint32 611 Addr uint8 612 raw RawSockaddrCAN 613} 614 615func (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. 696type SockaddrALG struct { 697 Type string 698 Name string 699 Feature uint32 700 Mask uint32 701 raw RawSockaddrALG 702} 703 704func (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. 727type 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 739func (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 748type SockaddrXDP struct { 749 Flags uint16 750 Ifindex uint32 751 QueueID uint32 752 SharedUmemFD uint32 753 raw RawSockaddrXDP 754} 755 756func (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. 773const px_proto_oe = 0 774 775type SockaddrPPPoE struct { 776 SID uint16 777 Remote []byte 778 Dev string 779 raw RawSockaddrPPPoX 780} 781 782func (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 for i := 14; i < 14+IFNAMSIZ; i++ { 805 sa.raw[i] = 0 806 } 807 copy(sa.raw[14:], sa.Dev) 808 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil 809} 810 811// SockaddrTIPC implements the Sockaddr interface for AF_TIPC type sockets. 812// For more information on TIPC, see: http://tipc.sourceforge.net/. 813type SockaddrTIPC struct { 814 // Scope is the publication scopes when binding service/service range. 815 // Should be set to TIPC_CLUSTER_SCOPE or TIPC_NODE_SCOPE. 816 Scope int 817 818 // Addr is the type of address used to manipulate a socket. Addr must be 819 // one of: 820 // - *TIPCSocketAddr: "id" variant in the C addr union 821 // - *TIPCServiceRange: "nameseq" variant in the C addr union 822 // - *TIPCServiceName: "name" variant in the C addr union 823 // 824 // If nil, EINVAL will be returned when the structure is used. 825 Addr TIPCAddr 826 827 raw RawSockaddrTIPC 828} 829 830// TIPCAddr is implemented by types that can be used as an address for 831// SockaddrTIPC. It is only implemented by *TIPCSocketAddr, *TIPCServiceRange, 832// and *TIPCServiceName. 833type TIPCAddr interface { 834 tipcAddrtype() uint8 835 tipcAddr() [12]byte 836} 837 838func (sa *TIPCSocketAddr) tipcAddr() [12]byte { 839 var out [12]byte 840 copy(out[:], (*(*[unsafe.Sizeof(TIPCSocketAddr{})]byte)(unsafe.Pointer(sa)))[:]) 841 return out 842} 843 844func (sa *TIPCSocketAddr) tipcAddrtype() uint8 { return TIPC_SOCKET_ADDR } 845 846func (sa *TIPCServiceRange) tipcAddr() [12]byte { 847 var out [12]byte 848 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceRange{})]byte)(unsafe.Pointer(sa)))[:]) 849 return out 850} 851 852func (sa *TIPCServiceRange) tipcAddrtype() uint8 { return TIPC_SERVICE_RANGE } 853 854func (sa *TIPCServiceName) tipcAddr() [12]byte { 855 var out [12]byte 856 copy(out[:], (*(*[unsafe.Sizeof(TIPCServiceName{})]byte)(unsafe.Pointer(sa)))[:]) 857 return out 858} 859 860func (sa *TIPCServiceName) tipcAddrtype() uint8 { return TIPC_SERVICE_ADDR } 861 862func (sa *SockaddrTIPC) sockaddr() (unsafe.Pointer, _Socklen, error) { 863 if sa.Addr == nil { 864 return nil, 0, EINVAL 865 } 866 sa.raw.Family = AF_TIPC 867 sa.raw.Scope = int8(sa.Scope) 868 sa.raw.Addrtype = sa.Addr.tipcAddrtype() 869 sa.raw.Addr = sa.Addr.tipcAddr() 870 return unsafe.Pointer(&sa.raw), SizeofSockaddrTIPC, nil 871} 872 873// SockaddrL2TPIP implements the Sockaddr interface for IPPROTO_L2TP/AF_INET sockets. 874type SockaddrL2TPIP struct { 875 Addr [4]byte 876 ConnId uint32 877 raw RawSockaddrL2TPIP 878} 879 880func (sa *SockaddrL2TPIP) sockaddr() (unsafe.Pointer, _Socklen, error) { 881 sa.raw.Family = AF_INET 882 sa.raw.Conn_id = sa.ConnId 883 sa.raw.Addr = sa.Addr 884 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP, nil 885} 886 887// SockaddrL2TPIP6 implements the Sockaddr interface for IPPROTO_L2TP/AF_INET6 sockets. 888type SockaddrL2TPIP6 struct { 889 Addr [16]byte 890 ZoneId uint32 891 ConnId uint32 892 raw RawSockaddrL2TPIP6 893} 894 895func (sa *SockaddrL2TPIP6) sockaddr() (unsafe.Pointer, _Socklen, error) { 896 sa.raw.Family = AF_INET6 897 sa.raw.Conn_id = sa.ConnId 898 sa.raw.Scope_id = sa.ZoneId 899 sa.raw.Addr = sa.Addr 900 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2TPIP6, nil 901} 902 903// SockaddrIUCV implements the Sockaddr interface for AF_IUCV sockets. 904type SockaddrIUCV struct { 905 UserID string 906 Name string 907 raw RawSockaddrIUCV 908} 909 910func (sa *SockaddrIUCV) sockaddr() (unsafe.Pointer, _Socklen, error) { 911 sa.raw.Family = AF_IUCV 912 // These are EBCDIC encoded by the kernel, but we still need to pad them 913 // with blanks. Initializing with blanks allows the caller to feed in either 914 // a padded or an unpadded string. 915 for i := range 8 { 916 sa.raw.Nodeid[i] = ' ' 917 sa.raw.User_id[i] = ' ' 918 sa.raw.Name[i] = ' ' 919 } 920 if len(sa.UserID) > 8 || len(sa.Name) > 8 { 921 return nil, 0, EINVAL 922 } 923 for i, b := range []byte(sa.UserID[:]) { 924 sa.raw.User_id[i] = int8(b) 925 } 926 for i, b := range []byte(sa.Name[:]) { 927 sa.raw.Name[i] = int8(b) 928 } 929 return unsafe.Pointer(&sa.raw), SizeofSockaddrIUCV, nil 930} 931 932type SockaddrNFC struct { 933 DeviceIdx uint32 934 TargetIdx uint32 935 NFCProtocol uint32 936 raw RawSockaddrNFC 937} 938 939func (sa *SockaddrNFC) sockaddr() (unsafe.Pointer, _Socklen, error) { 940 sa.raw.Sa_family = AF_NFC 941 sa.raw.Dev_idx = sa.DeviceIdx 942 sa.raw.Target_idx = sa.TargetIdx 943 sa.raw.Nfc_protocol = sa.NFCProtocol 944 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFC, nil 945} 946 947type SockaddrNFCLLCP struct { 948 DeviceIdx uint32 949 TargetIdx uint32 950 NFCProtocol uint32 951 DestinationSAP uint8 952 SourceSAP uint8 953 ServiceName string 954 raw RawSockaddrNFCLLCP 955} 956 957func (sa *SockaddrNFCLLCP) sockaddr() (unsafe.Pointer, _Socklen, error) { 958 sa.raw.Sa_family = AF_NFC 959 sa.raw.Dev_idx = sa.DeviceIdx 960 sa.raw.Target_idx = sa.TargetIdx 961 sa.raw.Nfc_protocol = sa.NFCProtocol 962 sa.raw.Dsap = sa.DestinationSAP 963 sa.raw.Ssap = sa.SourceSAP 964 if len(sa.ServiceName) > len(sa.raw.Service_name) { 965 return nil, 0, EINVAL 966 } 967 copy(sa.raw.Service_name[:], sa.ServiceName) 968 sa.raw.SetServiceNameLen(len(sa.ServiceName)) 969 return unsafe.Pointer(&sa.raw), SizeofSockaddrNFCLLCP, nil 970} 971 972var socketProtocol = func(fd int) (int, error) { 973 return GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL) 974} 975 976func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { 977 switch rsa.Addr.Family { 978 case AF_NETLINK: 979 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 980 sa := new(SockaddrNetlink) 981 sa.Family = pp.Family 982 sa.Pad = pp.Pad 983 sa.Pid = pp.Pid 984 sa.Groups = pp.Groups 985 return sa, nil 986 987 case AF_PACKET: 988 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 989 sa := new(SockaddrLinklayer) 990 sa.Protocol = pp.Protocol 991 sa.Ifindex = int(pp.Ifindex) 992 sa.Hatype = pp.Hatype 993 sa.Pkttype = pp.Pkttype 994 sa.Halen = pp.Halen 995 sa.Addr = pp.Addr 996 return sa, nil 997 998 case AF_UNIX: 999 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 1000 sa := new(SockaddrUnix) 1001 if pp.Path[0] == 0 { 1002 // "Abstract" Unix domain socket. 1003 // Rewrite leading NUL as @ for textual display. 1004 // (This is the standard convention.) 1005 // Not friendly to overwrite in place, 1006 // but the callers below don't care. 1007 pp.Path[0] = '@' 1008 } 1009 1010 // Assume path ends at NUL. 1011 // This is not technically the Linux semantics for 1012 // abstract Unix domain sockets--they are supposed 1013 // to be uninterpreted fixed-size binary blobs--but 1014 // everyone uses this convention. 1015 n := 0 1016 for n < len(pp.Path) && pp.Path[n] != 0 { 1017 n++ 1018 } 1019 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n)) 1020 return sa, nil 1021 1022 case AF_INET: 1023 proto, err := socketProtocol(fd) 1024 if err != nil { 1025 return nil, err 1026 } 1027 1028 switch proto { 1029 case IPPROTO_L2TP: 1030 pp := (*RawSockaddrL2TPIP)(unsafe.Pointer(rsa)) 1031 sa := new(SockaddrL2TPIP) 1032 sa.ConnId = pp.Conn_id 1033 sa.Addr = pp.Addr 1034 return sa, nil 1035 default: 1036 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 1037 sa := new(SockaddrInet4) 1038 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1039 sa.Port = int(p[0])<<8 + int(p[1]) 1040 sa.Addr = pp.Addr 1041 return sa, nil 1042 } 1043 1044 case AF_INET6: 1045 proto, err := socketProtocol(fd) 1046 if err != nil { 1047 return nil, err 1048 } 1049 1050 switch proto { 1051 case IPPROTO_L2TP: 1052 pp := (*RawSockaddrL2TPIP6)(unsafe.Pointer(rsa)) 1053 sa := new(SockaddrL2TPIP6) 1054 sa.ConnId = pp.Conn_id 1055 sa.ZoneId = pp.Scope_id 1056 sa.Addr = pp.Addr 1057 return sa, nil 1058 default: 1059 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 1060 sa := new(SockaddrInet6) 1061 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 1062 sa.Port = int(p[0])<<8 + int(p[1]) 1063 sa.ZoneId = pp.Scope_id 1064 sa.Addr = pp.Addr 1065 return sa, nil 1066 } 1067 1068 case AF_VSOCK: 1069 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa)) 1070 sa := &SockaddrVM{ 1071 CID: pp.Cid, 1072 Port: pp.Port, 1073 Flags: pp.Flags, 1074 } 1075 return sa, nil 1076 case AF_BLUETOOTH: 1077 proto, err := socketProtocol(fd) 1078 if err != nil { 1079 return nil, err 1080 } 1081 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections 1082 switch proto { 1083 case BTPROTO_L2CAP: 1084 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa)) 1085 sa := &SockaddrL2{ 1086 PSM: pp.Psm, 1087 CID: pp.Cid, 1088 Addr: pp.Bdaddr, 1089 AddrType: pp.Bdaddr_type, 1090 } 1091 return sa, nil 1092 case BTPROTO_RFCOMM: 1093 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa)) 1094 sa := &SockaddrRFCOMM{ 1095 Channel: pp.Channel, 1096 Addr: pp.Bdaddr, 1097 } 1098 return sa, nil 1099 } 1100 case AF_XDP: 1101 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa)) 1102 sa := &SockaddrXDP{ 1103 Flags: pp.Flags, 1104 Ifindex: pp.Ifindex, 1105 QueueID: pp.Queue_id, 1106 SharedUmemFD: pp.Shared_umem_fd, 1107 } 1108 return sa, nil 1109 case AF_PPPOX: 1110 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa)) 1111 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe { 1112 return nil, EINVAL 1113 } 1114 sa := &SockaddrPPPoE{ 1115 SID: binary.BigEndian.Uint16(pp[6:8]), 1116 Remote: pp[8:14], 1117 } 1118 for i := 14; i < 14+IFNAMSIZ; i++ { 1119 if pp[i] == 0 { 1120 sa.Dev = string(pp[14:i]) 1121 break 1122 } 1123 } 1124 return sa, nil 1125 case AF_TIPC: 1126 pp := (*RawSockaddrTIPC)(unsafe.Pointer(rsa)) 1127 1128 sa := &SockaddrTIPC{ 1129 Scope: int(pp.Scope), 1130 } 1131 1132 // Determine which union variant is present in pp.Addr by checking 1133 // pp.Addrtype. 1134 switch pp.Addrtype { 1135 case TIPC_SERVICE_RANGE: 1136 sa.Addr = (*TIPCServiceRange)(unsafe.Pointer(&pp.Addr)) 1137 case TIPC_SERVICE_ADDR: 1138 sa.Addr = (*TIPCServiceName)(unsafe.Pointer(&pp.Addr)) 1139 case TIPC_SOCKET_ADDR: 1140 sa.Addr = (*TIPCSocketAddr)(unsafe.Pointer(&pp.Addr)) 1141 default: 1142 return nil, EINVAL 1143 } 1144 1145 return sa, nil 1146 case AF_IUCV: 1147 pp := (*RawSockaddrIUCV)(unsafe.Pointer(rsa)) 1148 1149 var user [8]byte 1150 var name [8]byte 1151 1152 for i := range 8 { 1153 user[i] = byte(pp.User_id[i]) 1154 name[i] = byte(pp.Name[i]) 1155 } 1156 1157 sa := &SockaddrIUCV{ 1158 UserID: string(user[:]), 1159 Name: string(name[:]), 1160 } 1161 return sa, nil 1162 1163 case AF_CAN: 1164 proto, err := socketProtocol(fd) 1165 if err != nil { 1166 return nil, err 1167 } 1168 1169 pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa)) 1170 1171 switch proto { 1172 case CAN_J1939: 1173 sa := &SockaddrCANJ1939{ 1174 Ifindex: int(pp.Ifindex), 1175 } 1176 name := (*[8]byte)(unsafe.Pointer(&sa.Name)) 1177 for i := range 8 { 1178 name[i] = pp.Addr[i] 1179 } 1180 pgn := (*[4]byte)(unsafe.Pointer(&sa.PGN)) 1181 for i := range 4 { 1182 pgn[i] = pp.Addr[i+8] 1183 } 1184 addr := (*[1]byte)(unsafe.Pointer(&sa.Addr)) 1185 addr[0] = pp.Addr[12] 1186 return sa, nil 1187 default: 1188 sa := &SockaddrCAN{ 1189 Ifindex: int(pp.Ifindex), 1190 } 1191 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID)) 1192 for i := range 4 { 1193 rx[i] = pp.Addr[i] 1194 } 1195 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID)) 1196 for i := range 4 { 1197 tx[i] = pp.Addr[i+4] 1198 } 1199 return sa, nil 1200 } 1201 case AF_NFC: 1202 proto, err := socketProtocol(fd) 1203 if err != nil { 1204 return nil, err 1205 } 1206 switch proto { 1207 case NFC_SOCKPROTO_RAW: 1208 pp := (*RawSockaddrNFC)(unsafe.Pointer(rsa)) 1209 sa := &SockaddrNFC{ 1210 DeviceIdx: pp.Dev_idx, 1211 TargetIdx: pp.Target_idx, 1212 NFCProtocol: pp.Nfc_protocol, 1213 } 1214 return sa, nil 1215 case NFC_SOCKPROTO_LLCP: 1216 pp := (*RawSockaddrNFCLLCP)(unsafe.Pointer(rsa)) 1217 if uint64(pp.Service_name_len) > uint64(len(pp.Service_name)) { 1218 return nil, EINVAL 1219 } 1220 sa := &SockaddrNFCLLCP{ 1221 DeviceIdx: pp.Dev_idx, 1222 TargetIdx: pp.Target_idx, 1223 NFCProtocol: pp.Nfc_protocol, 1224 DestinationSAP: pp.Dsap, 1225 SourceSAP: pp.Ssap, 1226 ServiceName: string(pp.Service_name[:pp.Service_name_len]), 1227 } 1228 return sa, nil 1229 default: 1230 return nil, EINVAL 1231 } 1232 } 1233 return nil, EAFNOSUPPORT 1234} 1235 1236func Accept(fd int) (nfd int, sa Sockaddr, err error) { 1237 var rsa RawSockaddrAny 1238 var len _Socklen = SizeofSockaddrAny 1239 nfd, err = accept4(fd, &rsa, &len, 0) 1240 if err != nil { 1241 return 1242 } 1243 sa, err = anyToSockaddr(fd, &rsa) 1244 if err != nil { 1245 Close(nfd) 1246 nfd = 0 1247 } 1248 return 1249} 1250 1251func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 1252 var rsa RawSockaddrAny 1253 var len _Socklen = SizeofSockaddrAny 1254 nfd, err = accept4(fd, &rsa, &len, flags) 1255 if err != nil { 1256 return 1257 } 1258 if len > SizeofSockaddrAny { 1259 panic("RawSockaddrAny too small") 1260 } 1261 sa, err = anyToSockaddr(fd, &rsa) 1262 if err != nil { 1263 Close(nfd) 1264 nfd = 0 1265 } 1266 return 1267} 1268 1269func Getsockname(fd int) (sa Sockaddr, err error) { 1270 var rsa RawSockaddrAny 1271 var len _Socklen = SizeofSockaddrAny 1272 if err = getsockname(fd, &rsa, &len); err != nil { 1273 return 1274 } 1275 return anyToSockaddr(fd, &rsa) 1276} 1277 1278func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 1279 var value IPMreqn 1280 vallen := _Socklen(SizeofIPMreqn) 1281 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1282 return &value, err 1283} 1284 1285func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 1286 var value Ucred 1287 vallen := _Socklen(SizeofUcred) 1288 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1289 return &value, err 1290} 1291 1292func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { 1293 var value TCPInfo 1294 vallen := _Socklen(SizeofTCPInfo) 1295 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1296 return &value, err 1297} 1298 1299// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas" 1300// algorithm. 1301// 1302// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1303// 1304// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1305func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) { 1306 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1307 vallen := _Socklen(SizeofTCPCCInfo) 1308 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1309 out := (*TCPVegasInfo)(unsafe.Pointer(&value[0])) 1310 return out, err 1311} 1312 1313// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp" 1314// algorithm. 1315// 1316// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1317// 1318// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1319func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) { 1320 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1321 vallen := _Socklen(SizeofTCPCCInfo) 1322 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1323 out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0])) 1324 return out, err 1325} 1326 1327// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr" 1328// algorithm. 1329// 1330// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: 1331// 1332// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) 1333func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) { 1334 var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment 1335 vallen := _Socklen(SizeofTCPCCInfo) 1336 err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 1337 out := (*TCPBBRInfo)(unsafe.Pointer(&value[0])) 1338 return out, err 1339} 1340 1341// GetsockoptString returns the string value of the socket option opt for the 1342// socket associated with fd at the given socket level. 1343func GetsockoptString(fd, level, opt int) (string, error) { 1344 buf := make([]byte, 256) 1345 vallen := _Socklen(len(buf)) 1346 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1347 if err != nil { 1348 if err == ERANGE { 1349 buf = make([]byte, vallen) 1350 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen) 1351 } 1352 if err != nil { 1353 return "", err 1354 } 1355 } 1356 return ByteSliceToString(buf[:vallen]), nil 1357} 1358 1359func GetsockoptTpacketStats(fd, level, opt int) (*TpacketStats, error) { 1360 var value TpacketStats 1361 vallen := _Socklen(SizeofTpacketStats) 1362 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1363 return &value, err 1364} 1365 1366func GetsockoptTpacketStatsV3(fd, level, opt int) (*TpacketStatsV3, error) { 1367 var value TpacketStatsV3 1368 vallen := _Socklen(SizeofTpacketStatsV3) 1369 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 1370 return &value, err 1371} 1372 1373func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 1374 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1375} 1376 1377func SetsockoptPacketMreq(fd, level, opt int, mreq *PacketMreq) error { 1378 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 1379} 1380 1381// SetsockoptSockFprog attaches a classic BPF or an extended BPF program to a 1382// socket to filter incoming packets. See 'man 7 socket' for usage information. 1383func SetsockoptSockFprog(fd, level, opt int, fprog *SockFprog) error { 1384 return setsockopt(fd, level, opt, unsafe.Pointer(fprog), unsafe.Sizeof(*fprog)) 1385} 1386 1387func SetsockoptCanRawFilter(fd, level, opt int, filter []CanFilter) error { 1388 var p unsafe.Pointer 1389 if len(filter) > 0 { 1390 p = unsafe.Pointer(&filter[0]) 1391 } 1392 return setsockopt(fd, level, opt, p, uintptr(len(filter)*SizeofCanFilter)) 1393} 1394 1395func SetsockoptTpacketReq(fd, level, opt int, tp *TpacketReq) error { 1396 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1397} 1398 1399func SetsockoptTpacketReq3(fd, level, opt int, tp *TpacketReq3) error { 1400 return setsockopt(fd, level, opt, unsafe.Pointer(tp), unsafe.Sizeof(*tp)) 1401} 1402 1403func SetsockoptTCPRepairOpt(fd, level, opt int, o []TCPRepairOpt) (err error) { 1404 if len(o) == 0 { 1405 return EINVAL 1406 } 1407 return setsockopt(fd, level, opt, unsafe.Pointer(&o[0]), uintptr(SizeofTCPRepairOpt*len(o))) 1408} 1409 1410func SetsockoptTCPMD5Sig(fd, level, opt int, s *TCPMD5Sig) error { 1411 return setsockopt(fd, level, opt, unsafe.Pointer(s), unsafe.Sizeof(*s)) 1412} 1413 1414// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html) 1415 1416// KeyctlInt calls keyctl commands in which each argument is an int. 1417// These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK, 1418// KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT, 1419// KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT, 1420// KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT. 1421//sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL 1422 1423// KeyctlBuffer calls keyctl commands in which the third and fourth 1424// arguments are a buffer and its length, respectively. 1425// These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE. 1426//sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL 1427 1428// KeyctlString calls keyctl commands which return a string. 1429// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY. 1430func KeyctlString(cmd int, id int) (string, error) { 1431 // We must loop as the string data may change in between the syscalls. 1432 // We could allocate a large buffer here to reduce the chance that the 1433 // syscall needs to be called twice; however, this is unnecessary as 1434 // the performance loss is negligible. 1435 var buffer []byte 1436 for { 1437 // Try to fill the buffer with data 1438 length, err := KeyctlBuffer(cmd, id, buffer, 0) 1439 if err != nil { 1440 return "", err 1441 } 1442 1443 // Check if the data was written 1444 if length <= len(buffer) { 1445 // Exclude the null terminator 1446 return string(buffer[:length-1]), nil 1447 } 1448 1449 // Make a bigger buffer if needed 1450 buffer = make([]byte, length) 1451 } 1452} 1453 1454// Keyctl commands with special signatures. 1455 1456// KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command. 1457// See the full documentation at: 1458// http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html 1459func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) { 1460 createInt := 0 1461 if create { 1462 createInt = 1 1463 } 1464 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0) 1465} 1466 1467// KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the 1468// key handle permission mask as described in the "keyctl setperm" section of 1469// http://man7.org/linux/man-pages/man1/keyctl.1.html. 1470// See the full documentation at: 1471// http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html 1472func KeyctlSetperm(id int, perm uint32) error { 1473 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0) 1474 return err 1475} 1476 1477//sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL 1478 1479// KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command. 1480// See the full documentation at: 1481// http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html 1482func KeyctlJoinSessionKeyring(name string) (ringid int, err error) { 1483 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name) 1484} 1485 1486//sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL 1487 1488// KeyctlSearch implements the KEYCTL_SEARCH command. 1489// See the full documentation at: 1490// http://man7.org/linux/man-pages/man3/keyctl_search.3.html 1491func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) { 1492 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid) 1493} 1494 1495//sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL 1496 1497// KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This 1498// command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice 1499// of Iovec (each of which represents a buffer) instead of a single buffer. 1500// See the full documentation at: 1501// http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html 1502func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error { 1503 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid) 1504} 1505 1506//sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL 1507 1508// KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command 1509// computes a Diffie-Hellman shared secret based on the provide params. The 1510// secret is written to the provided buffer and the returned size is the number 1511// of bytes written (returning an error if there is insufficient space in the 1512// buffer). If a nil buffer is passed in, this function returns the minimum 1513// buffer length needed to store the appropriate data. Note that this differs 1514// from KEYCTL_READ's behavior which always returns the requested payload size. 1515// See the full documentation at: 1516// http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html 1517func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) { 1518 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer) 1519} 1520 1521// KeyctlRestrictKeyring implements the KEYCTL_RESTRICT_KEYRING command. This 1522// command limits the set of keys that can be linked to the keyring, regardless 1523// of keyring permissions. The command requires the "setattr" permission. 1524// 1525// When called with an empty keyType the command locks the keyring, preventing 1526// any further keys from being linked to the keyring. 1527// 1528// The "asymmetric" keyType defines restrictions requiring key payloads to be 1529// DER encoded X.509 certificates signed by keys in another keyring. Restrictions 1530// for "asymmetric" include "builtin_trusted", "builtin_and_secondary_trusted", 1531// "key_or_keyring:<key>", and "key_or_keyring:<key>:chain". 1532// 1533// As of Linux 4.12, only the "asymmetric" keyType defines type-specific 1534// restrictions. 1535// 1536// See the full documentation at: 1537// http://man7.org/linux/man-pages/man3/keyctl_restrict_keyring.3.html 1538// http://man7.org/linux/man-pages/man2/keyctl.2.html 1539func KeyctlRestrictKeyring(ringid int, keyType string, restriction string) error { 1540 if keyType == "" { 1541 return keyctlRestrictKeyring(KEYCTL_RESTRICT_KEYRING, ringid) 1542 } 1543 return keyctlRestrictKeyringByType(KEYCTL_RESTRICT_KEYRING, ringid, keyType, restriction) 1544} 1545 1546//sys keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL 1547//sys keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL 1548 1549func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { 1550 var msg Msghdr 1551 msg.Name = (*byte)(unsafe.Pointer(rsa)) 1552 msg.Namelen = uint32(SizeofSockaddrAny) 1553 var dummy byte 1554 if len(oob) > 0 { 1555 if emptyIovecs(iov) { 1556 var sockType int 1557 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1558 if err != nil { 1559 return 1560 } 1561 // receive at least one normal byte 1562 if sockType != SOCK_DGRAM { 1563 var iova [1]Iovec 1564 iova[0].Base = &dummy 1565 iova[0].SetLen(1) 1566 iov = iova[:] 1567 } 1568 } 1569 msg.Control = &oob[0] 1570 msg.SetControllen(len(oob)) 1571 } 1572 if len(iov) > 0 { 1573 msg.Iov = &iov[0] 1574 msg.SetIovlen(len(iov)) 1575 } 1576 if n, err = recvmsg(fd, &msg, flags); err != nil { 1577 return 1578 } 1579 oobn = int(msg.Controllen) 1580 recvflags = int(msg.Flags) 1581 return 1582} 1583 1584func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { 1585 var msg Msghdr 1586 msg.Name = (*byte)(ptr) 1587 msg.Namelen = uint32(salen) 1588 var dummy byte 1589 var empty bool 1590 if len(oob) > 0 { 1591 empty = emptyIovecs(iov) 1592 if empty { 1593 var sockType int 1594 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 1595 if err != nil { 1596 return 0, err 1597 } 1598 // send at least one normal byte 1599 if sockType != SOCK_DGRAM { 1600 var iova [1]Iovec 1601 iova[0].Base = &dummy 1602 iova[0].SetLen(1) 1603 iov = iova[:] 1604 } 1605 } 1606 msg.Control = &oob[0] 1607 msg.SetControllen(len(oob)) 1608 } 1609 if len(iov) > 0 { 1610 msg.Iov = &iov[0] 1611 msg.SetIovlen(len(iov)) 1612 } 1613 if n, err = sendmsg(fd, &msg, flags); err != nil { 1614 return 0, err 1615 } 1616 if len(oob) > 0 && empty { 1617 n = 0 1618 } 1619 return n, nil 1620} 1621 1622// BindToDevice binds the socket associated with fd to device. 1623func BindToDevice(fd int, device string) (err error) { 1624 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 1625} 1626 1627//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 1628//sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE 1629 1630func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 1631 // The peek requests are machine-size oriented, so we wrap it 1632 // to retrieve arbitrary-length data. 1633 1634 // The ptrace syscall differs from glibc's ptrace. 1635 // Peeks returns the word in *data, not as the return value. 1636 1637 var buf [SizeofPtr]byte 1638 1639 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 1640 // access (PEEKUSER warns that it might), but if we don't 1641 // align our reads, we might straddle an unmapped page 1642 // boundary and not get the bytes leading up to the page 1643 // boundary. 1644 n := 0 1645 if addr%SizeofPtr != 0 { 1646 err = ptracePtr(req, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) 1647 if err != nil { 1648 return 0, err 1649 } 1650 n += copy(out, buf[addr%SizeofPtr:]) 1651 out = out[n:] 1652 } 1653 1654 // Remainder. 1655 for len(out) > 0 { 1656 // We use an internal buffer to guarantee alignment. 1657 // It's not documented if this is necessary, but we're paranoid. 1658 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) 1659 if err != nil { 1660 return n, err 1661 } 1662 copied := copy(out, buf[0:]) 1663 n += copied 1664 out = out[copied:] 1665 } 1666 1667 return n, nil 1668} 1669 1670func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 1671 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 1672} 1673 1674func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 1675 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 1676} 1677 1678func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) { 1679 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out) 1680} 1681 1682func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 1683 // As for ptracePeek, we need to align our accesses to deal 1684 // with the possibility of straddling an invalid page. 1685 1686 // Leading edge. 1687 n := 0 1688 if addr%SizeofPtr != 0 { 1689 var buf [SizeofPtr]byte 1690 err = ptracePtr(peekReq, pid, addr-addr%SizeofPtr, unsafe.Pointer(&buf[0])) 1691 if err != nil { 1692 return 0, err 1693 } 1694 n += copy(buf[addr%SizeofPtr:], data) 1695 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1696 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word) 1697 if err != nil { 1698 return 0, err 1699 } 1700 data = data[n:] 1701 } 1702 1703 // Interior. 1704 for len(data) > SizeofPtr { 1705 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 1706 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1707 if err != nil { 1708 return n, err 1709 } 1710 n += SizeofPtr 1711 data = data[SizeofPtr:] 1712 } 1713 1714 // Trailing edge. 1715 if len(data) > 0 { 1716 var buf [SizeofPtr]byte 1717 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0])) 1718 if err != nil { 1719 return n, err 1720 } 1721 copy(buf[0:], data) 1722 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 1723 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 1724 if err != nil { 1725 return n, err 1726 } 1727 n += len(data) 1728 } 1729 1730 return n, nil 1731} 1732 1733func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 1734 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 1735} 1736 1737func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 1738 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 1739} 1740 1741func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { 1742 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) 1743} 1744 1745// elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so 1746// x/sys/unix doesn't need to depend on debug/elf and thus 1747// compress/zlib, debug/dwarf, and other packages. 1748const elfNT_PRSTATUS = 1 1749 1750func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 1751 var iov Iovec 1752 iov.Base = (*byte)(unsafe.Pointer(regsout)) 1753 iov.SetLen(int(unsafe.Sizeof(*regsout))) 1754 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) 1755} 1756 1757func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 1758 var iov Iovec 1759 iov.Base = (*byte)(unsafe.Pointer(regs)) 1760 iov.SetLen(int(unsafe.Sizeof(*regs))) 1761 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) 1762} 1763 1764func PtraceSetOptions(pid int, options int) (err error) { 1765 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 1766} 1767 1768func PtraceGetEventMsg(pid int) (msg uint, err error) { 1769 var data _C_long 1770 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data)) 1771 msg = uint(data) 1772 return 1773} 1774 1775func PtraceCont(pid int, signal int) (err error) { 1776 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 1777} 1778 1779func PtraceSyscall(pid int, signal int) (err error) { 1780 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 1781} 1782 1783func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 1784 1785func PtraceInterrupt(pid int) (err error) { return ptrace(PTRACE_INTERRUPT, pid, 0, 0) } 1786 1787func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 1788 1789func PtraceSeize(pid int) (err error) { return ptrace(PTRACE_SEIZE, pid, 0, 0) } 1790 1791func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 1792 1793//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 1794 1795func Reboot(cmd int) (err error) { 1796 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 1797} 1798 1799func direntIno(buf []byte) (uint64, bool) { 1800 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 1801} 1802 1803func direntReclen(buf []byte) (uint64, bool) { 1804 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 1805} 1806 1807func direntNamlen(buf []byte) (uint64, bool) { 1808 reclen, ok := direntReclen(buf) 1809 if !ok { 1810 return 0, false 1811 } 1812 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 1813} 1814 1815//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 1816 1817func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 1818 // Certain file systems get rather angry and EINVAL if you give 1819 // them an empty string of data, rather than NULL. 1820 if data == "" { 1821 return mount(source, target, fstype, flags, nil) 1822 } 1823 datap, err := BytePtrFromString(data) 1824 if err != nil { 1825 return err 1826 } 1827 return mount(source, target, fstype, flags, datap) 1828} 1829 1830//sys mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) = SYS_MOUNT_SETATTR 1831 1832// MountSetattr is a wrapper for mount_setattr(2). 1833// https://man7.org/linux/man-pages/man2/mount_setattr.2.html 1834// 1835// Requires kernel >= 5.12. 1836func MountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr) error { 1837 return mountSetattr(dirfd, pathname, flags, attr, unsafe.Sizeof(*attr)) 1838} 1839 1840func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 1841 if raceenabled { 1842 raceReleaseMerge(unsafe.Pointer(&ioSync)) 1843 } 1844 return sendfile(outfd, infd, offset, count) 1845} 1846 1847// Sendto 1848// Recvfrom 1849// Socketpair 1850 1851/* 1852 * Direct access 1853 */ 1854//sys Acct(path string) (err error) 1855//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) 1856//sys Adjtimex(buf *Timex) (state int, err error) 1857//sysnb Capget(hdr *CapUserHeader, data *CapUserData) (err error) 1858//sysnb Capset(hdr *CapUserHeader, data *CapUserData) (err error) 1859//sys Chdir(path string) (err error) 1860//sys Chroot(path string) (err error) 1861//sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error) 1862//sys ClockGetres(clockid int32, res *Timespec) (err error) 1863//sys ClockGettime(clockid int32, time *Timespec) (err error) 1864//sys ClockSettime(clockid int32, time *Timespec) (err error) 1865//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) 1866//sys Close(fd int) (err error) 1867//sys CloseRange(first uint, last uint, flags uint) (err error) 1868//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 1869//sys DeleteModule(name string, flags int) (err error) 1870//sys Dup(oldfd int) (fd int, err error) 1871 1872func Dup2(oldfd, newfd int) error { 1873 return Dup3(oldfd, newfd, 0) 1874} 1875 1876//sys Dup3(oldfd int, newfd int, flags int) (err error) 1877//sysnb EpollCreate1(flag int) (fd int, err error) 1878//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 1879//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2 1880//sys Exit(code int) = SYS_EXIT_GROUP 1881//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 1882//sys Fchdir(fd int) (err error) 1883//sys Fchmod(fd int, mode uint32) (err error) 1884//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 1885//sys Fdatasync(fd int) (err error) 1886//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) 1887//sys FinitModule(fd int, params string, flags int) (err error) 1888//sys Flistxattr(fd int, dest []byte) (sz int, err error) 1889//sys Flock(fd int, how int) (err error) 1890//sys Fremovexattr(fd int, attr string) (err error) 1891//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) 1892//sys Fsync(fd int) (err error) 1893//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) 1894//sys Fsopen(fsName string, flags int) (fd int, err error) 1895//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) 1896 1897//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) 1898 1899func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { 1900 var keyp *byte 1901 if keyp, err = BytePtrFromString(key); err != nil { 1902 return 1903 } 1904 return fsconfig(fd, cmd, keyp, value, aux) 1905} 1906 1907// FsconfigSetFlag is equivalent to fsconfig(2) called 1908// with cmd == FSCONFIG_SET_FLAG. 1909// 1910// fd is the filesystem context to act upon. 1911// key the parameter key to set. 1912func FsconfigSetFlag(fd int, key string) (err error) { 1913 return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) 1914} 1915 1916// FsconfigSetString is equivalent to fsconfig(2) called 1917// with cmd == FSCONFIG_SET_STRING. 1918// 1919// fd is the filesystem context to act upon. 1920// key the parameter key to set. 1921// value is the parameter value to set. 1922func FsconfigSetString(fd int, key string, value string) (err error) { 1923 var valuep *byte 1924 if valuep, err = BytePtrFromString(value); err != nil { 1925 return 1926 } 1927 return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) 1928} 1929 1930// FsconfigSetBinary is equivalent to fsconfig(2) called 1931// with cmd == FSCONFIG_SET_BINARY. 1932// 1933// fd is the filesystem context to act upon. 1934// key the parameter key to set. 1935// value is the parameter value to set. 1936func FsconfigSetBinary(fd int, key string, value []byte) (err error) { 1937 if len(value) == 0 { 1938 return EINVAL 1939 } 1940 return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) 1941} 1942 1943// FsconfigSetPath is equivalent to fsconfig(2) called 1944// with cmd == FSCONFIG_SET_PATH. 1945// 1946// fd is the filesystem context to act upon. 1947// key the parameter key to set. 1948// path is a non-empty path for specified key. 1949// atfd is a file descriptor at which to start lookup from or AT_FDCWD. 1950func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { 1951 var valuep *byte 1952 if valuep, err = BytePtrFromString(path); err != nil { 1953 return 1954 } 1955 return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) 1956} 1957 1958// FsconfigSetPathEmpty is equivalent to fsconfig(2) called 1959// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as 1960// FconfigSetPath but with AT_PATH_EMPTY implied. 1961func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { 1962 var valuep *byte 1963 if valuep, err = BytePtrFromString(path); err != nil { 1964 return 1965 } 1966 return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) 1967} 1968 1969// FsconfigSetFd is equivalent to fsconfig(2) called 1970// with cmd == FSCONFIG_SET_FD. 1971// 1972// fd is the filesystem context to act upon. 1973// key the parameter key to set. 1974// value is a file descriptor to be assigned to specified key. 1975func FsconfigSetFd(fd int, key string, value int) (err error) { 1976 return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) 1977} 1978 1979// FsconfigCreate is equivalent to fsconfig(2) called 1980// with cmd == FSCONFIG_CMD_CREATE. 1981// 1982// fd is the filesystem context to act upon. 1983func FsconfigCreate(fd int) (err error) { 1984 return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) 1985} 1986 1987// FsconfigReconfigure is equivalent to fsconfig(2) called 1988// with cmd == FSCONFIG_CMD_RECONFIGURE. 1989// 1990// fd is the filesystem context to act upon. 1991func FsconfigReconfigure(fd int) (err error) { 1992 return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) 1993} 1994 1995//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 1996//sysnb Getpgid(pid int) (pgid int, err error) 1997 1998func Getpgrp() (pid int) { 1999 pid, _ = Getpgid(0) 2000 return 2001} 2002 2003//sysnb Getpid() (pid int) 2004//sysnb Getppid() (ppid int) 2005//sys Getpriority(which int, who int) (prio int, err error) 2006 2007func Getrandom(buf []byte, flags int) (n int, err error) { 2008 vdsoRet, supported := vgetrandom(buf, uint32(flags)) 2009 if supported { 2010 if vdsoRet < 0 { 2011 return 0, errnoErr(syscall.Errno(-vdsoRet)) 2012 } 2013 return vdsoRet, nil 2014 } 2015 var p *byte 2016 if len(buf) > 0 { 2017 p = &buf[0] 2018 } 2019 r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags)) 2020 if e != 0 { 2021 return 0, errnoErr(e) 2022 } 2023 return int(r), nil 2024} 2025 2026//sysnb Getrusage(who int, rusage *Rusage) (err error) 2027//sysnb Getsid(pid int) (sid int, err error) 2028//sysnb Gettid() (tid int) 2029//sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 2030//sys InitModule(moduleImage []byte, params string) (err error) 2031//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 2032//sysnb InotifyInit1(flags int) (fd int, err error) 2033//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 2034//sysnb Kill(pid int, sig syscall.Signal) (err error) 2035//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 2036//sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error) 2037//sys Listxattr(path string, dest []byte) (sz int, err error) 2038//sys Llistxattr(path string, dest []byte) (sz int, err error) 2039//sys Lremovexattr(path string, attr string) (err error) 2040//sys Lsetxattr(path string, attr string, data []byte, flags int) (err error) 2041//sys MemfdCreate(name string, flags int) (fd int, err error) 2042//sys Mkdirat(dirfd int, path string, mode uint32) (err error) 2043//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 2044//sys MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error) 2045//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 2046//sys OpenTree(dfd int, fileName string, flags uint) (r int, err error) 2047//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) 2048//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 2049//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) 2050//sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) 2051//sys read(fd int, p []byte) (n int, err error) 2052//sys Removexattr(path string, attr string) (err error) 2053//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) 2054//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) 2055//sys Setdomainname(p []byte) (err error) 2056//sys Sethostname(p []byte) (err error) 2057//sysnb Setpgid(pid int, pgid int) (err error) 2058//sysnb Setsid() (pid int, err error) 2059//sysnb Settimeofday(tv *Timeval) (err error) 2060//sys Setns(fd int, nstype int) (err error) 2061 2062//go:linkname syscall_prlimit syscall.prlimit 2063func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error 2064 2065func Prlimit(pid, resource int, newlimit, old *Rlimit) error { 2066 // Just call the syscall version, because as of Go 1.21 2067 // it will affect starting a new process. 2068 return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old)) 2069} 2070 2071// PrctlRetInt performs a prctl operation specified by option and further 2072// optional arguments arg2 through arg5 depending on option. It returns a 2073// non-negative integer that is returned by the prctl syscall. 2074func PrctlRetInt(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (int, error) { 2075 ret, _, err := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) 2076 if err != 0 { 2077 return 0, err 2078 } 2079 return int(ret), nil 2080} 2081 2082func Setuid(uid int) (err error) { 2083 return syscall.Setuid(uid) 2084} 2085 2086func Setgid(gid int) (err error) { 2087 return syscall.Setgid(gid) 2088} 2089 2090func Setreuid(ruid, euid int) (err error) { 2091 return syscall.Setreuid(ruid, euid) 2092} 2093 2094func Setregid(rgid, egid int) (err error) { 2095 return syscall.Setregid(rgid, egid) 2096} 2097 2098func Setresuid(ruid, euid, suid int) (err error) { 2099 return syscall.Setresuid(ruid, euid, suid) 2100} 2101 2102func Setresgid(rgid, egid, sgid int) (err error) { 2103 return syscall.Setresgid(rgid, egid, sgid) 2104} 2105 2106// SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set. 2107// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability. 2108// If the call fails due to other reasons, current fsgid will be returned. 2109func SetfsgidRetGid(gid int) (int, error) { 2110 return setfsgid(gid) 2111} 2112 2113// SetfsuidRetUid sets fsuid for current thread and returns previous fsuid set. 2114// setfsgid(2) will return a non-nil error only if its caller lacks CAP_SETUID capability 2115// If the call fails due to other reasons, current fsuid will be returned. 2116func SetfsuidRetUid(uid int) (int, error) { 2117 return setfsuid(uid) 2118} 2119 2120func Setfsgid(gid int) error { 2121 _, err := setfsgid(gid) 2122 return err 2123} 2124 2125func Setfsuid(uid int) error { 2126 _, err := setfsuid(uid) 2127 return err 2128} 2129 2130func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { 2131 return signalfd(fd, sigmask, _C__NSIG/8, flags) 2132} 2133 2134//sys Setpriority(which int, who int, prio int) (err error) 2135//sys Setxattr(path string, attr string, data []byte, flags int) (err error) 2136//sys signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4 2137//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) 2138//sys Sync() 2139//sys Syncfs(fd int) (err error) 2140//sysnb Sysinfo(info *Sysinfo_t) (err error) 2141//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 2142//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error) 2143//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error) 2144//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) 2145//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error) 2146//sysnb Times(tms *Tms) (ticks uintptr, err error) 2147//sysnb Umask(mask int) (oldmask int) 2148//sysnb Uname(buf *Utsname) (err error) 2149//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 2150//sys Unshare(flags int) (err error) 2151//sys write(fd int, p []byte) (n int, err error) 2152//sys exitThread(code int) (err error) = SYS_EXIT 2153//sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV 2154//sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV 2155//sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV 2156//sys pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PWRITEV 2157//sys preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PREADV2 2158//sys pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) = SYS_PWRITEV2 2159 2160// minIovec is the size of the small initial allocation used by 2161// Readv, Writev, etc. 2162// 2163// This small allocation gets stack allocated, which lets the 2164// common use case of len(iovs) <= minIovs avoid more expensive 2165// heap allocations. 2166const minIovec = 8 2167 2168// appendBytes converts bs to Iovecs and appends them to vecs. 2169func appendBytes(vecs []Iovec, bs [][]byte) []Iovec { 2170 for _, b := range bs { 2171 var v Iovec 2172 v.SetLen(len(b)) 2173 if len(b) > 0 { 2174 v.Base = &b[0] 2175 } else { 2176 v.Base = (*byte)(unsafe.Pointer(&_zero)) 2177 } 2178 vecs = append(vecs, v) 2179 } 2180 return vecs 2181} 2182 2183// offs2lohi splits offs into its low and high order bits. 2184func offs2lohi(offs int64) (lo, hi uintptr) { 2185 const longBits = SizeofLong * 8 2186 return uintptr(offs), uintptr(uint64(offs) >> (longBits - 1) >> 1) // two shifts to avoid false positive in vet 2187} 2188 2189func Readv(fd int, iovs [][]byte) (n int, err error) { 2190 iovecs := make([]Iovec, 0, minIovec) 2191 iovecs = appendBytes(iovecs, iovs) 2192 n, err = readv(fd, iovecs) 2193 readvRacedetect(iovecs, n, err) 2194 return n, err 2195} 2196 2197func Preadv(fd int, iovs [][]byte, offset int64) (n int, err error) { 2198 iovecs := make([]Iovec, 0, minIovec) 2199 iovecs = appendBytes(iovecs, iovs) 2200 lo, hi := offs2lohi(offset) 2201 n, err = preadv(fd, iovecs, lo, hi) 2202 readvRacedetect(iovecs, n, err) 2203 return n, err 2204} 2205 2206func Preadv2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2207 iovecs := make([]Iovec, 0, minIovec) 2208 iovecs = appendBytes(iovecs, iovs) 2209 lo, hi := offs2lohi(offset) 2210 n, err = preadv2(fd, iovecs, lo, hi, flags) 2211 readvRacedetect(iovecs, n, err) 2212 return n, err 2213} 2214 2215func readvRacedetect(iovecs []Iovec, n int, err error) { 2216 if !raceenabled { 2217 return 2218 } 2219 for i := 0; n > 0 && i < len(iovecs); i++ { 2220 m := min(int(iovecs[i].Len), n) 2221 n -= m 2222 if m > 0 { 2223 raceWriteRange(unsafe.Pointer(iovecs[i].Base), m) 2224 } 2225 } 2226 if err == nil { 2227 raceAcquire(unsafe.Pointer(&ioSync)) 2228 } 2229} 2230 2231func Writev(fd int, iovs [][]byte) (n int, err error) { 2232 iovecs := make([]Iovec, 0, minIovec) 2233 iovecs = appendBytes(iovecs, iovs) 2234 if raceenabled { 2235 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2236 } 2237 n, err = writev(fd, iovecs) 2238 writevRacedetect(iovecs, n) 2239 return n, err 2240} 2241 2242func Pwritev(fd int, iovs [][]byte, offset int64) (n int, err error) { 2243 iovecs := make([]Iovec, 0, minIovec) 2244 iovecs = appendBytes(iovecs, iovs) 2245 if raceenabled { 2246 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2247 } 2248 lo, hi := offs2lohi(offset) 2249 n, err = pwritev(fd, iovecs, lo, hi) 2250 writevRacedetect(iovecs, n) 2251 return n, err 2252} 2253 2254func Pwritev2(fd int, iovs [][]byte, offset int64, flags int) (n int, err error) { 2255 iovecs := make([]Iovec, 0, minIovec) 2256 iovecs = appendBytes(iovecs, iovs) 2257 if raceenabled { 2258 raceReleaseMerge(unsafe.Pointer(&ioSync)) 2259 } 2260 lo, hi := offs2lohi(offset) 2261 n, err = pwritev2(fd, iovecs, lo, hi, flags) 2262 writevRacedetect(iovecs, n) 2263 return n, err 2264} 2265 2266func writevRacedetect(iovecs []Iovec, n int) { 2267 if !raceenabled { 2268 return 2269 } 2270 for i := 0; n > 0 && i < len(iovecs); i++ { 2271 m := min(int(iovecs[i].Len), n) 2272 n -= m 2273 if m > 0 { 2274 raceReadRange(unsafe.Pointer(iovecs[i].Base), m) 2275 } 2276 } 2277} 2278 2279// mmap varies by architecture; see syscall_linux_*.go. 2280//sys munmap(addr uintptr, length uintptr) (err error) 2281//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) 2282//sys Madvise(b []byte, advice int) (err error) 2283//sys Mprotect(b []byte, prot int) (err error) 2284//sys Mlock(b []byte) (err error) 2285//sys Mlockall(flags int) (err error) 2286//sys Msync(b []byte, flags int) (err error) 2287//sys Munlock(b []byte) (err error) 2288//sys Munlockall() (err error) 2289 2290const ( 2291 mremapFixed = MREMAP_FIXED 2292 mremapDontunmap = MREMAP_DONTUNMAP 2293 mremapMaymove = MREMAP_MAYMOVE 2294) 2295 2296// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, 2297// using the specified flags. 2298func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { 2299 var p unsafe.Pointer 2300 if len(iovs) > 0 { 2301 p = unsafe.Pointer(&iovs[0]) 2302 } 2303 2304 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0) 2305 if errno != 0 { 2306 return 0, syscall.Errno(errno) 2307 } 2308 2309 return int(n), nil 2310} 2311 2312func isGroupMember(gid int) bool { 2313 groups, err := Getgroups() 2314 if err != nil { 2315 return false 2316 } 2317 2318 return slices.Contains(groups, gid) 2319} 2320 2321func isCapDacOverrideSet() bool { 2322 hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3} 2323 data := [2]CapUserData{} 2324 err := Capget(&hdr, &data[0]) 2325 2326 return err == nil && data[0].Effective&(1<<CAP_DAC_OVERRIDE) != 0 2327} 2328 2329//sys faccessat(dirfd int, path string, mode uint32) (err error) 2330//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) 2331 2332func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 2333 if flags == 0 { 2334 return faccessat(dirfd, path, mode) 2335 } 2336 2337 if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM { 2338 return err 2339 } 2340 2341 // The Linux kernel faccessat system call does not take any flags. 2342 // The glibc faccessat implements the flags itself; see 2343 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 2344 // Because people naturally expect syscall.Faccessat to act 2345 // like C faccessat, we do the same. 2346 2347 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { 2348 return EINVAL 2349 } 2350 2351 var st Stat_t 2352 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil { 2353 return err 2354 } 2355 2356 mode &= 7 2357 if mode == 0 { 2358 return nil 2359 } 2360 2361 var uid int 2362 if flags&AT_EACCESS != 0 { 2363 uid = Geteuid() 2364 if uid != 0 && isCapDacOverrideSet() { 2365 // If CAP_DAC_OVERRIDE is set, file access check is 2366 // done by the kernel in the same way as for root 2367 // (see generic_permission() in the Linux sources). 2368 uid = 0 2369 } 2370 } else { 2371 uid = Getuid() 2372 } 2373 2374 if uid == 0 { 2375 if mode&1 == 0 { 2376 // Root can read and write any file. 2377 return nil 2378 } 2379 if st.Mode&0111 != 0 { 2380 // Root can execute any file that anybody can execute. 2381 return nil 2382 } 2383 return EACCES 2384 } 2385 2386 var fmode uint32 2387 if uint32(uid) == st.Uid { 2388 fmode = (st.Mode >> 6) & 7 2389 } else { 2390 var gid int 2391 if flags&AT_EACCESS != 0 { 2392 gid = Getegid() 2393 } else { 2394 gid = Getgid() 2395 } 2396 2397 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) { 2398 fmode = (st.Mode >> 3) & 7 2399 } else { 2400 fmode = st.Mode & 7 2401 } 2402 } 2403 2404 if fmode&mode == mode { 2405 return nil 2406 } 2407 2408 return EACCES 2409} 2410 2411//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT 2412//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT 2413 2414// fileHandle is the argument to nameToHandleAt and openByHandleAt. We 2415// originally tried to generate it via unix/linux/types.go with "type 2416// fileHandle C.struct_file_handle" but that generated empty structs 2417// for mips64 and mips64le. Instead, hard code it for now (it's the 2418// same everywhere else) until the mips64 generator issue is fixed. 2419type fileHandle struct { 2420 Bytes uint32 2421 Type int32 2422} 2423 2424// FileHandle represents the C struct file_handle used by 2425// name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see 2426// OpenByHandleAt). 2427type FileHandle struct { 2428 *fileHandle 2429} 2430 2431// NewFileHandle constructs a FileHandle. 2432func NewFileHandle(handleType int32, handle []byte) FileHandle { 2433 const hdrSize = unsafe.Sizeof(fileHandle{}) 2434 buf := make([]byte, hdrSize+uintptr(len(handle))) 2435 copy(buf[hdrSize:], handle) 2436 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2437 fh.Type = handleType 2438 fh.Bytes = uint32(len(handle)) 2439 return FileHandle{fh} 2440} 2441 2442func (fh *FileHandle) Size() int { return int(fh.fileHandle.Bytes) } 2443func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type } 2444func (fh *FileHandle) Bytes() []byte { 2445 n := fh.Size() 2446 if n == 0 { 2447 return nil 2448 } 2449 return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n) 2450} 2451 2452// NameToHandleAt wraps the name_to_handle_at system call; it obtains 2453// a handle for a path name. 2454func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) { 2455 var mid _C_int 2456 // Try first with a small buffer, assuming the handle will 2457 // only be 32 bytes. 2458 size := uint32(32 + unsafe.Sizeof(fileHandle{})) 2459 didResize := false 2460 for { 2461 buf := make([]byte, size) 2462 fh := (*fileHandle)(unsafe.Pointer(&buf[0])) 2463 fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{})) 2464 err = nameToHandleAt(dirfd, path, fh, &mid, flags) 2465 if err == EOVERFLOW { 2466 if didResize { 2467 // We shouldn't need to resize more than once 2468 return 2469 } 2470 didResize = true 2471 size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{})) 2472 continue 2473 } 2474 if err != nil { 2475 return 2476 } 2477 return FileHandle{fh}, int(mid), nil 2478 } 2479} 2480 2481// OpenByHandleAt wraps the open_by_handle_at system call; it opens a 2482// file via a handle as previously returned by NameToHandleAt. 2483func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) { 2484 return openByHandleAt(mountFD, handle.fileHandle, flags) 2485} 2486 2487// Klogset wraps the sys_syslog system call; it sets console_loglevel to 2488// the value specified by arg and passes a dummy pointer to bufp. 2489func Klogset(typ int, arg int) (err error) { 2490 var p unsafe.Pointer 2491 _, _, errno := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(p), uintptr(arg)) 2492 if errno != 0 { 2493 return errnoErr(errno) 2494 } 2495 return nil 2496} 2497 2498// RemoteIovec is Iovec with the pointer replaced with an integer. 2499// It is used for ProcessVMReadv and ProcessVMWritev, where the pointer 2500// refers to a location in a different process' address space, which 2501// would confuse the Go garbage collector. 2502type RemoteIovec struct { 2503 Base uintptr 2504 Len int 2505} 2506 2507//sys ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_READV 2508//sys ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) = SYS_PROCESS_VM_WRITEV 2509 2510//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN 2511//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD 2512//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL 2513 2514//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) 2515//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) 2516//sys shmdt(addr uintptr) (err error) 2517//sys shmget(key int, size int, flag int) (id int, err error) 2518 2519//sys getitimer(which int, currValue *Itimerval) (err error) 2520//sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) 2521 2522// MakeItimerval creates an Itimerval from interval and value durations. 2523func MakeItimerval(interval, value time.Duration) Itimerval { 2524 return Itimerval{ 2525 Interval: NsecToTimeval(interval.Nanoseconds()), 2526 Value: NsecToTimeval(value.Nanoseconds()), 2527 } 2528} 2529 2530// A value which may be passed to the which parameter for Getitimer and 2531// Setitimer. 2532type ItimerWhich int 2533 2534// Possible which values for Getitimer and Setitimer. 2535const ( 2536 ItimerReal ItimerWhich = ITIMER_REAL 2537 ItimerVirtual ItimerWhich = ITIMER_VIRTUAL 2538 ItimerProf ItimerWhich = ITIMER_PROF 2539) 2540 2541// Getitimer wraps getitimer(2) to return the current value of the timer 2542// specified by which. 2543func Getitimer(which ItimerWhich) (Itimerval, error) { 2544 var it Itimerval 2545 if err := getitimer(int(which), &it); err != nil { 2546 return Itimerval{}, err 2547 } 2548 2549 return it, nil 2550} 2551 2552// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which. 2553// It returns the previous value of the timer. 2554// 2555// If the Itimerval argument is the zero value, the timer will be disarmed. 2556func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) { 2557 var prev Itimerval 2558 if err := setitimer(int(which), &it, &prev); err != nil { 2559 return Itimerval{}, err 2560 } 2561 2562 return prev, nil 2563} 2564 2565//sysnb rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK 2566 2567func PthreadSigmask(how int, set, oldset *Sigset_t) error { 2568 if oldset != nil { 2569 // Explicitly clear in case Sigset_t is larger than _C__NSIG. 2570 *oldset = Sigset_t{} 2571 } 2572 return rtSigprocmask(how, set, oldset, _C__NSIG/8) 2573} 2574 2575//sysnb getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) 2576//sysnb getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) 2577 2578func Getresuid() (ruid, euid, suid int) { 2579 var r, e, s _C_int 2580 getresuid(&r, &e, &s) 2581 return int(r), int(e), int(s) 2582} 2583 2584func Getresgid() (rgid, egid, sgid int) { 2585 var r, e, s _C_int 2586 getresgid(&r, &e, &s) 2587 return int(r), int(e), int(s) 2588} 2589 2590// Pselect is a wrapper around the Linux pselect6 system call. 2591// This version does not modify the timeout argument. 2592func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { 2593 // Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES, 2594 // The Linux pselect6() system call modifies its timeout argument. 2595 // [Not modifying the argument] is the behavior required by POSIX.1-2001. 2596 var mutableTimeout *Timespec 2597 if timeout != nil { 2598 mutableTimeout = new(Timespec) 2599 *mutableTimeout = *timeout 2600 } 2601 2602 // The final argument of the pselect6() system call is not a 2603 // sigset_t * pointer, but is instead a structure 2604 var kernelMask *sigset_argpack 2605 if sigmask != nil { 2606 wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize 2607 2608 // A sigset stores one bit per signal, 2609 // offset by 1 (because signal 0 does not exist). 2610 // So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉. 2611 sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits) 2612 2613 sigsetBytes := uintptr(sigsetWords * (wordBits / 8)) 2614 kernelMask = &sigset_argpack{ 2615 ss: sigmask, 2616 ssLen: sigsetBytes, 2617 } 2618 } 2619 2620 return pselect6(nfd, r, w, e, mutableTimeout, kernelMask) 2621} 2622 2623//sys schedSetattr(pid int, attr *SchedAttr, flags uint) (err error) 2624//sys schedGetattr(pid int, attr *SchedAttr, size uint, flags uint) (err error) 2625 2626// SchedSetAttr is a wrapper for sched_setattr(2) syscall. 2627// https://man7.org/linux/man-pages/man2/sched_setattr.2.html 2628func SchedSetAttr(pid int, attr *SchedAttr, flags uint) error { 2629 if attr == nil { 2630 return EINVAL 2631 } 2632 attr.Size = SizeofSchedAttr 2633 return schedSetattr(pid, attr, flags) 2634} 2635 2636// SchedGetAttr is a wrapper for sched_getattr(2) syscall. 2637// https://man7.org/linux/man-pages/man2/sched_getattr.2.html 2638func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { 2639 attr := &SchedAttr{} 2640 if err := schedGetattr(pid, attr, SizeofSchedAttr, flags); err != nil { 2641 return nil, err 2642 } 2643 return attr, nil 2644} 2645 2646//sys Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) 2647//sys Mseal(b []byte, flags uint) (err error)