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