github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/syscall/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 syscall 13 14 import "unsafe" 15 16 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr) 17 18 /* 19 * Wrapped 20 */ 21 22 func Access(path string, mode uint32) (err error) { 23 return Faccessat(_AT_FDCWD, path, mode, 0) 24 } 25 26 func Chmod(path string, mode uint32) (err error) { 27 return Fchmodat(_AT_FDCWD, path, mode, 0) 28 } 29 30 func Chown(path string, uid int, gid int) (err error) { 31 return Fchownat(_AT_FDCWD, path, uid, gid, 0) 32 } 33 34 func Creat(path string, mode uint32) (fd int, err error) { 35 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 36 } 37 38 func isGroupMember(gid int) bool { 39 groups, err := Getgroups() 40 if err != nil { 41 return false 42 } 43 44 for _, g := range groups { 45 if g == gid { 46 return true 47 } 48 } 49 return false 50 } 51 52 //sys faccessat(dirfd int, path string, mode uint32) (err error) 53 54 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { 55 if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 { 56 return EINVAL 57 } 58 59 // The Linux kernel faccessat system call does not take any flags. 60 // The glibc faccessat implements the flags itself; see 61 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD 62 // Because people naturally expect syscall.Faccessat to act 63 // like C faccessat, we do the same. 64 65 if flags == 0 { 66 return faccessat(dirfd, path, mode) 67 } 68 69 var st Stat_t 70 if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil { 71 return err 72 } 73 74 mode &= 7 75 if mode == 0 { 76 return nil 77 } 78 79 var uid int 80 if flags&_AT_EACCESS != 0 { 81 uid = Geteuid() 82 } else { 83 uid = Getuid() 84 } 85 86 if uid == 0 { 87 if mode&1 == 0 { 88 // Root can read and write any file. 89 return nil 90 } 91 if st.Mode&0111 != 0 { 92 // Root can execute any file that anybody can execute. 93 return nil 94 } 95 return EACCES 96 } 97 98 var fmode uint32 99 if uint32(uid) == st.Uid { 100 fmode = (st.Mode >> 6) & 7 101 } else { 102 var gid int 103 if flags&_AT_EACCESS != 0 { 104 gid = Getegid() 105 } else { 106 gid = Getgid() 107 } 108 109 if uint32(gid) == st.Gid || isGroupMember(gid) { 110 fmode = (st.Mode >> 3) & 7 111 } else { 112 fmode = st.Mode & 7 113 } 114 } 115 116 if fmode&mode == mode { 117 return nil 118 } 119 120 return EACCES 121 } 122 123 //sys fchmodat(dirfd int, path string, mode uint32) (err error) 124 125 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { 126 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior 127 // and check the flags. Otherwise the mode would be applied to the symlink 128 // destination which is not what the user expects. 129 if flags&^_AT_SYMLINK_NOFOLLOW != 0 { 130 return EINVAL 131 } else if flags&_AT_SYMLINK_NOFOLLOW != 0 { 132 return EOPNOTSUPP 133 } 134 return fchmodat(dirfd, path, mode) 135 } 136 137 //sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) 138 139 func Link(oldpath string, newpath string) (err error) { 140 return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0) 141 } 142 143 func Mkdir(path string, mode uint32) (err error) { 144 return Mkdirat(_AT_FDCWD, path, mode) 145 } 146 147 func Mknod(path string, mode uint32, dev int) (err error) { 148 return Mknodat(_AT_FDCWD, path, mode, dev) 149 } 150 151 func Open(path string, mode int, perm uint32) (fd int, err error) { 152 return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm) 153 } 154 155 //sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) 156 157 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { 158 return openat(dirfd, path, flags|O_LARGEFILE, mode) 159 } 160 161 //sys readlinkat(dirfd int, path string, buf []byte) (n int, err error) 162 163 func Readlink(path string, buf []byte) (n int, err error) { 164 return readlinkat(_AT_FDCWD, path, buf) 165 } 166 167 func Rename(oldpath string, newpath string) (err error) { 168 return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath) 169 } 170 171 func Rmdir(path string) error { 172 return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR) 173 } 174 175 //sys symlinkat(oldpath string, newdirfd int, newpath string) (err error) 176 177 func Symlink(oldpath string, newpath string) (err error) { 178 return symlinkat(oldpath, _AT_FDCWD, newpath) 179 } 180 181 func Unlink(path string) error { 182 return unlinkat(_AT_FDCWD, path, 0) 183 } 184 185 //sys unlinkat(dirfd int, path string, flags int) (err error) 186 187 func Unlinkat(dirfd int, path string) error { 188 return unlinkat(dirfd, path, 0) 189 } 190 191 func Utimes(path string, tv []Timeval) (err error) { 192 if len(tv) != 2 { 193 return EINVAL 194 } 195 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 196 } 197 198 //sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) 199 200 func UtimesNano(path string, ts []Timespec) (err error) { 201 if len(ts) != 2 { 202 return EINVAL 203 } 204 err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) 205 if err != ENOSYS { 206 return err 207 } 208 // If the utimensat syscall isn't available (utimensat was added to Linux 209 // in 2.6.22, Released, 8 July 2007) then fall back to utimes 210 var tv [2]Timeval 211 for i := 0; i < 2; i++ { 212 tv[i].Sec = ts[i].Sec 213 tv[i].Usec = ts[i].Nsec / 1000 214 } 215 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 216 } 217 218 func Futimesat(dirfd int, path string, tv []Timeval) (err error) { 219 if len(tv) != 2 { 220 return EINVAL 221 } 222 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) 223 } 224 225 func Futimes(fd int, tv []Timeval) (err error) { 226 // Believe it or not, this is the best we can do on Linux 227 // (and is what glibc does). 228 return Utimes("/proc/self/fd/"+itoa(fd), tv) 229 } 230 231 const ImplementsGetwd = true 232 233 //sys Getcwd(buf []byte) (n int, err error) 234 235 func Getwd() (wd string, err error) { 236 var buf [PathMax]byte 237 n, err := Getcwd(buf[0:]) 238 if err != nil { 239 return "", err 240 } 241 // Getcwd returns the number of bytes written to buf, including the NUL. 242 if n < 1 || n > len(buf) || buf[n-1] != 0 { 243 return "", EINVAL 244 } 245 return string(buf[0 : n-1]), nil 246 } 247 248 func Getgroups() (gids []int, err error) { 249 n, err := getgroups(0, nil) 250 if err != nil { 251 return nil, err 252 } 253 if n == 0 { 254 return nil, nil 255 } 256 257 // Sanity check group count. Max is 1<<16 on Linux. 258 if n < 0 || n > 1<<20 { 259 return nil, EINVAL 260 } 261 262 a := make([]_Gid_t, n) 263 n, err = getgroups(n, &a[0]) 264 if err != nil { 265 return nil, err 266 } 267 gids = make([]int, n) 268 for i, v := range a[0:n] { 269 gids[i] = int(v) 270 } 271 return 272 } 273 274 var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked. 275 276 func Setgroups(gids []int) (err error) { 277 n := uintptr(len(gids)) 278 if n == 0 { 279 if cgo_libc_setgroups == nil { 280 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 { 281 err = errnoErr(e1) 282 } 283 return 284 } 285 if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 { 286 err = errnoErr(Errno(ret)) 287 } 288 return 289 } 290 291 a := make([]_Gid_t, len(gids)) 292 for i, v := range gids { 293 a[i] = _Gid_t(v) 294 } 295 if cgo_libc_setgroups == nil { 296 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 { 297 err = errnoErr(e1) 298 } 299 return 300 } 301 if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 { 302 err = errnoErr(Errno(ret)) 303 } 304 return 305 } 306 307 type WaitStatus uint32 308 309 // Wait status is 7 bits at bottom, either 0 (exited), 310 // 0x7F (stopped), or a signal number that caused an exit. 311 // The 0x80 bit is whether there was a core dump. 312 // An extra number (exit code, signal causing a stop) 313 // is in the high bits. At least that's the idea. 314 // There are various irregularities. For example, the 315 // "continued" status is 0xFFFF, distinguishing itself 316 // from stopped via the core dump bit. 317 318 const ( 319 mask = 0x7F 320 core = 0x80 321 exited = 0x00 322 stopped = 0x7F 323 shift = 8 324 ) 325 326 func (w WaitStatus) Exited() bool { return w&mask == exited } 327 328 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited } 329 330 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped } 331 332 func (w WaitStatus) Continued() bool { return w == 0xFFFF } 333 334 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 } 335 336 func (w WaitStatus) ExitStatus() int { 337 if !w.Exited() { 338 return -1 339 } 340 return int(w>>shift) & 0xFF 341 } 342 343 func (w WaitStatus) Signal() Signal { 344 if !w.Signaled() { 345 return -1 346 } 347 return Signal(w & mask) 348 } 349 350 func (w WaitStatus) StopSignal() Signal { 351 if !w.Stopped() { 352 return -1 353 } 354 return Signal(w>>shift) & 0xFF 355 } 356 357 func (w WaitStatus) TrapCause() int { 358 if w.StopSignal() != SIGTRAP { 359 return -1 360 } 361 return int(w>>shift) >> 8 362 } 363 364 //sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) 365 366 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { 367 var status _C_int 368 wpid, err = wait4(pid, &status, options, rusage) 369 if wstatus != nil { 370 *wstatus = WaitStatus(status) 371 } 372 return 373 } 374 375 func Mkfifo(path string, mode uint32) (err error) { 376 return Mknod(path, mode|S_IFIFO, 0) 377 } 378 379 func (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 393 func (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 408 func (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 if n == len(sa.raw.Path) && name[0] != '@' { 415 return nil, 0, EINVAL 416 } 417 sa.raw.Family = AF_UNIX 418 for i := 0; i < n; i++ { 419 sa.raw.Path[i] = int8(name[i]) 420 } 421 // length is family (uint16), name, NUL. 422 sl := _Socklen(2) 423 if n > 0 { 424 sl += _Socklen(n) + 1 425 } 426 if sa.raw.Path[0] == '@' { 427 sa.raw.Path[0] = 0 428 // Don't count trailing NUL for abstract address. 429 sl-- 430 } 431 432 return unsafe.Pointer(&sa.raw), sl, nil 433 } 434 435 type SockaddrLinklayer struct { 436 Protocol uint16 437 Ifindex int 438 Hatype uint16 439 Pkttype uint8 440 Halen uint8 441 Addr [8]byte 442 raw RawSockaddrLinklayer 443 } 444 445 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) { 446 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff { 447 return nil, 0, EINVAL 448 } 449 sa.raw.Family = AF_PACKET 450 sa.raw.Protocol = sa.Protocol 451 sa.raw.Ifindex = int32(sa.Ifindex) 452 sa.raw.Hatype = sa.Hatype 453 sa.raw.Pkttype = sa.Pkttype 454 sa.raw.Halen = sa.Halen 455 for i := 0; i < len(sa.Addr); i++ { 456 sa.raw.Addr[i] = sa.Addr[i] 457 } 458 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil 459 } 460 461 type SockaddrNetlink struct { 462 Family uint16 463 Pad uint16 464 Pid uint32 465 Groups uint32 466 raw RawSockaddrNetlink 467 } 468 469 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) { 470 sa.raw.Family = AF_NETLINK 471 sa.raw.Pad = sa.Pad 472 sa.raw.Pid = sa.Pid 473 sa.raw.Groups = sa.Groups 474 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil 475 } 476 477 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { 478 switch rsa.Addr.Family { 479 case AF_NETLINK: 480 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa)) 481 sa := new(SockaddrNetlink) 482 sa.Family = pp.Family 483 sa.Pad = pp.Pad 484 sa.Pid = pp.Pid 485 sa.Groups = pp.Groups 486 return sa, nil 487 488 case AF_PACKET: 489 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa)) 490 sa := new(SockaddrLinklayer) 491 sa.Protocol = pp.Protocol 492 sa.Ifindex = int(pp.Ifindex) 493 sa.Hatype = pp.Hatype 494 sa.Pkttype = pp.Pkttype 495 sa.Halen = pp.Halen 496 for i := 0; i < len(sa.Addr); i++ { 497 sa.Addr[i] = pp.Addr[i] 498 } 499 return sa, nil 500 501 case AF_UNIX: 502 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) 503 sa := new(SockaddrUnix) 504 if pp.Path[0] == 0 { 505 // "Abstract" Unix domain socket. 506 // Rewrite leading NUL as @ for textual display. 507 // (This is the standard convention.) 508 // Not friendly to overwrite in place, 509 // but the callers below don't care. 510 pp.Path[0] = '@' 511 } 512 513 // Assume path ends at NUL. 514 // This is not technically the Linux semantics for 515 // abstract Unix domain sockets--they are supposed 516 // to be uninterpreted fixed-size binary blobs--but 517 // everyone uses this convention. 518 n := 0 519 for n < len(pp.Path) && pp.Path[n] != 0 { 520 n++ 521 } 522 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] 523 sa.Name = string(bytes) 524 return sa, nil 525 526 case AF_INET: 527 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) 528 sa := new(SockaddrInet4) 529 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 530 sa.Port = int(p[0])<<8 + int(p[1]) 531 for i := 0; i < len(sa.Addr); i++ { 532 sa.Addr[i] = pp.Addr[i] 533 } 534 return sa, nil 535 536 case AF_INET6: 537 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) 538 sa := new(SockaddrInet6) 539 p := (*[2]byte)(unsafe.Pointer(&pp.Port)) 540 sa.Port = int(p[0])<<8 + int(p[1]) 541 sa.ZoneId = pp.Scope_id 542 for i := 0; i < len(sa.Addr); i++ { 543 sa.Addr[i] = pp.Addr[i] 544 } 545 return sa, nil 546 } 547 return nil, EAFNOSUPPORT 548 } 549 550 func Accept(fd int) (nfd int, sa Sockaddr, err error) { 551 var rsa RawSockaddrAny 552 var len _Socklen = SizeofSockaddrAny 553 nfd, err = accept(fd, &rsa, &len) 554 if err != nil { 555 return 556 } 557 sa, err = anyToSockaddr(&rsa) 558 if err != nil { 559 Close(nfd) 560 nfd = 0 561 } 562 return 563 } 564 565 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { 566 var rsa RawSockaddrAny 567 var len _Socklen = SizeofSockaddrAny 568 nfd, err = accept4(fd, &rsa, &len, flags) 569 if err != nil { 570 return 571 } 572 if len > SizeofSockaddrAny { 573 panic("RawSockaddrAny too small") 574 } 575 sa, err = anyToSockaddr(&rsa) 576 if err != nil { 577 Close(nfd) 578 nfd = 0 579 } 580 return 581 } 582 583 func Getsockname(fd int) (sa Sockaddr, err error) { 584 var rsa RawSockaddrAny 585 var len _Socklen = SizeofSockaddrAny 586 if err = getsockname(fd, &rsa, &len); err != nil { 587 return 588 } 589 return anyToSockaddr(&rsa) 590 } 591 592 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) { 593 vallen := _Socklen(4) 594 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) 595 return value, err 596 } 597 598 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) { 599 var value IPMreq 600 vallen := _Socklen(SizeofIPMreq) 601 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 602 return &value, err 603 } 604 605 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) { 606 var value IPMreqn 607 vallen := _Socklen(SizeofIPMreqn) 608 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 609 return &value, err 610 } 611 612 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) { 613 var value IPv6Mreq 614 vallen := _Socklen(SizeofIPv6Mreq) 615 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 616 return &value, err 617 } 618 619 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) { 620 var value IPv6MTUInfo 621 vallen := _Socklen(SizeofIPv6MTUInfo) 622 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 623 return &value, err 624 } 625 626 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) { 627 var value ICMPv6Filter 628 vallen := _Socklen(SizeofICMPv6Filter) 629 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 630 return &value, err 631 } 632 633 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) { 634 var value Ucred 635 vallen := _Socklen(SizeofUcred) 636 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen) 637 return &value, err 638 } 639 640 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) { 641 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq)) 642 } 643 644 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { 645 var msg Msghdr 646 var rsa RawSockaddrAny 647 msg.Name = (*byte)(unsafe.Pointer(&rsa)) 648 msg.Namelen = uint32(SizeofSockaddrAny) 649 var iov Iovec 650 if len(p) > 0 { 651 iov.Base = &p[0] 652 iov.SetLen(len(p)) 653 } 654 var dummy byte 655 if len(oob) > 0 { 656 if len(p) == 0 { 657 var sockType int 658 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 659 if err != nil { 660 return 661 } 662 // receive at least one normal byte 663 if sockType != SOCK_DGRAM { 664 iov.Base = &dummy 665 iov.SetLen(1) 666 } 667 } 668 msg.Control = &oob[0] 669 msg.SetControllen(len(oob)) 670 } 671 msg.Iov = &iov 672 msg.Iovlen = 1 673 if n, err = recvmsg(fd, &msg, flags); err != nil { 674 return 675 } 676 oobn = int(msg.Controllen) 677 recvflags = int(msg.Flags) 678 // source address is only specified if the socket is unconnected 679 if rsa.Addr.Family != AF_UNSPEC { 680 from, err = anyToSockaddr(&rsa) 681 } 682 return 683 } 684 685 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { 686 _, err = SendmsgN(fd, p, oob, to, flags) 687 return 688 } 689 690 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { 691 var ptr unsafe.Pointer 692 var salen _Socklen 693 if to != nil { 694 var err error 695 ptr, salen, err = to.sockaddr() 696 if err != nil { 697 return 0, err 698 } 699 } 700 var msg Msghdr 701 msg.Name = (*byte)(ptr) 702 msg.Namelen = uint32(salen) 703 var iov Iovec 704 if len(p) > 0 { 705 iov.Base = &p[0] 706 iov.SetLen(len(p)) 707 } 708 var dummy byte 709 if len(oob) > 0 { 710 if len(p) == 0 { 711 var sockType int 712 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) 713 if err != nil { 714 return 0, err 715 } 716 // send at least one normal byte 717 if sockType != SOCK_DGRAM { 718 iov.Base = &dummy 719 iov.SetLen(1) 720 } 721 } 722 msg.Control = &oob[0] 723 msg.SetControllen(len(oob)) 724 } 725 msg.Iov = &iov 726 msg.Iovlen = 1 727 if n, err = sendmsg(fd, &msg, flags); err != nil { 728 return 0, err 729 } 730 if len(oob) > 0 && len(p) == 0 { 731 n = 0 732 } 733 return n, nil 734 } 735 736 // BindToDevice binds the socket associated with fd to device. 737 func BindToDevice(fd int, device string) (err error) { 738 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device) 739 } 740 741 //sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error) 742 743 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) { 744 // The peek requests are machine-size oriented, so we wrap it 745 // to retrieve arbitrary-length data. 746 747 // The ptrace syscall differs from glibc's ptrace. 748 // Peeks returns the word in *data, not as the return value. 749 750 var buf [sizeofPtr]byte 751 752 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned 753 // access (PEEKUSER warns that it might), but if we don't 754 // align our reads, we might straddle an unmapped page 755 // boundary and not get the bytes leading up to the page 756 // boundary. 757 n := 0 758 if addr%sizeofPtr != 0 { 759 err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 760 if err != nil { 761 return 0, err 762 } 763 n += copy(out, buf[addr%sizeofPtr:]) 764 out = out[n:] 765 } 766 767 // Remainder. 768 for len(out) > 0 { 769 // We use an internal buffer to guarantee alignment. 770 // It's not documented if this is necessary, but we're paranoid. 771 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 772 if err != nil { 773 return n, err 774 } 775 copied := copy(out, buf[0:]) 776 n += copied 777 out = out[copied:] 778 } 779 780 return n, nil 781 } 782 783 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) { 784 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out) 785 } 786 787 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) { 788 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out) 789 } 790 791 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) { 792 // As for ptracePeek, we need to align our accesses to deal 793 // with the possibility of straddling an invalid page. 794 795 // Leading edge. 796 n := 0 797 if addr%sizeofPtr != 0 { 798 var buf [sizeofPtr]byte 799 err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0]))) 800 if err != nil { 801 return 0, err 802 } 803 n += copy(buf[addr%sizeofPtr:], data) 804 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 805 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word) 806 if err != nil { 807 return 0, err 808 } 809 data = data[n:] 810 } 811 812 // Interior. 813 for len(data) > sizeofPtr { 814 word := *((*uintptr)(unsafe.Pointer(&data[0]))) 815 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 816 if err != nil { 817 return n, err 818 } 819 n += sizeofPtr 820 data = data[sizeofPtr:] 821 } 822 823 // Trailing edge. 824 if len(data) > 0 { 825 var buf [sizeofPtr]byte 826 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0]))) 827 if err != nil { 828 return n, err 829 } 830 copy(buf[0:], data) 831 word := *((*uintptr)(unsafe.Pointer(&buf[0]))) 832 err = ptrace(pokeReq, pid, addr+uintptr(n), word) 833 if err != nil { 834 return n, err 835 } 836 n += len(data) 837 } 838 839 return n, nil 840 } 841 842 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) { 843 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data) 844 } 845 846 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) { 847 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data) 848 } 849 850 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { 851 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout))) 852 } 853 854 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { 855 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs))) 856 } 857 858 func PtraceSetOptions(pid int, options int) (err error) { 859 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options)) 860 } 861 862 func PtraceGetEventMsg(pid int) (msg uint, err error) { 863 var data _C_long 864 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data))) 865 msg = uint(data) 866 return 867 } 868 869 func PtraceCont(pid int, signal int) (err error) { 870 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal)) 871 } 872 873 func PtraceSyscall(pid int, signal int) (err error) { 874 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal)) 875 } 876 877 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) } 878 879 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) } 880 881 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) } 882 883 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) 884 885 func Reboot(cmd int) (err error) { 886 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "") 887 } 888 889 func ReadDirent(fd int, buf []byte) (n int, err error) { 890 return Getdents(fd, buf) 891 } 892 893 func direntIno(buf []byte) (uint64, bool) { 894 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) 895 } 896 897 func direntReclen(buf []byte) (uint64, bool) { 898 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen)) 899 } 900 901 func direntNamlen(buf []byte) (uint64, bool) { 902 reclen, ok := direntReclen(buf) 903 if !ok { 904 return 0, false 905 } 906 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true 907 } 908 909 //sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) 910 911 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) { 912 // Certain file systems get rather angry and EINVAL if you give 913 // them an empty string of data, rather than NULL. 914 if data == "" { 915 return mount(source, target, fstype, flags, nil) 916 } 917 datap, err := BytePtrFromString(data) 918 if err != nil { 919 return err 920 } 921 return mount(source, target, fstype, flags, datap) 922 } 923 924 // Sendto 925 // Recvfrom 926 // Socketpair 927 928 /* 929 * Direct access 930 */ 931 //sys Acct(path string) (err error) 932 //sys Adjtimex(buf *Timex) (state int, err error) 933 //sys Chdir(path string) (err error) 934 //sys Chroot(path string) (err error) 935 //sys Close(fd int) (err error) 936 //sys Dup(oldfd int) (fd int, err error) 937 //sys Dup3(oldfd int, newfd int, flags int) (err error) 938 //sysnb EpollCreate1(flag int) (fd int, err error) 939 //sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) 940 //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) 941 //sys Fchdir(fd int) (err error) 942 //sys Fchmod(fd int, mode uint32) (err error) 943 //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) 944 //sys fcntl(fd int, cmd int, arg int) (val int, err error) 945 //sys Fdatasync(fd int) (err error) 946 //sys Flock(fd int, how int) (err error) 947 //sys Fsync(fd int) (err error) 948 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 949 //sysnb Getpgid(pid int) (pgid int, err error) 950 951 func Getpgrp() (pid int) { 952 pid, _ = Getpgid(0) 953 return 954 } 955 956 //sysnb Getpid() (pid int) 957 //sysnb Getppid() (ppid int) 958 //sys Getpriority(which int, who int) (prio int, err error) 959 //sysnb Getrusage(who int, rusage *Rusage) (err error) 960 //sysnb Gettid() (tid int) 961 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error) 962 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) 963 //sysnb InotifyInit1(flags int) (fd int, err error) 964 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) 965 //sysnb Kill(pid int, sig Signal) (err error) 966 //sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG 967 //sys Listxattr(path string, dest []byte) (sz int, err error) 968 //sys Mkdirat(dirfd int, path string, mode uint32) (err error) 969 //sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error) 970 //sys Nanosleep(time *Timespec, leftover *Timespec) (err error) 971 //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT 972 //sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 973 //sys read(fd int, p []byte) (n int, err error) 974 //sys Removexattr(path string, attr string) (err error) 975 //sys Setdomainname(p []byte) (err error) 976 //sys Sethostname(p []byte) (err error) 977 //sysnb Setpgid(pid int, pgid int) (err error) 978 //sysnb Setsid() (pid int, err error) 979 //sysnb Settimeofday(tv *Timeval) (err error) 980 981 // allThreadsCaller holds the input and output state for performing a 982 // allThreadsSyscall that needs to synchronize all OS thread state. Linux 983 // generally does not always support this natively, so we have to 984 // manipulate the runtime to fix things up. 985 type allThreadsCaller struct { 986 // arguments 987 trap, a1, a2, a3, a4, a5, a6 uintptr 988 989 // return values (only set by 0th invocation) 990 r1, r2 uintptr 991 992 // err is the error code 993 err Errno 994 } 995 996 // doSyscall is a callback for executing a syscall on the current m 997 // (OS thread). 998 //go:nosplit 999 //go:norace 1000 func (pc *allThreadsCaller) doSyscall(initial bool) bool { 1001 r1, r2, err := RawSyscall(pc.trap, pc.a1, pc.a2, pc.a3) 1002 if initial { 1003 pc.r1 = r1 1004 pc.r2 = r2 1005 pc.err = err 1006 } else if pc.r1 != r1 || (archHonorsR2 && pc.r2 != r2) || pc.err != err { 1007 print("trap:", pc.trap, ", a123=[", pc.a1, ",", pc.a2, ",", pc.a3, "]\n") 1008 print("results: got {r1=", r1, ",r2=", r2, ",err=", err, "}, want {r1=", pc.r1, ",r2=", pc.r2, ",r3=", pc.err, "}\n") 1009 panic("AllThreadsSyscall results differ between threads; runtime corrupted") 1010 } 1011 return err == 0 1012 } 1013 1014 // doSyscall6 is a callback for executing a syscall6 on the current m 1015 // (OS thread). 1016 //go:nosplit 1017 //go:norace 1018 func (pc *allThreadsCaller) doSyscall6(initial bool) bool { 1019 r1, r2, err := RawSyscall6(pc.trap, pc.a1, pc.a2, pc.a3, pc.a4, pc.a5, pc.a6) 1020 if initial { 1021 pc.r1 = r1 1022 pc.r2 = r2 1023 pc.err = err 1024 } else if pc.r1 != r1 || (archHonorsR2 && pc.r2 != r2) || pc.err != err { 1025 print("trap:", pc.trap, ", a123456=[", pc.a1, ",", pc.a2, ",", pc.a3, ",", pc.a4, ",", pc.a5, ",", pc.a6, "]\n") 1026 print("results: got {r1=", r1, ",r2=", r2, ",err=", err, "}, want {r1=", pc.r1, ",r2=", pc.r2, ",r3=", pc.err, "}\n") 1027 panic("AllThreadsSyscall6 results differ between threads; runtime corrupted") 1028 } 1029 return err == 0 1030 } 1031 1032 // Provided by runtime.syscall_runtime_doAllThreadsSyscall which 1033 // serializes the world and invokes the fn on each OS thread (what the 1034 // runtime refers to as m's). Once this function returns, all threads 1035 // are in sync. 1036 func runtime_doAllThreadsSyscall(fn func(bool) bool) 1037 1038 // AllThreadsSyscall performs a syscall on each OS thread of the Go 1039 // runtime. It first invokes the syscall on one thread. Should that 1040 // invocation fail, it returns immediately with the error status. 1041 // Otherwise, it invokes the syscall on all of the remaining threads 1042 // in parallel. It will terminate the program if it observes any 1043 // invoked syscall's return value differs from that of the first 1044 // invocation. 1045 // 1046 // AllThreadsSyscall is intended for emulating simultaneous 1047 // process-wide state changes that require consistently modifying 1048 // per-thread state of the Go runtime. 1049 // 1050 // AllThreadsSyscall is unaware of any threads that are launched 1051 // explicitly by cgo linked code, so the function always returns 1052 // ENOTSUP in binaries that use cgo. 1053 //go:uintptrescapes 1054 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { 1055 if cgo_libc_setegid != nil { 1056 return minus1, minus1, ENOTSUP 1057 } 1058 pc := &allThreadsCaller{ 1059 trap: trap, 1060 a1: a1, 1061 a2: a2, 1062 a3: a3, 1063 } 1064 runtime_doAllThreadsSyscall(pc.doSyscall) 1065 r1 = pc.r1 1066 r2 = pc.r2 1067 err = pc.err 1068 return 1069 } 1070 1071 // AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six 1072 // arguments. 1073 //go:uintptrescapes 1074 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) { 1075 if cgo_libc_setegid != nil { 1076 return minus1, minus1, ENOTSUP 1077 } 1078 pc := &allThreadsCaller{ 1079 trap: trap, 1080 a1: a1, 1081 a2: a2, 1082 a3: a3, 1083 a4: a4, 1084 a5: a5, 1085 a6: a6, 1086 } 1087 runtime_doAllThreadsSyscall(pc.doSyscall6) 1088 r1 = pc.r1 1089 r2 = pc.r2 1090 err = pc.err 1091 return 1092 } 1093 1094 // linked by runtime.cgocall.go 1095 //go:uintptrescapes 1096 func cgocaller(unsafe.Pointer, ...uintptr) uintptr 1097 1098 var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked. 1099 1100 const minus1 = ^uintptr(0) 1101 1102 func Setegid(egid int) (err error) { 1103 if cgo_libc_setegid == nil { 1104 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 { 1105 err = errnoErr(e1) 1106 } 1107 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 { 1108 err = errnoErr(Errno(ret)) 1109 } 1110 return 1111 } 1112 1113 var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked. 1114 1115 func Seteuid(euid int) (err error) { 1116 if cgo_libc_seteuid == nil { 1117 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 { 1118 err = errnoErr(e1) 1119 } 1120 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 { 1121 err = errnoErr(Errno(ret)) 1122 } 1123 return 1124 } 1125 1126 var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked. 1127 1128 func Setgid(gid int) (err error) { 1129 if cgo_libc_setgid == nil { 1130 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 { 1131 err = errnoErr(e1) 1132 } 1133 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 { 1134 err = errnoErr(Errno(ret)) 1135 } 1136 return 1137 } 1138 1139 var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked. 1140 1141 func Setregid(rgid, egid int) (err error) { 1142 if cgo_libc_setregid == nil { 1143 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 { 1144 err = errnoErr(e1) 1145 } 1146 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 { 1147 err = errnoErr(Errno(ret)) 1148 } 1149 return 1150 } 1151 1152 var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked. 1153 1154 func Setresgid(rgid, egid, sgid int) (err error) { 1155 if cgo_libc_setresgid == nil { 1156 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 { 1157 err = errnoErr(e1) 1158 } 1159 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 { 1160 err = errnoErr(Errno(ret)) 1161 } 1162 return 1163 } 1164 1165 var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked. 1166 1167 func Setresuid(ruid, euid, suid int) (err error) { 1168 if cgo_libc_setresuid == nil { 1169 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 { 1170 err = errnoErr(e1) 1171 } 1172 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 { 1173 err = errnoErr(Errno(ret)) 1174 } 1175 return 1176 } 1177 1178 var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked. 1179 1180 func Setreuid(ruid, euid int) (err error) { 1181 if cgo_libc_setreuid == nil { 1182 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 { 1183 err = errnoErr(e1) 1184 } 1185 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 { 1186 err = errnoErr(Errno(ret)) 1187 } 1188 return 1189 } 1190 1191 var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked. 1192 1193 func Setuid(uid int) (err error) { 1194 if cgo_libc_setuid == nil { 1195 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 { 1196 err = errnoErr(e1) 1197 } 1198 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 { 1199 err = errnoErr(Errno(ret)) 1200 } 1201 return 1202 } 1203 1204 //sys Setpriority(which int, who int, prio int) (err error) 1205 //sys Setxattr(path string, attr string, data []byte, flags int) (err error) 1206 //sys Sync() 1207 //sysnb Sysinfo(info *Sysinfo_t) (err error) 1208 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error) 1209 //sysnb Tgkill(tgid int, tid int, sig Signal) (err error) 1210 //sysnb Times(tms *Tms) (ticks uintptr, err error) 1211 //sysnb Umask(mask int) (oldmask int) 1212 //sysnb Uname(buf *Utsname) (err error) 1213 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2 1214 //sys Unshare(flags int) (err error) 1215 //sys write(fd int, p []byte) (n int, err error) 1216 //sys exitThread(code int) (err error) = SYS_EXIT 1217 //sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ 1218 //sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE 1219 1220 // mmap varies by architecture; see syscall_linux_*.go. 1221 //sys munmap(addr uintptr, length uintptr) (err error) 1222 1223 var mapper = &mmapper{ 1224 active: make(map[*byte][]byte), 1225 mmap: mmap, 1226 munmap: munmap, 1227 } 1228 1229 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 1230 return mapper.Mmap(fd, offset, length, prot, flags) 1231 } 1232 1233 func Munmap(b []byte) (err error) { 1234 return mapper.Munmap(b) 1235 } 1236 1237 //sys Madvise(b []byte, advice int) (err error) 1238 //sys Mprotect(b []byte, prot int) (err error) 1239 //sys Mlock(b []byte) (err error) 1240 //sys Munlock(b []byte) (err error) 1241 //sys Mlockall(flags int) (err error) 1242 //sys Munlockall() (err error)