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