Source file
src/syscall/syscall_linux.go
1
2
3
4
5
6
7
8
9
10
11
12 package syscall
13
14 import (
15 "internal/itoa"
16 "runtime"
17 "unsafe"
18 )
19
20
21
22
23
24
25 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
26
27
28
29
30
31
32
33
34
35 func runtime_entersyscall()
36
37
38 func runtime_exitsyscall()
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
62 return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
63 }
64
65
66
67
68 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
69 runtime_entersyscall()
70
71
72
73
74
75
76
77
78
79
80
81
82 r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
83 runtime_exitsyscall()
84 return
85 }
86
87
88
89
90 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
91 runtime_entersyscall()
92 r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
93 runtime_exitsyscall()
94 return
95 }
96
97 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
98 func rawVforkSyscall(trap, a1, a2 uintptr) (r1 uintptr, err Errno)
99
100
103
104 func Access(path string, mode uint32) (err error) {
105 return Faccessat(_AT_FDCWD, path, mode, 0)
106 }
107
108 func Chmod(path string, mode uint32) (err error) {
109 return Fchmodat(_AT_FDCWD, path, mode, 0)
110 }
111
112 func Chown(path string, uid int, gid int) (err error) {
113 return Fchownat(_AT_FDCWD, path, uid, gid, 0)
114 }
115
116 func Creat(path string, mode uint32) (fd int, err error) {
117 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
118 }
119
120 func EpollCreate(size int) (fd int, err error) {
121 if size <= 0 {
122 return -1, EINVAL
123 }
124 return EpollCreate1(0)
125 }
126
127 func isGroupMember(gid int) bool {
128 groups, err := Getgroups()
129 if err != nil {
130 return false
131 }
132
133 for _, g := range groups {
134 if g == gid {
135 return true
136 }
137 }
138 return false
139 }
140
141 func isCapDacOverrideSet() bool {
142 const _CAP_DAC_OVERRIDE = 1
143 var c caps
144 c.hdr.version = _LINUX_CAPABILITY_VERSION_3
145
146 _, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
147
148 return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
149 }
150
151
152
153
154 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
155 if flags == 0 {
156 return faccessat(dirfd, path, mode)
157 }
158
159
160
161
162
163
164
165
166 if runtime.GOOS != "android" {
167 if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
168 return err
169 }
170 }
171
172
173
174
175
176
177
178 if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
179 return EINVAL
180 }
181
182 var st Stat_t
183 if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
184 return err
185 }
186
187 mode &= 7
188 if mode == 0 {
189 return nil
190 }
191
192
193 var uid int
194 if flags&_AT_EACCESS != 0 {
195 uid = Geteuid()
196 if uid != 0 && isCapDacOverrideSet() {
197
198
199
200 uid = 0
201 }
202 } else {
203 uid = Getuid()
204 }
205
206 if uid == 0 {
207 if mode&1 == 0 {
208
209 return nil
210 }
211 if st.Mode&0111 != 0 {
212
213 return nil
214 }
215 return EACCES
216 }
217
218 var fmode uint32
219 if uint32(uid) == st.Uid {
220 fmode = (st.Mode >> 6) & 7
221 } else {
222 var gid int
223 if flags&_AT_EACCESS != 0 {
224 gid = Getegid()
225 } else {
226 gid = Getgid()
227 }
228
229 if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
230 fmode = (st.Mode >> 3) & 7
231 } else {
232 fmode = st.Mode & 7
233 }
234 }
235
236 if fmode&mode == mode {
237 return nil
238 }
239
240 return EACCES
241 }
242
243
244
245 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
246
247
248
249 if flags&^_AT_SYMLINK_NOFOLLOW != 0 {
250 return EINVAL
251 } else if flags&_AT_SYMLINK_NOFOLLOW != 0 {
252 return EOPNOTSUPP
253 }
254 return fchmodat(dirfd, path, mode)
255 }
256
257
258
259 func Link(oldpath string, newpath string) (err error) {
260 return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
261 }
262
263 func Mkdir(path string, mode uint32) (err error) {
264 return Mkdirat(_AT_FDCWD, path, mode)
265 }
266
267 func Mknod(path string, mode uint32, dev int) (err error) {
268 return Mknodat(_AT_FDCWD, path, mode, dev)
269 }
270
271 func Open(path string, mode int, perm uint32) (fd int, err error) {
272 return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
273 }
274
275
276
277 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
278 return openat(dirfd, path, flags|O_LARGEFILE, mode)
279 }
280
281 func Pipe(p []int) error {
282 return Pipe2(p, 0)
283 }
284
285
286
287 func Pipe2(p []int, flags int) error {
288 if len(p) != 2 {
289 return EINVAL
290 }
291 var pp [2]_C_int
292 err := pipe2(&pp, flags)
293 if err == nil {
294 p[0] = int(pp[0])
295 p[1] = int(pp[1])
296 }
297 return err
298 }
299
300
301
302 func Readlink(path string, buf []byte) (n int, err error) {
303 return readlinkat(_AT_FDCWD, path, buf)
304 }
305
306 func Rename(oldpath string, newpath string) (err error) {
307 return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
308 }
309
310 func Rmdir(path string) error {
311 return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
312 }
313
314
315
316 func Symlink(oldpath string, newpath string) (err error) {
317 return symlinkat(oldpath, _AT_FDCWD, newpath)
318 }
319
320 func Unlink(path string) error {
321 return unlinkat(_AT_FDCWD, path, 0)
322 }
323
324
325
326 func Unlinkat(dirfd int, path string) error {
327 return unlinkat(dirfd, path, 0)
328 }
329
330 func Utimes(path string, tv []Timeval) (err error) {
331 if len(tv) != 2 {
332 return EINVAL
333 }
334 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
335 }
336
337
338
339 func UtimesNano(path string, ts []Timespec) (err error) {
340 if len(ts) != 2 {
341 return EINVAL
342 }
343 return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
344 }
345
346 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
347 if len(tv) != 2 {
348 return EINVAL
349 }
350 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
351 }
352
353 func Futimes(fd int, tv []Timeval) (err error) {
354
355
356 return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
357 }
358
359 const ImplementsGetwd = true
360
361
362
363 func Getwd() (wd string, err error) {
364 var buf [PathMax]byte
365 n, err := Getcwd(buf[0:])
366 if err != nil {
367 return "", err
368 }
369
370 if n < 1 || n > len(buf) || buf[n-1] != 0 {
371 return "", EINVAL
372 }
373
374
375
376 if buf[0] != '/' {
377 return "", ENOENT
378 }
379
380 return string(buf[0 : n-1]), nil
381 }
382
383 func Getgroups() (gids []int, err error) {
384 n, err := getgroups(0, nil)
385 if err != nil {
386 return nil, err
387 }
388 if n == 0 {
389 return nil, nil
390 }
391
392
393 if n < 0 || n > 1<<20 {
394 return nil, EINVAL
395 }
396
397 a := make([]_Gid_t, n)
398 n, err = getgroups(n, &a[0])
399 if err != nil {
400 return nil, err
401 }
402 gids = make([]int, n)
403 for i, v := range a[0:n] {
404 gids[i] = int(v)
405 }
406 return
407 }
408
409 var cgo_libc_setgroups unsafe.Pointer
410
411 func Setgroups(gids []int) (err error) {
412 n := uintptr(len(gids))
413 if n == 0 {
414 if cgo_libc_setgroups == nil {
415 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
416 err = errnoErr(e1)
417 }
418 return
419 }
420 if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
421 err = errnoErr(Errno(ret))
422 }
423 return
424 }
425
426 a := make([]_Gid_t, len(gids))
427 for i, v := range gids {
428 a[i] = _Gid_t(v)
429 }
430 if cgo_libc_setgroups == nil {
431 if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
432 err = errnoErr(e1)
433 }
434 return
435 }
436 if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
437 err = errnoErr(Errno(ret))
438 }
439 return
440 }
441
442 type WaitStatus uint32
443
444
445
446
447
448
449
450
451
452
453 const (
454 mask = 0x7F
455 core = 0x80
456 exited = 0x00
457 stopped = 0x7F
458 shift = 8
459 )
460
461 func (w WaitStatus) Exited() bool { return w&mask == exited }
462
463 func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
464
465 func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
466
467 func (w WaitStatus) Continued() bool { return w == 0xFFFF }
468
469 func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
470
471 func (w WaitStatus) ExitStatus() int {
472 if !w.Exited() {
473 return -1
474 }
475 return int(w>>shift) & 0xFF
476 }
477
478 func (w WaitStatus) Signal() Signal {
479 if !w.Signaled() {
480 return -1
481 }
482 return Signal(w & mask)
483 }
484
485 func (w WaitStatus) StopSignal() Signal {
486 if !w.Stopped() {
487 return -1
488 }
489 return Signal(w>>shift) & 0xFF
490 }
491
492 func (w WaitStatus) TrapCause() int {
493 if w.StopSignal() != SIGTRAP {
494 return -1
495 }
496 return int(w>>shift) >> 8
497 }
498
499
500
501 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
502 var status _C_int
503 wpid, err = wait4(pid, &status, options, rusage)
504 if wstatus != nil {
505 *wstatus = WaitStatus(status)
506 }
507 return
508 }
509
510 func Mkfifo(path string, mode uint32) (err error) {
511 return Mknod(path, mode|S_IFIFO, 0)
512 }
513
514 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
515 if sa.Port < 0 || sa.Port > 0xFFFF {
516 return nil, 0, EINVAL
517 }
518 sa.raw.Family = AF_INET
519 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
520 p[0] = byte(sa.Port >> 8)
521 p[1] = byte(sa.Port)
522 sa.raw.Addr = sa.Addr
523 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
524 }
525
526 func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
527 if sa.Port < 0 || sa.Port > 0xFFFF {
528 return nil, 0, EINVAL
529 }
530 sa.raw.Family = AF_INET6
531 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
532 p[0] = byte(sa.Port >> 8)
533 p[1] = byte(sa.Port)
534 sa.raw.Scope_id = sa.ZoneId
535 sa.raw.Addr = sa.Addr
536 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
537 }
538
539 func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
540 name := sa.Name
541 n := len(name)
542 if n > len(sa.raw.Path) {
543 return nil, 0, EINVAL
544 }
545 if n == len(sa.raw.Path) && name[0] != '@' {
546 return nil, 0, EINVAL
547 }
548 sa.raw.Family = AF_UNIX
549 for i := 0; i < n; i++ {
550 sa.raw.Path[i] = int8(name[i])
551 }
552
553 sl := _Socklen(2)
554 if n > 0 {
555 sl += _Socklen(n) + 1
556 }
557 if sa.raw.Path[0] == '@' {
558 sa.raw.Path[0] = 0
559
560 sl--
561 }
562
563 return unsafe.Pointer(&sa.raw), sl, nil
564 }
565
566 type SockaddrLinklayer struct {
567 Protocol uint16
568 Ifindex int
569 Hatype uint16
570 Pkttype uint8
571 Halen uint8
572 Addr [8]byte
573 raw RawSockaddrLinklayer
574 }
575
576 func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
577 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
578 return nil, 0, EINVAL
579 }
580 sa.raw.Family = AF_PACKET
581 sa.raw.Protocol = sa.Protocol
582 sa.raw.Ifindex = int32(sa.Ifindex)
583 sa.raw.Hatype = sa.Hatype
584 sa.raw.Pkttype = sa.Pkttype
585 sa.raw.Halen = sa.Halen
586 sa.raw.Addr = sa.Addr
587 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
588 }
589
590 type SockaddrNetlink struct {
591 Family uint16
592 Pad uint16
593 Pid uint32
594 Groups uint32
595 raw RawSockaddrNetlink
596 }
597
598 func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
599 sa.raw.Family = AF_NETLINK
600 sa.raw.Pad = sa.Pad
601 sa.raw.Pid = sa.Pid
602 sa.raw.Groups = sa.Groups
603 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
604 }
605
606 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
607 switch rsa.Addr.Family {
608 case AF_NETLINK:
609 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
610 sa := new(SockaddrNetlink)
611 sa.Family = pp.Family
612 sa.Pad = pp.Pad
613 sa.Pid = pp.Pid
614 sa.Groups = pp.Groups
615 return sa, nil
616
617 case AF_PACKET:
618 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
619 sa := new(SockaddrLinklayer)
620 sa.Protocol = pp.Protocol
621 sa.Ifindex = int(pp.Ifindex)
622 sa.Hatype = pp.Hatype
623 sa.Pkttype = pp.Pkttype
624 sa.Halen = pp.Halen
625 sa.Addr = pp.Addr
626 return sa, nil
627
628 case AF_UNIX:
629 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
630 sa := new(SockaddrUnix)
631 if pp.Path[0] == 0 {
632
633
634
635
636
637 pp.Path[0] = '@'
638 }
639
640
641
642
643
644
645 n := 0
646 for n < len(pp.Path) && pp.Path[n] != 0 {
647 n++
648 }
649 sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
650 return sa, nil
651
652 case AF_INET:
653 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
654 sa := new(SockaddrInet4)
655 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
656 sa.Port = int(p[0])<<8 + int(p[1])
657 sa.Addr = pp.Addr
658 return sa, nil
659
660 case AF_INET6:
661 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
662 sa := new(SockaddrInet6)
663 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
664 sa.Port = int(p[0])<<8 + int(p[1])
665 sa.ZoneId = pp.Scope_id
666 sa.Addr = pp.Addr
667 return sa, nil
668 }
669 return nil, EAFNOSUPPORT
670 }
671
672 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
673 var rsa RawSockaddrAny
674 var len _Socklen = SizeofSockaddrAny
675 nfd, err = accept4(fd, &rsa, &len, flags)
676 if err != nil {
677 return
678 }
679 if len > SizeofSockaddrAny {
680 panic("RawSockaddrAny too small")
681 }
682 sa, err = anyToSockaddr(&rsa)
683 if err != nil {
684 Close(nfd)
685 nfd = 0
686 }
687 return
688 }
689
690 func Getsockname(fd int) (sa Sockaddr, err error) {
691 var rsa RawSockaddrAny
692 var len _Socklen = SizeofSockaddrAny
693 if err = getsockname(fd, &rsa, &len); err != nil {
694 return
695 }
696 return anyToSockaddr(&rsa)
697 }
698
699 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
700 vallen := _Socklen(4)
701 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
702 return value, err
703 }
704
705 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
706 var value IPMreq
707 vallen := _Socklen(SizeofIPMreq)
708 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
709 return &value, err
710 }
711
712 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
713 var value IPMreqn
714 vallen := _Socklen(SizeofIPMreqn)
715 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
716 return &value, err
717 }
718
719 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
720 var value IPv6Mreq
721 vallen := _Socklen(SizeofIPv6Mreq)
722 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
723 return &value, err
724 }
725
726 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
727 var value IPv6MTUInfo
728 vallen := _Socklen(SizeofIPv6MTUInfo)
729 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
730 return &value, err
731 }
732
733 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
734 var value ICMPv6Filter
735 vallen := _Socklen(SizeofICMPv6Filter)
736 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
737 return &value, err
738 }
739
740 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
741 var value Ucred
742 vallen := _Socklen(SizeofUcred)
743 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
744 return &value, err
745 }
746
747 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
748 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
749 }
750
751 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
752 var msg Msghdr
753 msg.Name = (*byte)(unsafe.Pointer(rsa))
754 msg.Namelen = uint32(SizeofSockaddrAny)
755 var iov Iovec
756 if len(p) > 0 {
757 iov.Base = &p[0]
758 iov.SetLen(len(p))
759 }
760 var dummy byte
761 if len(oob) > 0 {
762 if len(p) == 0 {
763 var sockType int
764 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
765 if err != nil {
766 return
767 }
768
769 if sockType != SOCK_DGRAM {
770 iov.Base = &dummy
771 iov.SetLen(1)
772 }
773 }
774 msg.Control = &oob[0]
775 msg.SetControllen(len(oob))
776 }
777 msg.Iov = &iov
778 msg.Iovlen = 1
779 if n, err = recvmsg(fd, &msg, flags); err != nil {
780 return
781 }
782 oobn = int(msg.Controllen)
783 recvflags = int(msg.Flags)
784 return
785 }
786
787 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
788 var msg Msghdr
789 msg.Name = (*byte)(ptr)
790 msg.Namelen = uint32(salen)
791 var iov Iovec
792 if len(p) > 0 {
793 iov.Base = &p[0]
794 iov.SetLen(len(p))
795 }
796 var dummy byte
797 if len(oob) > 0 {
798 if len(p) == 0 {
799 var sockType int
800 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
801 if err != nil {
802 return 0, err
803 }
804
805 if sockType != SOCK_DGRAM {
806 iov.Base = &dummy
807 iov.SetLen(1)
808 }
809 }
810 msg.Control = &oob[0]
811 msg.SetControllen(len(oob))
812 }
813 msg.Iov = &iov
814 msg.Iovlen = 1
815 if n, err = sendmsg(fd, &msg, flags); err != nil {
816 return 0, err
817 }
818 if len(oob) > 0 && len(p) == 0 {
819 n = 0
820 }
821 return n, nil
822 }
823
824
825 func BindToDevice(fd int, device string) (err error) {
826 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
827 }
828
829
830
831
832 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
833
834
835
836
837
838
839 var buf [sizeofPtr]byte
840
841
842
843
844
845
846 n := 0
847 if addr%sizeofPtr != 0 {
848 err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
849 if err != nil {
850 return 0, err
851 }
852 n += copy(out, buf[addr%sizeofPtr:])
853 out = out[n:]
854 }
855
856
857 for len(out) > 0 {
858
859
860 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
861 if err != nil {
862 return n, err
863 }
864 copied := copy(out, buf[0:])
865 n += copied
866 out = out[copied:]
867 }
868
869 return n, nil
870 }
871
872 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
873 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
874 }
875
876 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
877 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
878 }
879
880 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
881
882
883
884
885 n := 0
886 if addr%sizeofPtr != 0 {
887 var buf [sizeofPtr]byte
888 err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
889 if err != nil {
890 return 0, err
891 }
892 n += copy(buf[addr%sizeofPtr:], data)
893 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
894 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
895 if err != nil {
896 return 0, err
897 }
898 data = data[n:]
899 }
900
901
902 for len(data) > sizeofPtr {
903 word := *((*uintptr)(unsafe.Pointer(&data[0])))
904 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
905 if err != nil {
906 return n, err
907 }
908 n += sizeofPtr
909 data = data[sizeofPtr:]
910 }
911
912
913 if len(data) > 0 {
914 var buf [sizeofPtr]byte
915 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
916 if err != nil {
917 return n, err
918 }
919 copy(buf[0:], data)
920 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
921 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
922 if err != nil {
923 return n, err
924 }
925 n += len(data)
926 }
927
928 return n, nil
929 }
930
931 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
932 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
933 }
934
935 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
936 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
937 }
938
939 const (
940 _NT_PRSTATUS = 1
941 )
942
943 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
944 var iov Iovec
945 iov.Base = (*byte)(unsafe.Pointer(regsout))
946 iov.SetLen(int(unsafe.Sizeof(*regsout)))
947 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
948 }
949
950 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
951 var iov Iovec
952 iov.Base = (*byte)(unsafe.Pointer(regs))
953 iov.SetLen(int(unsafe.Sizeof(*regs)))
954 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
955 }
956
957 func PtraceSetOptions(pid int, options int) (err error) {
958 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
959 }
960
961 func PtraceGetEventMsg(pid int) (msg uint, err error) {
962 var data _C_long
963 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
964 msg = uint(data)
965 return
966 }
967
968 func PtraceCont(pid int, signal int) (err error) {
969 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
970 }
971
972 func PtraceSyscall(pid int, signal int) (err error) {
973 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
974 }
975
976 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
977
978 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
979
980 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
981
982
983
984 func Reboot(cmd int) (err error) {
985 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
986 }
987
988 func ReadDirent(fd int, buf []byte) (n int, err error) {
989 return Getdents(fd, buf)
990 }
991
992 func direntIno(buf []byte) (uint64, bool) {
993 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
994 }
995
996 func direntReclen(buf []byte) (uint64, bool) {
997 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
998 }
999
1000 func direntNamlen(buf []byte) (uint64, bool) {
1001 reclen, ok := direntReclen(buf)
1002 if !ok {
1003 return 0, false
1004 }
1005 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1006 }
1007
1008
1009
1010 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1011
1012
1013 if data == "" {
1014 return mount(source, target, fstype, flags, nil)
1015 }
1016 datap, err := BytePtrFromString(data)
1017 if err != nil {
1018 return err
1019 }
1020 return mount(source, target, fstype, flags, datap)
1021 }
1022
1023
1024
1025
1026
1027
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 func Getpgrp() (pid int) {
1051 pid, _ = Getpgid(0)
1052 return
1053 }
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1105 if cgo_libc_setegid != nil {
1106 return minus1, minus1, ENOTSUP
1107 }
1108 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1109 return r1, r2, Errno(errno)
1110 }
1111
1112
1113
1114
1115
1116 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1117 if cgo_libc_setegid != nil {
1118 return minus1, minus1, ENOTSUP
1119 }
1120 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1121 return r1, r2, Errno(errno)
1122 }
1123
1124
1125
1126
1127 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1128
1129 var cgo_libc_setegid unsafe.Pointer
1130
1131 const minus1 = ^uintptr(0)
1132
1133 func Setegid(egid int) (err error) {
1134 if cgo_libc_setegid == nil {
1135 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1136 err = errnoErr(e1)
1137 }
1138 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1139 err = errnoErr(Errno(ret))
1140 }
1141 return
1142 }
1143
1144 var cgo_libc_seteuid unsafe.Pointer
1145
1146 func Seteuid(euid int) (err error) {
1147 if cgo_libc_seteuid == nil {
1148 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1149 err = errnoErr(e1)
1150 }
1151 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1152 err = errnoErr(Errno(ret))
1153 }
1154 return
1155 }
1156
1157 var cgo_libc_setgid unsafe.Pointer
1158
1159 func Setgid(gid int) (err error) {
1160 if cgo_libc_setgid == nil {
1161 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1162 err = errnoErr(e1)
1163 }
1164 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1165 err = errnoErr(Errno(ret))
1166 }
1167 return
1168 }
1169
1170 var cgo_libc_setregid unsafe.Pointer
1171
1172 func Setregid(rgid, egid int) (err error) {
1173 if cgo_libc_setregid == nil {
1174 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1175 err = errnoErr(e1)
1176 }
1177 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1178 err = errnoErr(Errno(ret))
1179 }
1180 return
1181 }
1182
1183 var cgo_libc_setresgid unsafe.Pointer
1184
1185 func Setresgid(rgid, egid, sgid int) (err error) {
1186 if cgo_libc_setresgid == nil {
1187 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1188 err = errnoErr(e1)
1189 }
1190 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1191 err = errnoErr(Errno(ret))
1192 }
1193 return
1194 }
1195
1196 var cgo_libc_setresuid unsafe.Pointer
1197
1198 func Setresuid(ruid, euid, suid int) (err error) {
1199 if cgo_libc_setresuid == nil {
1200 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1201 err = errnoErr(e1)
1202 }
1203 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1204 err = errnoErr(Errno(ret))
1205 }
1206 return
1207 }
1208
1209 var cgo_libc_setreuid unsafe.Pointer
1210
1211 func Setreuid(ruid, euid int) (err error) {
1212 if cgo_libc_setreuid == nil {
1213 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1214 err = errnoErr(e1)
1215 }
1216 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1217 err = errnoErr(Errno(ret))
1218 }
1219 return
1220 }
1221
1222 var cgo_libc_setuid unsafe.Pointer
1223
1224 func Setuid(uid int) (err error) {
1225 if cgo_libc_setuid == nil {
1226 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1227 err = errnoErr(e1)
1228 }
1229 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1230 err = errnoErr(Errno(ret))
1231 }
1232 return
1233 }
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254 var mapper = &mmapper{
1255 active: make(map[*byte][]byte),
1256 mmap: mmap,
1257 munmap: munmap,
1258 }
1259
1260 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1261 return mapper.Mmap(fd, offset, length, prot, flags)
1262 }
1263
1264 func Munmap(b []byte) (err error) {
1265 return mapper.Munmap(b)
1266 }
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278 func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1279 err = prlimit1(pid, resource, newlimit, old)
1280 if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
1281 origRlimitNofile.Store(Rlimit{0, 0})
1282 }
1283 return err
1284 }
1285
View as plain text