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 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
650 sa.Name = string(bytes)
651 return sa, nil
652
653 case AF_INET:
654 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
655 sa := new(SockaddrInet4)
656 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
657 sa.Port = int(p[0])<<8 + int(p[1])
658 sa.Addr = pp.Addr
659 return sa, nil
660
661 case AF_INET6:
662 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
663 sa := new(SockaddrInet6)
664 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
665 sa.Port = int(p[0])<<8 + int(p[1])
666 sa.ZoneId = pp.Scope_id
667 sa.Addr = pp.Addr
668 return sa, nil
669 }
670 return nil, EAFNOSUPPORT
671 }
672
673 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
674 var rsa RawSockaddrAny
675 var len _Socklen = SizeofSockaddrAny
676 nfd, err = accept4(fd, &rsa, &len, flags)
677 if err != nil {
678 return
679 }
680 if len > SizeofSockaddrAny {
681 panic("RawSockaddrAny too small")
682 }
683 sa, err = anyToSockaddr(&rsa)
684 if err != nil {
685 Close(nfd)
686 nfd = 0
687 }
688 return
689 }
690
691 func Getsockname(fd int) (sa Sockaddr, err error) {
692 var rsa RawSockaddrAny
693 var len _Socklen = SizeofSockaddrAny
694 if err = getsockname(fd, &rsa, &len); err != nil {
695 return
696 }
697 return anyToSockaddr(&rsa)
698 }
699
700 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
701 vallen := _Socklen(4)
702 err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
703 return value, err
704 }
705
706 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
707 var value IPMreq
708 vallen := _Socklen(SizeofIPMreq)
709 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
710 return &value, err
711 }
712
713 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
714 var value IPMreqn
715 vallen := _Socklen(SizeofIPMreqn)
716 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
717 return &value, err
718 }
719
720 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
721 var value IPv6Mreq
722 vallen := _Socklen(SizeofIPv6Mreq)
723 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
724 return &value, err
725 }
726
727 func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
728 var value IPv6MTUInfo
729 vallen := _Socklen(SizeofIPv6MTUInfo)
730 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
731 return &value, err
732 }
733
734 func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
735 var value ICMPv6Filter
736 vallen := _Socklen(SizeofICMPv6Filter)
737 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
738 return &value, err
739 }
740
741 func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
742 var value Ucred
743 vallen := _Socklen(SizeofUcred)
744 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
745 return &value, err
746 }
747
748 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
749 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
750 }
751
752 func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
753 var msg Msghdr
754 msg.Name = (*byte)(unsafe.Pointer(rsa))
755 msg.Namelen = uint32(SizeofSockaddrAny)
756 var iov Iovec
757 if len(p) > 0 {
758 iov.Base = &p[0]
759 iov.SetLen(len(p))
760 }
761 var dummy byte
762 if len(oob) > 0 {
763 if len(p) == 0 {
764 var sockType int
765 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
766 if err != nil {
767 return
768 }
769
770 if sockType != SOCK_DGRAM {
771 iov.Base = &dummy
772 iov.SetLen(1)
773 }
774 }
775 msg.Control = &oob[0]
776 msg.SetControllen(len(oob))
777 }
778 msg.Iov = &iov
779 msg.Iovlen = 1
780 if n, err = recvmsg(fd, &msg, flags); err != nil {
781 return
782 }
783 oobn = int(msg.Controllen)
784 recvflags = int(msg.Flags)
785 return
786 }
787
788 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
789 var msg Msghdr
790 msg.Name = (*byte)(ptr)
791 msg.Namelen = uint32(salen)
792 var iov Iovec
793 if len(p) > 0 {
794 iov.Base = &p[0]
795 iov.SetLen(len(p))
796 }
797 var dummy byte
798 if len(oob) > 0 {
799 if len(p) == 0 {
800 var sockType int
801 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
802 if err != nil {
803 return 0, err
804 }
805
806 if sockType != SOCK_DGRAM {
807 iov.Base = &dummy
808 iov.SetLen(1)
809 }
810 }
811 msg.Control = &oob[0]
812 msg.SetControllen(len(oob))
813 }
814 msg.Iov = &iov
815 msg.Iovlen = 1
816 if n, err = sendmsg(fd, &msg, flags); err != nil {
817 return 0, err
818 }
819 if len(oob) > 0 && len(p) == 0 {
820 n = 0
821 }
822 return n, nil
823 }
824
825
826 func BindToDevice(fd int, device string) (err error) {
827 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
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 = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(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 = ptrace(req, pid, addr+uintptr(n), uintptr(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 = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(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 = ptrace(peekReq, pid, addr+uintptr(n), uintptr(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 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
940 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
941 }
942
943 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
944 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
945 }
946
947 func PtraceSetOptions(pid int, options int) (err error) {
948 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
949 }
950
951 func PtraceGetEventMsg(pid int) (msg uint, err error) {
952 var data _C_long
953 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
954 msg = uint(data)
955 return
956 }
957
958 func PtraceCont(pid int, signal int) (err error) {
959 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
960 }
961
962 func PtraceSyscall(pid int, signal int) (err error) {
963 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
964 }
965
966 func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
967
968 func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
969
970 func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
971
972
973
974 func Reboot(cmd int) (err error) {
975 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
976 }
977
978 func ReadDirent(fd int, buf []byte) (n int, err error) {
979 return Getdents(fd, buf)
980 }
981
982 func direntIno(buf []byte) (uint64, bool) {
983 return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
984 }
985
986 func direntReclen(buf []byte) (uint64, bool) {
987 return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
988 }
989
990 func direntNamlen(buf []byte) (uint64, bool) {
991 reclen, ok := direntReclen(buf)
992 if !ok {
993 return 0, false
994 }
995 return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
996 }
997
998
999
1000 func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1001
1002
1003 if data == "" {
1004 return mount(source, target, fstype, flags, nil)
1005 }
1006 datap, err := BytePtrFromString(data)
1007 if err != nil {
1008 return err
1009 }
1010 return mount(source, target, fstype, flags, datap)
1011 }
1012
1013
1014
1015
1016
1017
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 func Getpgrp() (pid int) {
1041 pid, _ = Getpgid(0)
1042 return
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075 func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
1095 if cgo_libc_setegid != nil {
1096 return minus1, minus1, ENOTSUP
1097 }
1098 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
1099 return r1, r2, Errno(errno)
1100 }
1101
1102
1103
1104
1105
1106 func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
1107 if cgo_libc_setegid != nil {
1108 return minus1, minus1, ENOTSUP
1109 }
1110 r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
1111 return r1, r2, Errno(errno)
1112 }
1113
1114
1115
1116
1117 func cgocaller(unsafe.Pointer, ...uintptr) uintptr
1118
1119 var cgo_libc_setegid unsafe.Pointer
1120
1121 const minus1 = ^uintptr(0)
1122
1123 func Setegid(egid int) (err error) {
1124 if cgo_libc_setegid == nil {
1125 if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
1126 err = errnoErr(e1)
1127 }
1128 } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
1129 err = errnoErr(Errno(ret))
1130 }
1131 return
1132 }
1133
1134 var cgo_libc_seteuid unsafe.Pointer
1135
1136 func Seteuid(euid int) (err error) {
1137 if cgo_libc_seteuid == nil {
1138 if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
1139 err = errnoErr(e1)
1140 }
1141 } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
1142 err = errnoErr(Errno(ret))
1143 }
1144 return
1145 }
1146
1147 var cgo_libc_setgid unsafe.Pointer
1148
1149 func Setgid(gid int) (err error) {
1150 if cgo_libc_setgid == nil {
1151 if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
1152 err = errnoErr(e1)
1153 }
1154 } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
1155 err = errnoErr(Errno(ret))
1156 }
1157 return
1158 }
1159
1160 var cgo_libc_setregid unsafe.Pointer
1161
1162 func Setregid(rgid, egid int) (err error) {
1163 if cgo_libc_setregid == nil {
1164 if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
1165 err = errnoErr(e1)
1166 }
1167 } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
1168 err = errnoErr(Errno(ret))
1169 }
1170 return
1171 }
1172
1173 var cgo_libc_setresgid unsafe.Pointer
1174
1175 func Setresgid(rgid, egid, sgid int) (err error) {
1176 if cgo_libc_setresgid == nil {
1177 if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
1178 err = errnoErr(e1)
1179 }
1180 } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
1181 err = errnoErr(Errno(ret))
1182 }
1183 return
1184 }
1185
1186 var cgo_libc_setresuid unsafe.Pointer
1187
1188 func Setresuid(ruid, euid, suid int) (err error) {
1189 if cgo_libc_setresuid == nil {
1190 if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
1191 err = errnoErr(e1)
1192 }
1193 } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
1194 err = errnoErr(Errno(ret))
1195 }
1196 return
1197 }
1198
1199 var cgo_libc_setreuid unsafe.Pointer
1200
1201 func Setreuid(ruid, euid int) (err error) {
1202 if cgo_libc_setreuid == nil {
1203 if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
1204 err = errnoErr(e1)
1205 }
1206 } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
1207 err = errnoErr(Errno(ret))
1208 }
1209 return
1210 }
1211
1212 var cgo_libc_setuid unsafe.Pointer
1213
1214 func Setuid(uid int) (err error) {
1215 if cgo_libc_setuid == nil {
1216 if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
1217 err = errnoErr(e1)
1218 }
1219 } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
1220 err = errnoErr(Errno(ret))
1221 }
1222 return
1223 }
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 var mapper = &mmapper{
1245 active: make(map[*byte][]byte),
1246 mmap: mmap,
1247 munmap: munmap,
1248 }
1249
1250 func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1251 return mapper.Mmap(fd, offset, length, prot, flags)
1252 }
1253
1254 func Munmap(b []byte) (err error) {
1255 return mapper.Munmap(b)
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
1269 err = prlimit1(pid, resource, newlimit, old)
1270 if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
1271 origRlimitNofile.Store(Rlimit{0, 0})
1272 }
1273 return err
1274 }
1275
View as plain text