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