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