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 Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
686 var rsa RawSockaddrAny
687 var len _Socklen = SizeofSockaddrAny
688 nfd, err = accept4(fd, &rsa, &len, flags)
689 if err != nil {
690 return
691 }
692 if len > SizeofSockaddrAny {
693 panic("RawSockaddrAny too small")
694 }
695 sa, err = anyToSockaddr(&rsa)
696 if err != nil {
697 Close(nfd)
698 nfd = 0
699 }
700 return
701 }
702
703 func Getsockname(fd int) (sa Sockaddr, err error) {
704 var rsa RawSockaddrAny
705 var len _Socklen = SizeofSockaddrAny
706 if err = getsockname(fd, &rsa, &len); err != nil {
707 return
708 }
709 return anyToSockaddr(&rsa)
710 }
711
712 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
713 vallen := _Socklen(4)
714 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
715 return value, err
716 }
717
718 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
719 var value IPMreq
720 vallen := _Socklen(SizeofIPMreq)
721 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
722 return &value, err
723 }
724
725 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
726 var value IPMreqn
727 vallen := _Socklen(SizeofIPMreqn)
728 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
729 return &value, err
730 }
731
732 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
733 var value IPv6Mreq
734 vallen := _Socklen(SizeofIPv6Mreq)
735 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
736 return &value, err
737 }
738
739 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
740 var value IPv6MTUInfo
741 vallen := _Socklen(SizeofIPv6MTUInfo)
742 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
743 return &value, err
744 }
745
746 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
747 var value ICMPv6Filter
748 vallen := _Socklen(SizeofICMPv6Filter)
749 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
750 return &value, err
751 }
752
753 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
754 var value Ucred
755 vallen := _Socklen(SizeofUcred)
756 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
757 return &value, err
758 }
759
760 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
761 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
762 }
763
764 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
765 var msg Msghdr
766 msg.Name = (*byte)(unsafe.Pointer(rsa))
767 msg.Namelen = uint32(SizeofSockaddrAny)
768 var iov Iovec
769 if len(p) > 0 {
770 iov.Base = &p[0]
771 iov.SetLen(len(p))
772 }
773 var dummy byte
774 if len(oob) > 0 {
775 if len(p) == 0 {
776 var sockType int
777 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
778 if err != nil {
779 return
780 }
781
782 if sockType != SOCK_DGRAM {
783 iov.Base = &dummy
784 iov.SetLen(1)
785 }
786 }
787 msg.Control = &oob[0]
788 msg.SetControllen(len(oob))
789 }
790 msg.Iov = &iov
791 msg.Iovlen = 1
792 if n, err = recvmsg(fd, &msg, flags); err != nil {
793 return
794 }
795 oobn = int(msg.Controllen)
796 recvflags = int(msg.Flags)
797 return
798 }
799
800 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
801 var msg Msghdr
802 msg.Name = (*byte)(ptr)
803 msg.Namelen = uint32(salen)
804 var iov Iovec
805 if len(p) > 0 {
806 iov.Base = &p[0]
807 iov.SetLen(len(p))
808 }
809 var dummy byte
810 if len(oob) > 0 {
811 if len(p) == 0 {
812 var sockType int
813 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
814 if err != nil {
815 return 0, err
816 }
817
818 if sockType != SOCK_DGRAM {
819 iov.Base = &dummy
820 iov.SetLen(1)
821 }
822 }
823 msg.Control = &oob[0]
824 msg.SetControllen(len(oob))
825 }
826 msg.Iov = &iov
827 msg.Iovlen = 1
828 if n, err = sendmsg(fd, &msg, flags); err != nil {
829 return 0, err
830 }
831 if len(oob) > 0 && len(p) == 0 {
832 n = 0
833 }
834 return n, nil
835 }
836
837
838 func BindToDevice(fd int, device string) (err error) {
839 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
840 }
841
842
843
844
845 func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
846
847
848
849
850
851
852 var buf [sizeofPtr]byte
853
854
855
856
857
858
859 n := 0
860 if addr%sizeofPtr != 0 {
861 err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
862 if err != nil {
863 return 0, err
864 }
865 n += copy(out, buf[addr%sizeofPtr:])
866 out = out[n:]
867 }
868
869
870 for len(out) > 0 {
871
872
873 err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
874 if err != nil {
875 return n, err
876 }
877 copied := copy(out, buf[0:])
878 n += copied
879 out = out[copied:]
880 }
881
882 return n, nil
883 }
884
885 func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
886 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
887 }
888
889 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
890 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
891 }
892
893 func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
894
895
896
897
898 n := 0
899 if addr%sizeofPtr != 0 {
900 var buf [sizeofPtr]byte
901 err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
902 if err != nil {
903 return 0, err
904 }
905 n += copy(buf[addr%sizeofPtr:], data)
906 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
907 err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
908 if err != nil {
909 return 0, err
910 }
911 data = data[n:]
912 }
913
914
915 for len(data) > sizeofPtr {
916 word := *((*uintptr)(unsafe.Pointer(&data[0])))
917 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
918 if err != nil {
919 return n, err
920 }
921 n += sizeofPtr
922 data = data[sizeofPtr:]
923 }
924
925
926 if len(data) > 0 {
927 var buf [sizeofPtr]byte
928 err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
929 if err != nil {
930 return n, err
931 }
932 copy(buf[0:], data)
933 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
934 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
935 if err != nil {
936 return n, err
937 }
938 n += len(data)
939 }
940
941 return n, nil
942 }
943
944 func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
945 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
946 }
947
948 func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
949 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
950 }
951
952 const (
953 _NT_PRSTATUS = 1
954 )
955
956 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
957 var iov Iovec
958 iov.Base = (*byte)(unsafe.Pointer(regsout))
959 iov.SetLen(int(unsafe.Sizeof(*regsout)))
960 return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
961 }
962
963 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
964 var iov Iovec
965 iov.Base = (*byte)(unsafe.Pointer(regs))
966 iov.SetLen(int(unsafe.Sizeof(*regs)))
967 return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
968 }
969
970 func PtraceSetOptions(pid int, options int) (err error) {
971 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
972 }
973
974 func PtraceGetEventMsg(pid int) (msg uint, err error) {
975 var data _C_long
976 err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
977 msg = uint(data)
978 return
979 }
980
981 func PtraceCont(pid int, signal int) (err error) {
982 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
983 }
984
985 func PtraceSyscall(pid int, signal int) (err error) {
986 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
987 }
988
989 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
990
991 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
992
993 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
994
995
996
997 func Reboot(cmd int) (err error) {
998 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
999 }
1000
1001 func ReadDirent(fd int, buf []byte) (n int, err error) {
1002 return Getdents(fd, buf)
1003 }
1004
1005 func direntIno(buf []byte) (uint64, bool) {
1006 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
1007 }
1008
1009 func direntReclen(buf []byte) (uint64, bool) {
1010 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
1011 }
1012
1013 func direntNamlen(buf []byte) (uint64, bool) {
1014 reclen, ok := direntReclen(buf)
1015 if !ok {
1016 return 0, false
1017 }
1018 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
1019 }
1020
1021
1022
1023 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1024
1025
1026 if data == "" {
1027 return mount(source, target, fstype, flags, nil)
1028 }
1029 datap, err := BytePtrFromString(data)
1030 if err != nil {
1031 return err
1032 }
1033 return mount(source, target, fstype, flags, datap)
1034 }
1035
1036
1037
1038
1039
1040
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 func Getpgrp() (pid int) {
1064 pid, _ = Getpgid(0)
1065 return
1066 }
1067
1068
1069
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 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1118 if cgo_libc_setegid != nil {
1119 return minus1, minus1, ENOTSUP
1120 }
1121 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1122 return r1, r2, Errno(errno)
1123 }
1124
1125
1126
1127
1128
1129 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1130 if cgo_libc_setegid != nil {
1131 return minus1, minus1, ENOTSUP
1132 }
1133 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1134 return r1, r2, Errno(errno)
1135 }
1136
1137
1138
1139
1140 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1141
1142 var cgo_libc_setegid unsafe.Pointer
1143
1144 const minus1 = ^uintptr(0)
1145
1146 func Setegid(egid int) (err error) {
1147 if cgo_libc_setegid == nil {
1148 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1149 err = errnoErr(e1)
1150 }
1151 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1152 err = errnoErr(Errno(ret))
1153 }
1154 return
1155 }
1156
1157 var cgo_libc_seteuid unsafe.Pointer
1158
1159 func Seteuid(euid int) (err error) {
1160 if cgo_libc_seteuid == nil {
1161 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1162 err = errnoErr(e1)
1163 }
1164 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1165 err = errnoErr(Errno(ret))
1166 }
1167 return
1168 }
1169
1170 var cgo_libc_setgid unsafe.Pointer
1171
1172 func Setgid(gid int) (err error) {
1173 if cgo_libc_setgid == nil {
1174 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1175 err = errnoErr(e1)
1176 }
1177 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1178 err = errnoErr(Errno(ret))
1179 }
1180 return
1181 }
1182
1183 var cgo_libc_setregid unsafe.Pointer
1184
1185 func Setregid(rgid, egid int) (err error) {
1186 if cgo_libc_setregid == nil {
1187 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1188 err = errnoErr(e1)
1189 }
1190 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1191 err = errnoErr(Errno(ret))
1192 }
1193 return
1194 }
1195
1196 var cgo_libc_setresgid unsafe.Pointer
1197
1198 func Setresgid(rgid, egid, sgid int) (err error) {
1199 if cgo_libc_setresgid == nil {
1200 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1201 err = errnoErr(e1)
1202 }
1203 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1204 err = errnoErr(Errno(ret))
1205 }
1206 return
1207 }
1208
1209 var cgo_libc_setresuid unsafe.Pointer
1210
1211 func Setresuid(ruid, euid, suid int) (err error) {
1212 if cgo_libc_setresuid == nil {
1213 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1214 err = errnoErr(e1)
1215 }
1216 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1217 err = errnoErr(Errno(ret))
1218 }
1219 return
1220 }
1221
1222 var cgo_libc_setreuid unsafe.Pointer
1223
1224 func Setreuid(ruid, euid int) (err error) {
1225 if cgo_libc_setreuid == nil {
1226 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1227 err = errnoErr(e1)
1228 }
1229 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1230 err = errnoErr(Errno(ret))
1231 }
1232 return
1233 }
1234
1235 var cgo_libc_setuid unsafe.Pointer
1236
1237 func Setuid(uid int) (err error) {
1238 if cgo_libc_setuid == nil {
1239 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1240 err = errnoErr(e1)
1241 }
1242 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1243 err = errnoErr(Errno(ret))
1244 }
1245 return
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 var mapper = &mmapper{
1267 active: make(map[*byte][]byte),
1268 mmap: mmap,
1269 munmap: munmap,
1270 }
1271
1272 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1273 return mapper.Mmap(fd, offset, length, prot, flags)
1274 }
1275
1276 func Munmap(b []byte) (err error) {
1277 return mapper.Munmap(b)
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1295 err = prlimit1(pid, resource, newlimit, old)
1296 if err == nil && newlimit != nil && resource == RLIMIT_NOFILE && (pid == 0 || pid == Getpid()) {
1297 origRlimitNofile.Store(nil)
1298 }
1299 return err
1300 }
1301
View as plain text