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