blob: e371445acb5a09a854fd2bc84337e1a10a347195 [file] [log] [blame]
khenaidooac637102019-01-14 15:44:34 -05001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Linux system calls.
6// This file is compiled as ordinary Go code,
7// but it is also input to mksyscall,
8// which parses the //sys lines and generates system call stubs.
9// Note that sometimes we use a lowercase //sys name and
10// wrap it in our own nicer implementation.
11
12package unix
13
14import (
15 "encoding/binary"
16 "net"
17 "syscall"
18 "unsafe"
19)
20
21/*
22 * Wrapped
23 */
24
25func Access(path string, mode uint32) (err error) {
26 return Faccessat(AT_FDCWD, path, mode, 0)
27}
28
29func Chmod(path string, mode uint32) (err error) {
30 return Fchmodat(AT_FDCWD, path, mode, 0)
31}
32
33func Chown(path string, uid int, gid int) (err error) {
34 return Fchownat(AT_FDCWD, path, uid, gid, 0)
35}
36
37func Creat(path string, mode uint32) (fd int, err error) {
38 return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
39}
40
41//sys fchmodat(dirfd int, path string, mode uint32) (err error)
42
43func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
44 // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
45 // and check the flags. Otherwise the mode would be applied to the symlink
46 // destination which is not what the user expects.
47 if flags&^AT_SYMLINK_NOFOLLOW != 0 {
48 return EINVAL
49 } else if flags&AT_SYMLINK_NOFOLLOW != 0 {
50 return EOPNOTSUPP
51 }
52 return fchmodat(dirfd, path, mode)
53}
54
55//sys ioctl(fd int, req uint, arg uintptr) (err error)
56
57// ioctl itself should not be exposed directly, but additional get/set
58// functions for specific types are permissible.
59
60// IoctlSetPointerInt performs an ioctl operation which sets an
61// integer value on fd, using the specified request number. The ioctl
62// argument is called with a pointer to the integer value, rather than
63// passing the integer value directly.
64func IoctlSetPointerInt(fd int, req uint, value int) error {
65 v := int32(value)
66 return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
67}
68
69// IoctlSetInt performs an ioctl operation which sets an integer value
70// on fd, using the specified request number.
71func IoctlSetInt(fd int, req uint, value int) error {
72 return ioctl(fd, req, uintptr(value))
73}
74
75func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
76 return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
77}
78
79func ioctlSetTermios(fd int, req uint, value *Termios) error {
80 return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
81}
82
83// IoctlGetInt performs an ioctl operation which gets an integer value
84// from fd, using the specified request number.
85func IoctlGetInt(fd int, req uint) (int, error) {
86 var value int
87 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
88 return value, err
89}
90
91func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
92 var value Winsize
93 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
94 return &value, err
95}
96
97func IoctlGetTermios(fd int, req uint) (*Termios, error) {
98 var value Termios
99 err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
100 return &value, err
101}
102
103//sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
104
105func Link(oldpath string, newpath string) (err error) {
106 return Linkat(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0)
107}
108
109func Mkdir(path string, mode uint32) (err error) {
110 return Mkdirat(AT_FDCWD, path, mode)
111}
112
113func Mknod(path string, mode uint32, dev int) (err error) {
114 return Mknodat(AT_FDCWD, path, mode, dev)
115}
116
117func Open(path string, mode int, perm uint32) (fd int, err error) {
118 return openat(AT_FDCWD, path, mode|O_LARGEFILE, perm)
119}
120
121//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
122
123func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
124 return openat(dirfd, path, flags|O_LARGEFILE, mode)
125}
126
127//sys ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
128
129func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
130 if len(fds) == 0 {
131 return ppoll(nil, 0, timeout, sigmask)
132 }
133 return ppoll(&fds[0], len(fds), timeout, sigmask)
134}
135
136//sys Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
137
138func Readlink(path string, buf []byte) (n int, err error) {
139 return Readlinkat(AT_FDCWD, path, buf)
140}
141
142func Rename(oldpath string, newpath string) (err error) {
143 return Renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath)
144}
145
146func Rmdir(path string) error {
147 return Unlinkat(AT_FDCWD, path, AT_REMOVEDIR)
148}
149
150//sys Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
151
152func Symlink(oldpath string, newpath string) (err error) {
153 return Symlinkat(oldpath, AT_FDCWD, newpath)
154}
155
156func Unlink(path string) error {
157 return Unlinkat(AT_FDCWD, path, 0)
158}
159
160//sys Unlinkat(dirfd int, path string, flags int) (err error)
161
162func Utimes(path string, tv []Timeval) error {
163 if tv == nil {
164 err := utimensat(AT_FDCWD, path, nil, 0)
165 if err != ENOSYS {
166 return err
167 }
168 return utimes(path, nil)
169 }
170 if len(tv) != 2 {
171 return EINVAL
172 }
173 var ts [2]Timespec
174 ts[0] = NsecToTimespec(TimevalToNsec(tv[0]))
175 ts[1] = NsecToTimespec(TimevalToNsec(tv[1]))
176 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
177 if err != ENOSYS {
178 return err
179 }
180 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
181}
182
183//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
184
185func UtimesNano(path string, ts []Timespec) error {
186 if ts == nil {
187 err := utimensat(AT_FDCWD, path, nil, 0)
188 if err != ENOSYS {
189 return err
190 }
191 return utimes(path, nil)
192 }
193 if len(ts) != 2 {
194 return EINVAL
195 }
196 err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
197 if err != ENOSYS {
198 return err
199 }
200 // If the utimensat syscall isn't available (utimensat was added to Linux
201 // in 2.6.22, Released, 8 July 2007) then fall back to utimes
202 var tv [2]Timeval
203 for i := 0; i < 2; i++ {
204 tv[i] = NsecToTimeval(TimespecToNsec(ts[i]))
205 }
206 return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
207}
208
209func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
210 if ts == nil {
211 return utimensat(dirfd, path, nil, flags)
212 }
213 if len(ts) != 2 {
214 return EINVAL
215 }
216 return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags)
217}
218
219func Futimesat(dirfd int, path string, tv []Timeval) error {
220 if tv == nil {
221 return futimesat(dirfd, path, nil)
222 }
223 if len(tv) != 2 {
224 return EINVAL
225 }
226 return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
227}
228
229func Futimes(fd int, tv []Timeval) (err error) {
230 // Believe it or not, this is the best we can do on Linux
231 // (and is what glibc does).
232 return Utimes("/proc/self/fd/"+itoa(fd), tv)
233}
234
235const ImplementsGetwd = true
236
237//sys Getcwd(buf []byte) (n int, err error)
238
239func Getwd() (wd string, err error) {
240 var buf [PathMax]byte
241 n, err := Getcwd(buf[0:])
242 if err != nil {
243 return "", err
244 }
245 // Getcwd returns the number of bytes written to buf, including the NUL.
246 if n < 1 || n > len(buf) || buf[n-1] != 0 {
247 return "", EINVAL
248 }
249 return string(buf[0 : n-1]), nil
250}
251
252func Getgroups() (gids []int, err error) {
253 n, err := getgroups(0, nil)
254 if err != nil {
255 return nil, err
256 }
257 if n == 0 {
258 return nil, nil
259 }
260
261 // Sanity check group count. Max is 1<<16 on Linux.
262 if n < 0 || n > 1<<20 {
263 return nil, EINVAL
264 }
265
266 a := make([]_Gid_t, n)
267 n, err = getgroups(n, &a[0])
268 if err != nil {
269 return nil, err
270 }
271 gids = make([]int, n)
272 for i, v := range a[0:n] {
273 gids[i] = int(v)
274 }
275 return
276}
277
278func Setgroups(gids []int) (err error) {
279 if len(gids) == 0 {
280 return setgroups(0, nil)
281 }
282
283 a := make([]_Gid_t, len(gids))
284 for i, v := range gids {
285 a[i] = _Gid_t(v)
286 }
287 return setgroups(len(a), &a[0])
288}
289
290type WaitStatus uint32
291
292// Wait status is 7 bits at bottom, either 0 (exited),
293// 0x7F (stopped), or a signal number that caused an exit.
294// The 0x80 bit is whether there was a core dump.
295// An extra number (exit code, signal causing a stop)
296// is in the high bits. At least that's the idea.
297// There are various irregularities. For example, the
298// "continued" status is 0xFFFF, distinguishing itself
299// from stopped via the core dump bit.
300
301const (
302 mask = 0x7F
303 core = 0x80
304 exited = 0x00
305 stopped = 0x7F
306 shift = 8
307)
308
309func (w WaitStatus) Exited() bool { return w&mask == exited }
310
311func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
312
313func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
314
315func (w WaitStatus) Continued() bool { return w == 0xFFFF }
316
317func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
318
319func (w WaitStatus) ExitStatus() int {
320 if !w.Exited() {
321 return -1
322 }
323 return int(w>>shift) & 0xFF
324}
325
326func (w WaitStatus) Signal() syscall.Signal {
327 if !w.Signaled() {
328 return -1
329 }
330 return syscall.Signal(w & mask)
331}
332
333func (w WaitStatus) StopSignal() syscall.Signal {
334 if !w.Stopped() {
335 return -1
336 }
337 return syscall.Signal(w>>shift) & 0xFF
338}
339
340func (w WaitStatus) TrapCause() int {
341 if w.StopSignal() != SIGTRAP {
342 return -1
343 }
344 return int(w>>shift) >> 8
345}
346
347//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
348
349func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
350 var status _C_int
351 wpid, err = wait4(pid, &status, options, rusage)
352 if wstatus != nil {
353 *wstatus = WaitStatus(status)
354 }
355 return
356}
357
358func Mkfifo(path string, mode uint32) error {
359 return Mknod(path, mode|S_IFIFO, 0)
360}
361
362func Mkfifoat(dirfd int, path string, mode uint32) error {
363 return Mknodat(dirfd, path, mode|S_IFIFO, 0)
364}
365
366func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
367 if sa.Port < 0 || sa.Port > 0xFFFF {
368 return nil, 0, EINVAL
369 }
370 sa.raw.Family = AF_INET
371 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
372 p[0] = byte(sa.Port >> 8)
373 p[1] = byte(sa.Port)
374 for i := 0; i < len(sa.Addr); i++ {
375 sa.raw.Addr[i] = sa.Addr[i]
376 }
377 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
378}
379
380func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
381 if sa.Port < 0 || sa.Port > 0xFFFF {
382 return nil, 0, EINVAL
383 }
384 sa.raw.Family = AF_INET6
385 p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
386 p[0] = byte(sa.Port >> 8)
387 p[1] = byte(sa.Port)
388 sa.raw.Scope_id = sa.ZoneId
389 for i := 0; i < len(sa.Addr); i++ {
390 sa.raw.Addr[i] = sa.Addr[i]
391 }
392 return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
393}
394
395func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
396 name := sa.Name
397 n := len(name)
398 if n >= len(sa.raw.Path) {
399 return nil, 0, EINVAL
400 }
401 sa.raw.Family = AF_UNIX
402 for i := 0; i < n; i++ {
403 sa.raw.Path[i] = int8(name[i])
404 }
405 // length is family (uint16), name, NUL.
406 sl := _Socklen(2)
407 if n > 0 {
408 sl += _Socklen(n) + 1
409 }
410 if sa.raw.Path[0] == '@' {
411 sa.raw.Path[0] = 0
412 // Don't count trailing NUL for abstract address.
413 sl--
414 }
415
416 return unsafe.Pointer(&sa.raw), sl, nil
417}
418
419// SockaddrLinklayer implements the Sockaddr interface for AF_PACKET type sockets.
420type SockaddrLinklayer struct {
421 Protocol uint16
422 Ifindex int
423 Hatype uint16
424 Pkttype uint8
425 Halen uint8
426 Addr [8]byte
427 raw RawSockaddrLinklayer
428}
429
430func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
431 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
432 return nil, 0, EINVAL
433 }
434 sa.raw.Family = AF_PACKET
435 sa.raw.Protocol = sa.Protocol
436 sa.raw.Ifindex = int32(sa.Ifindex)
437 sa.raw.Hatype = sa.Hatype
438 sa.raw.Pkttype = sa.Pkttype
439 sa.raw.Halen = sa.Halen
440 for i := 0; i < len(sa.Addr); i++ {
441 sa.raw.Addr[i] = sa.Addr[i]
442 }
443 return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
444}
445
446// SockaddrNetlink implements the Sockaddr interface for AF_NETLINK type sockets.
447type SockaddrNetlink struct {
448 Family uint16
449 Pad uint16
450 Pid uint32
451 Groups uint32
452 raw RawSockaddrNetlink
453}
454
455func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
456 sa.raw.Family = AF_NETLINK
457 sa.raw.Pad = sa.Pad
458 sa.raw.Pid = sa.Pid
459 sa.raw.Groups = sa.Groups
460 return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
461}
462
463// SockaddrHCI implements the Sockaddr interface for AF_BLUETOOTH type sockets
464// using the HCI protocol.
465type SockaddrHCI struct {
466 Dev uint16
467 Channel uint16
468 raw RawSockaddrHCI
469}
470
471func (sa *SockaddrHCI) sockaddr() (unsafe.Pointer, _Socklen, error) {
472 sa.raw.Family = AF_BLUETOOTH
473 sa.raw.Dev = sa.Dev
474 sa.raw.Channel = sa.Channel
475 return unsafe.Pointer(&sa.raw), SizeofSockaddrHCI, nil
476}
477
478// SockaddrL2 implements the Sockaddr interface for AF_BLUETOOTH type sockets
479// using the L2CAP protocol.
480type SockaddrL2 struct {
481 PSM uint16
482 CID uint16
483 Addr [6]uint8
484 AddrType uint8
485 raw RawSockaddrL2
486}
487
488func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
489 sa.raw.Family = AF_BLUETOOTH
490 psm := (*[2]byte)(unsafe.Pointer(&sa.raw.Psm))
491 psm[0] = byte(sa.PSM)
492 psm[1] = byte(sa.PSM >> 8)
493 for i := 0; i < len(sa.Addr); i++ {
494 sa.raw.Bdaddr[i] = sa.Addr[len(sa.Addr)-1-i]
495 }
496 cid := (*[2]byte)(unsafe.Pointer(&sa.raw.Cid))
497 cid[0] = byte(sa.CID)
498 cid[1] = byte(sa.CID >> 8)
499 sa.raw.Bdaddr_type = sa.AddrType
500 return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
501}
502
503// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets
504// using the RFCOMM protocol.
505//
506// Server example:
507//
508// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
509// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{
510// Channel: 1,
511// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00
512// })
513// _ = Listen(fd, 1)
514// nfd, sa, _ := Accept(fd)
515// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd)
516// Read(nfd, buf)
517//
518// Client example:
519//
520// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
521// _ = Connect(fd, &SockaddrRFCOMM{
522// Channel: 1,
523// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11
524// })
525// Write(fd, []byte(`hello`))
526type SockaddrRFCOMM struct {
527 // Addr represents a bluetooth address, byte ordering is little-endian.
528 Addr [6]uint8
529
530 // Channel is a designated bluetooth channel, only 1-30 are available for use.
531 // Since Linux 2.6.7 and further zero value is the first available channel.
532 Channel uint8
533
534 raw RawSockaddrRFCOMM
535}
536
537func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
538 sa.raw.Family = AF_BLUETOOTH
539 sa.raw.Channel = sa.Channel
540 sa.raw.Bdaddr = sa.Addr
541 return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
542}
543
544// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
545// The RxID and TxID fields are used for transport protocol addressing in
546// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
547// zero values for CAN_RAW and CAN_BCM sockets as they have no meaning.
548//
549// The SockaddrCAN struct must be bound to the socket file descriptor
550// using Bind before the CAN socket can be used.
551//
552// // Read one raw CAN frame
553// fd, _ := Socket(AF_CAN, SOCK_RAW, CAN_RAW)
554// addr := &SockaddrCAN{Ifindex: index}
555// Bind(fd, addr)
556// frame := make([]byte, 16)
557// Read(fd, frame)
558//
559// The full SocketCAN documentation can be found in the linux kernel
560// archives at: https://www.kernel.org/doc/Documentation/networking/can.txt
561type SockaddrCAN struct {
562 Ifindex int
563 RxID uint32
564 TxID uint32
565 raw RawSockaddrCAN
566}
567
568func (sa *SockaddrCAN) sockaddr() (unsafe.Pointer, _Socklen, error) {
569 if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
570 return nil, 0, EINVAL
571 }
572 sa.raw.Family = AF_CAN
573 sa.raw.Ifindex = int32(sa.Ifindex)
574 rx := (*[4]byte)(unsafe.Pointer(&sa.RxID))
575 for i := 0; i < 4; i++ {
576 sa.raw.Addr[i] = rx[i]
577 }
578 tx := (*[4]byte)(unsafe.Pointer(&sa.TxID))
579 for i := 0; i < 4; i++ {
580 sa.raw.Addr[i+4] = tx[i]
581 }
582 return unsafe.Pointer(&sa.raw), SizeofSockaddrCAN, nil
583}
584
585// SockaddrALG implements the Sockaddr interface for AF_ALG type sockets.
586// SockaddrALG enables userspace access to the Linux kernel's cryptography
587// subsystem. The Type and Name fields specify which type of hash or cipher
588// should be used with a given socket.
589//
590// To create a file descriptor that provides access to a hash or cipher, both
591// Bind and Accept must be used. Once the setup process is complete, input
592// data can be written to the socket, processed by the kernel, and then read
593// back as hash output or ciphertext.
594//
595// Here is an example of using an AF_ALG socket with SHA1 hashing.
596// The initial socket setup process is as follows:
597//
598// // Open a socket to perform SHA1 hashing.
599// fd, _ := unix.Socket(unix.AF_ALG, unix.SOCK_SEQPACKET, 0)
600// addr := &unix.SockaddrALG{Type: "hash", Name: "sha1"}
601// unix.Bind(fd, addr)
602// // Note: unix.Accept does not work at this time; must invoke accept()
603// // manually using unix.Syscall.
604// hashfd, _, _ := unix.Syscall(unix.SYS_ACCEPT, uintptr(fd), 0, 0)
605//
606// Once a file descriptor has been returned from Accept, it may be used to
607// perform SHA1 hashing. The descriptor is not safe for concurrent use, but
608// may be re-used repeatedly with subsequent Write and Read operations.
609//
610// When hashing a small byte slice or string, a single Write and Read may
611// be used:
612//
613// // Assume hashfd is already configured using the setup process.
614// hash := os.NewFile(hashfd, "sha1")
615// // Hash an input string and read the results. Each Write discards
616// // previous hash state. Read always reads the current state.
617// b := make([]byte, 20)
618// for i := 0; i < 2; i++ {
619// io.WriteString(hash, "Hello, world.")
620// hash.Read(b)
621// fmt.Println(hex.EncodeToString(b))
622// }
623// // Output:
624// // 2ae01472317d1935a84797ec1983ae243fc6aa28
625// // 2ae01472317d1935a84797ec1983ae243fc6aa28
626//
627// For hashing larger byte slices, or byte streams such as those read from
628// a file or socket, use Sendto with MSG_MORE to instruct the kernel to update
629// the hash digest instead of creating a new one for a given chunk and finalizing it.
630//
631// // Assume hashfd and addr are already configured using the setup process.
632// hash := os.NewFile(hashfd, "sha1")
633// // Hash the contents of a file.
634// f, _ := os.Open("/tmp/linux-4.10-rc7.tar.xz")
635// b := make([]byte, 4096)
636// for {
637// n, err := f.Read(b)
638// if err == io.EOF {
639// break
640// }
641// unix.Sendto(hashfd, b[:n], unix.MSG_MORE, addr)
642// }
643// hash.Read(b)
644// fmt.Println(hex.EncodeToString(b))
645// // Output: 85cdcad0c06eef66f805ecce353bec9accbeecc5
646//
647// For more information, see: http://www.chronox.de/crypto-API/crypto/userspace-if.html.
648type SockaddrALG struct {
649 Type string
650 Name string
651 Feature uint32
652 Mask uint32
653 raw RawSockaddrALG
654}
655
656func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) {
657 // Leave room for NUL byte terminator.
658 if len(sa.Type) > 13 {
659 return nil, 0, EINVAL
660 }
661 if len(sa.Name) > 63 {
662 return nil, 0, EINVAL
663 }
664
665 sa.raw.Family = AF_ALG
666 sa.raw.Feat = sa.Feature
667 sa.raw.Mask = sa.Mask
668
669 typ, err := ByteSliceFromString(sa.Type)
670 if err != nil {
671 return nil, 0, err
672 }
673 name, err := ByteSliceFromString(sa.Name)
674 if err != nil {
675 return nil, 0, err
676 }
677
678 copy(sa.raw.Type[:], typ)
679 copy(sa.raw.Name[:], name)
680
681 return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil
682}
683
684// SockaddrVM implements the Sockaddr interface for AF_VSOCK type sockets.
685// SockaddrVM provides access to Linux VM sockets: a mechanism that enables
686// bidirectional communication between a hypervisor and its guest virtual
687// machines.
688type SockaddrVM struct {
689 // CID and Port specify a context ID and port address for a VM socket.
690 // Guests have a unique CID, and hosts may have a well-known CID of:
691 // - VMADDR_CID_HYPERVISOR: refers to the hypervisor process.
692 // - VMADDR_CID_HOST: refers to other processes on the host.
693 CID uint32
694 Port uint32
695 raw RawSockaddrVM
696}
697
698func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
699 sa.raw.Family = AF_VSOCK
700 sa.raw.Port = sa.Port
701 sa.raw.Cid = sa.CID
702
703 return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
704}
705
706type SockaddrXDP struct {
707 Flags uint16
708 Ifindex uint32
709 QueueID uint32
710 SharedUmemFD uint32
711 raw RawSockaddrXDP
712}
713
714func (sa *SockaddrXDP) sockaddr() (unsafe.Pointer, _Socklen, error) {
715 sa.raw.Family = AF_XDP
716 sa.raw.Flags = sa.Flags
717 sa.raw.Ifindex = sa.Ifindex
718 sa.raw.Queue_id = sa.QueueID
719 sa.raw.Shared_umem_fd = sa.SharedUmemFD
720
721 return unsafe.Pointer(&sa.raw), SizeofSockaddrXDP, nil
722}
723
724// This constant mirrors the #define of PX_PROTO_OE in
725// linux/if_pppox.h. We're defining this by hand here instead of
726// autogenerating through mkerrors.sh because including
727// linux/if_pppox.h causes some declaration conflicts with other
728// includes (linux/if_pppox.h includes linux/in.h, which conflicts
729// with netinet/in.h). Given that we only need a single zero constant
730// out of that file, it's cleaner to just define it by hand here.
731const px_proto_oe = 0
732
733type SockaddrPPPoE struct {
734 SID uint16
735 Remote net.HardwareAddr
736 Dev string
737 raw RawSockaddrPPPoX
738}
739
740func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
741 if len(sa.Remote) != 6 {
742 return nil, 0, EINVAL
743 }
744 if len(sa.Dev) > IFNAMSIZ-1 {
745 return nil, 0, EINVAL
746 }
747
748 *(*uint16)(unsafe.Pointer(&sa.raw[0])) = AF_PPPOX
749 // This next field is in host-endian byte order. We can't use the
750 // same unsafe pointer cast as above, because this value is not
751 // 32-bit aligned and some architectures don't allow unaligned
752 // access.
753 //
754 // However, the value of px_proto_oe is 0, so we can use
755 // encoding/binary helpers to write the bytes without worrying
756 // about the ordering.
757 binary.BigEndian.PutUint32(sa.raw[2:6], px_proto_oe)
758 // This field is deliberately big-endian, unlike the previous
759 // one. The kernel expects SID to be in network byte order.
760 binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
761 copy(sa.raw[8:14], sa.Remote)
762 for i := 14; i < 14+IFNAMSIZ; i++ {
763 sa.raw[i] = 0
764 }
765 copy(sa.raw[14:], sa.Dev)
766 return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
767}
768
769func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
770 switch rsa.Addr.Family {
771 case AF_NETLINK:
772 pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
773 sa := new(SockaddrNetlink)
774 sa.Family = pp.Family
775 sa.Pad = pp.Pad
776 sa.Pid = pp.Pid
777 sa.Groups = pp.Groups
778 return sa, nil
779
780 case AF_PACKET:
781 pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
782 sa := new(SockaddrLinklayer)
783 sa.Protocol = pp.Protocol
784 sa.Ifindex = int(pp.Ifindex)
785 sa.Hatype = pp.Hatype
786 sa.Pkttype = pp.Pkttype
787 sa.Halen = pp.Halen
788 for i := 0; i < len(sa.Addr); i++ {
789 sa.Addr[i] = pp.Addr[i]
790 }
791 return sa, nil
792
793 case AF_UNIX:
794 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
795 sa := new(SockaddrUnix)
796 if pp.Path[0] == 0 {
797 // "Abstract" Unix domain socket.
798 // Rewrite leading NUL as @ for textual display.
799 // (This is the standard convention.)
800 // Not friendly to overwrite in place,
801 // but the callers below don't care.
802 pp.Path[0] = '@'
803 }
804
805 // Assume path ends at NUL.
806 // This is not technically the Linux semantics for
807 // abstract Unix domain sockets--they are supposed
808 // to be uninterpreted fixed-size binary blobs--but
809 // everyone uses this convention.
810 n := 0
811 for n < len(pp.Path) && pp.Path[n] != 0 {
812 n++
813 }
814 bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
815 sa.Name = string(bytes)
816 return sa, nil
817
818 case AF_INET:
819 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
820 sa := new(SockaddrInet4)
821 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
822 sa.Port = int(p[0])<<8 + int(p[1])
823 for i := 0; i < len(sa.Addr); i++ {
824 sa.Addr[i] = pp.Addr[i]
825 }
826 return sa, nil
827
828 case AF_INET6:
829 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
830 sa := new(SockaddrInet6)
831 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
832 sa.Port = int(p[0])<<8 + int(p[1])
833 sa.ZoneId = pp.Scope_id
834 for i := 0; i < len(sa.Addr); i++ {
835 sa.Addr[i] = pp.Addr[i]
836 }
837 return sa, nil
838
839 case AF_VSOCK:
840 pp := (*RawSockaddrVM)(unsafe.Pointer(rsa))
841 sa := &SockaddrVM{
842 CID: pp.Cid,
843 Port: pp.Port,
844 }
845 return sa, nil
846 case AF_BLUETOOTH:
847 proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
848 if err != nil {
849 return nil, err
850 }
851 // only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections
852 switch proto {
853 case BTPROTO_L2CAP:
854 pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
855 sa := &SockaddrL2{
856 PSM: pp.Psm,
857 CID: pp.Cid,
858 Addr: pp.Bdaddr,
859 AddrType: pp.Bdaddr_type,
860 }
861 return sa, nil
862 case BTPROTO_RFCOMM:
863 pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
864 sa := &SockaddrRFCOMM{
865 Channel: pp.Channel,
866 Addr: pp.Bdaddr,
867 }
868 return sa, nil
869 }
870 case AF_XDP:
871 pp := (*RawSockaddrXDP)(unsafe.Pointer(rsa))
872 sa := &SockaddrXDP{
873 Flags: pp.Flags,
874 Ifindex: pp.Ifindex,
875 QueueID: pp.Queue_id,
876 SharedUmemFD: pp.Shared_umem_fd,
877 }
878 return sa, nil
879 case AF_PPPOX:
880 pp := (*RawSockaddrPPPoX)(unsafe.Pointer(rsa))
881 if binary.BigEndian.Uint32(pp[2:6]) != px_proto_oe {
882 return nil, EINVAL
883 }
884 sa := &SockaddrPPPoE{
885 SID: binary.BigEndian.Uint16(pp[6:8]),
886 Remote: net.HardwareAddr(pp[8:14]),
887 }
888 for i := 14; i < 14+IFNAMSIZ; i++ {
889 if pp[i] == 0 {
890 sa.Dev = string(pp[14:i])
891 break
892 }
893 }
894 return sa, nil
895 }
896 return nil, EAFNOSUPPORT
897}
898
899func Accept(fd int) (nfd int, sa Sockaddr, err error) {
900 var rsa RawSockaddrAny
901 var len _Socklen = SizeofSockaddrAny
902 nfd, err = accept(fd, &rsa, &len)
903 if err != nil {
904 return
905 }
906 sa, err = anyToSockaddr(fd, &rsa)
907 if err != nil {
908 Close(nfd)
909 nfd = 0
910 }
911 return
912}
913
914func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
915 var rsa RawSockaddrAny
916 var len _Socklen = SizeofSockaddrAny
917 nfd, err = accept4(fd, &rsa, &len, flags)
918 if err != nil {
919 return
920 }
921 if len > SizeofSockaddrAny {
922 panic("RawSockaddrAny too small")
923 }
924 sa, err = anyToSockaddr(fd, &rsa)
925 if err != nil {
926 Close(nfd)
927 nfd = 0
928 }
929 return
930}
931
932func Getsockname(fd int) (sa Sockaddr, err error) {
933 var rsa RawSockaddrAny
934 var len _Socklen = SizeofSockaddrAny
935 if err = getsockname(fd, &rsa, &len); err != nil {
936 return
937 }
938 return anyToSockaddr(fd, &rsa)
939}
940
941func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
942 var value IPMreqn
943 vallen := _Socklen(SizeofIPMreqn)
944 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
945 return &value, err
946}
947
948func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
949 var value Ucred
950 vallen := _Socklen(SizeofUcred)
951 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
952 return &value, err
953}
954
955func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) {
956 var value TCPInfo
957 vallen := _Socklen(SizeofTCPInfo)
958 err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
959 return &value, err
960}
961
962// GetsockoptString returns the string value of the socket option opt for the
963// socket associated with fd at the given socket level.
964func GetsockoptString(fd, level, opt int) (string, error) {
965 buf := make([]byte, 256)
966 vallen := _Socklen(len(buf))
967 err := getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
968 if err != nil {
969 if err == ERANGE {
970 buf = make([]byte, vallen)
971 err = getsockopt(fd, level, opt, unsafe.Pointer(&buf[0]), &vallen)
972 }
973 if err != nil {
974 return "", err
975 }
976 }
977 return string(buf[:vallen-1]), nil
978}
979
980func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
981 return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
982}
983
984// Keyctl Commands (http://man7.org/linux/man-pages/man2/keyctl.2.html)
985
986// KeyctlInt calls keyctl commands in which each argument is an int.
987// These commands are KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_CLEAR, KEYCTL_LINK,
988// KEYCTL_UNLINK, KEYCTL_NEGATE, KEYCTL_SET_REQKEY_KEYRING, KEYCTL_SET_TIMEOUT,
989// KEYCTL_ASSUME_AUTHORITY, KEYCTL_SESSION_TO_PARENT, KEYCTL_REJECT,
990// KEYCTL_INVALIDATE, and KEYCTL_GET_PERSISTENT.
991//sys KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) = SYS_KEYCTL
992
993// KeyctlBuffer calls keyctl commands in which the third and fourth
994// arguments are a buffer and its length, respectively.
995// These commands are KEYCTL_UPDATE, KEYCTL_READ, and KEYCTL_INSTANTIATE.
996//sys KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) = SYS_KEYCTL
997
998// KeyctlString calls keyctl commands which return a string.
999// These commands are KEYCTL_DESCRIBE and KEYCTL_GET_SECURITY.
1000func KeyctlString(cmd int, id int) (string, error) {
1001 // We must loop as the string data may change in between the syscalls.
1002 // We could allocate a large buffer here to reduce the chance that the
1003 // syscall needs to be called twice; however, this is unnecessary as
1004 // the performance loss is negligible.
1005 var buffer []byte
1006 for {
1007 // Try to fill the buffer with data
1008 length, err := KeyctlBuffer(cmd, id, buffer, 0)
1009 if err != nil {
1010 return "", err
1011 }
1012
1013 // Check if the data was written
1014 if length <= len(buffer) {
1015 // Exclude the null terminator
1016 return string(buffer[:length-1]), nil
1017 }
1018
1019 // Make a bigger buffer if needed
1020 buffer = make([]byte, length)
1021 }
1022}
1023
1024// Keyctl commands with special signatures.
1025
1026// KeyctlGetKeyringID implements the KEYCTL_GET_KEYRING_ID command.
1027// See the full documentation at:
1028// http://man7.org/linux/man-pages/man3/keyctl_get_keyring_ID.3.html
1029func KeyctlGetKeyringID(id int, create bool) (ringid int, err error) {
1030 createInt := 0
1031 if create {
1032 createInt = 1
1033 }
1034 return KeyctlInt(KEYCTL_GET_KEYRING_ID, id, createInt, 0, 0)
1035}
1036
1037// KeyctlSetperm implements the KEYCTL_SETPERM command. The perm value is the
1038// key handle permission mask as described in the "keyctl setperm" section of
1039// http://man7.org/linux/man-pages/man1/keyctl.1.html.
1040// See the full documentation at:
1041// http://man7.org/linux/man-pages/man3/keyctl_setperm.3.html
1042func KeyctlSetperm(id int, perm uint32) error {
1043 _, err := KeyctlInt(KEYCTL_SETPERM, id, int(perm), 0, 0)
1044 return err
1045}
1046
1047//sys keyctlJoin(cmd int, arg2 string) (ret int, err error) = SYS_KEYCTL
1048
1049// KeyctlJoinSessionKeyring implements the KEYCTL_JOIN_SESSION_KEYRING command.
1050// See the full documentation at:
1051// http://man7.org/linux/man-pages/man3/keyctl_join_session_keyring.3.html
1052func KeyctlJoinSessionKeyring(name string) (ringid int, err error) {
1053 return keyctlJoin(KEYCTL_JOIN_SESSION_KEYRING, name)
1054}
1055
1056//sys keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) = SYS_KEYCTL
1057
1058// KeyctlSearch implements the KEYCTL_SEARCH command.
1059// See the full documentation at:
1060// http://man7.org/linux/man-pages/man3/keyctl_search.3.html
1061func KeyctlSearch(ringid int, keyType, description string, destRingid int) (id int, err error) {
1062 return keyctlSearch(KEYCTL_SEARCH, ringid, keyType, description, destRingid)
1063}
1064
1065//sys keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) = SYS_KEYCTL
1066
1067// KeyctlInstantiateIOV implements the KEYCTL_INSTANTIATE_IOV command. This
1068// command is similar to KEYCTL_INSTANTIATE, except that the payload is a slice
1069// of Iovec (each of which represents a buffer) instead of a single buffer.
1070// See the full documentation at:
1071// http://man7.org/linux/man-pages/man3/keyctl_instantiate_iov.3.html
1072func KeyctlInstantiateIOV(id int, payload []Iovec, ringid int) error {
1073 return keyctlIOV(KEYCTL_INSTANTIATE_IOV, id, payload, ringid)
1074}
1075
1076//sys keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) = SYS_KEYCTL
1077
1078// KeyctlDHCompute implements the KEYCTL_DH_COMPUTE command. This command
1079// computes a Diffie-Hellman shared secret based on the provide params. The
1080// secret is written to the provided buffer and the returned size is the number
1081// of bytes written (returning an error if there is insufficient space in the
1082// buffer). If a nil buffer is passed in, this function returns the minimum
1083// buffer length needed to store the appropriate data. Note that this differs
1084// from KEYCTL_READ's behavior which always returns the requested payload size.
1085// See the full documentation at:
1086// http://man7.org/linux/man-pages/man3/keyctl_dh_compute.3.html
1087func KeyctlDHCompute(params *KeyctlDHParams, buffer []byte) (size int, err error) {
1088 return keyctlDH(KEYCTL_DH_COMPUTE, params, buffer)
1089}
1090
1091func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
1092 var msg Msghdr
1093 var rsa RawSockaddrAny
1094 msg.Name = (*byte)(unsafe.Pointer(&rsa))
1095 msg.Namelen = uint32(SizeofSockaddrAny)
1096 var iov Iovec
1097 if len(p) > 0 {
1098 iov.Base = &p[0]
1099 iov.SetLen(len(p))
1100 }
1101 var dummy byte
1102 if len(oob) > 0 {
1103 if len(p) == 0 {
1104 var sockType int
1105 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1106 if err != nil {
1107 return
1108 }
1109 // receive at least one normal byte
1110 if sockType != SOCK_DGRAM {
1111 iov.Base = &dummy
1112 iov.SetLen(1)
1113 }
1114 }
1115 msg.Control = &oob[0]
1116 msg.SetControllen(len(oob))
1117 }
1118 msg.Iov = &iov
1119 msg.Iovlen = 1
1120 if n, err = recvmsg(fd, &msg, flags); err != nil {
1121 return
1122 }
1123 oobn = int(msg.Controllen)
1124 recvflags = int(msg.Flags)
1125 // source address is only specified if the socket is unconnected
1126 if rsa.Addr.Family != AF_UNSPEC {
1127 from, err = anyToSockaddr(fd, &rsa)
1128 }
1129 return
1130}
1131
1132func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
1133 _, err = SendmsgN(fd, p, oob, to, flags)
1134 return
1135}
1136
1137func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
1138 var ptr unsafe.Pointer
1139 var salen _Socklen
1140 if to != nil {
1141 var err error
1142 ptr, salen, err = to.sockaddr()
1143 if err != nil {
1144 return 0, err
1145 }
1146 }
1147 var msg Msghdr
1148 msg.Name = (*byte)(ptr)
1149 msg.Namelen = uint32(salen)
1150 var iov Iovec
1151 if len(p) > 0 {
1152 iov.Base = &p[0]
1153 iov.SetLen(len(p))
1154 }
1155 var dummy byte
1156 if len(oob) > 0 {
1157 if len(p) == 0 {
1158 var sockType int
1159 sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
1160 if err != nil {
1161 return 0, err
1162 }
1163 // send at least one normal byte
1164 if sockType != SOCK_DGRAM {
1165 iov.Base = &dummy
1166 iov.SetLen(1)
1167 }
1168 }
1169 msg.Control = &oob[0]
1170 msg.SetControllen(len(oob))
1171 }
1172 msg.Iov = &iov
1173 msg.Iovlen = 1
1174 if n, err = sendmsg(fd, &msg, flags); err != nil {
1175 return 0, err
1176 }
1177 if len(oob) > 0 && len(p) == 0 {
1178 n = 0
1179 }
1180 return n, nil
1181}
1182
1183// BindToDevice binds the socket associated with fd to device.
1184func BindToDevice(fd int, device string) (err error) {
1185 return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
1186}
1187
1188//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
1189
1190func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
1191 // The peek requests are machine-size oriented, so we wrap it
1192 // to retrieve arbitrary-length data.
1193
1194 // The ptrace syscall differs from glibc's ptrace.
1195 // Peeks returns the word in *data, not as the return value.
1196
1197 var buf [SizeofPtr]byte
1198
1199 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
1200 // access (PEEKUSER warns that it might), but if we don't
1201 // align our reads, we might straddle an unmapped page
1202 // boundary and not get the bytes leading up to the page
1203 // boundary.
1204 n := 0
1205 if addr%SizeofPtr != 0 {
1206 err = ptrace(req, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
1207 if err != nil {
1208 return 0, err
1209 }
1210 n += copy(out, buf[addr%SizeofPtr:])
1211 out = out[n:]
1212 }
1213
1214 // Remainder.
1215 for len(out) > 0 {
1216 // We use an internal buffer to guarantee alignment.
1217 // It's not documented if this is necessary, but we're paranoid.
1218 err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
1219 if err != nil {
1220 return n, err
1221 }
1222 copied := copy(out, buf[0:])
1223 n += copied
1224 out = out[copied:]
1225 }
1226
1227 return n, nil
1228}
1229
1230func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
1231 return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
1232}
1233
1234func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
1235 return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
1236}
1237
1238func PtracePeekUser(pid int, addr uintptr, out []byte) (count int, err error) {
1239 return ptracePeek(PTRACE_PEEKUSR, pid, addr, out)
1240}
1241
1242func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
1243 // As for ptracePeek, we need to align our accesses to deal
1244 // with the possibility of straddling an invalid page.
1245
1246 // Leading edge.
1247 n := 0
1248 if addr%SizeofPtr != 0 {
1249 var buf [SizeofPtr]byte
1250 err = ptrace(peekReq, pid, addr-addr%SizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
1251 if err != nil {
1252 return 0, err
1253 }
1254 n += copy(buf[addr%SizeofPtr:], data)
1255 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1256 err = ptrace(pokeReq, pid, addr-addr%SizeofPtr, word)
1257 if err != nil {
1258 return 0, err
1259 }
1260 data = data[n:]
1261 }
1262
1263 // Interior.
1264 for len(data) > SizeofPtr {
1265 word := *((*uintptr)(unsafe.Pointer(&data[0])))
1266 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1267 if err != nil {
1268 return n, err
1269 }
1270 n += SizeofPtr
1271 data = data[SizeofPtr:]
1272 }
1273
1274 // Trailing edge.
1275 if len(data) > 0 {
1276 var buf [SizeofPtr]byte
1277 err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
1278 if err != nil {
1279 return n, err
1280 }
1281 copy(buf[0:], data)
1282 word := *((*uintptr)(unsafe.Pointer(&buf[0])))
1283 err = ptrace(pokeReq, pid, addr+uintptr(n), word)
1284 if err != nil {
1285 return n, err
1286 }
1287 n += len(data)
1288 }
1289
1290 return n, nil
1291}
1292
1293func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
1294 return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
1295}
1296
1297func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
1298 return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
1299}
1300
1301func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
1302 return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
1303}
1304
1305func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
1306 return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
1307}
1308
1309func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
1310 return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
1311}
1312
1313func PtraceSetOptions(pid int, options int) (err error) {
1314 return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
1315}
1316
1317func PtraceGetEventMsg(pid int) (msg uint, err error) {
1318 var data _C_long
1319 err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
1320 msg = uint(data)
1321 return
1322}
1323
1324func PtraceCont(pid int, signal int) (err error) {
1325 return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
1326}
1327
1328func PtraceSyscall(pid int, signal int) (err error) {
1329 return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
1330}
1331
1332func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
1333
1334func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
1335
1336func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
1337
1338//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
1339
1340func Reboot(cmd int) (err error) {
1341 return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
1342}
1343
1344func ReadDirent(fd int, buf []byte) (n int, err error) {
1345 return Getdents(fd, buf)
1346}
1347
1348//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
1349
1350func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
1351 // Certain file systems get rather angry and EINVAL if you give
1352 // them an empty string of data, rather than NULL.
1353 if data == "" {
1354 return mount(source, target, fstype, flags, nil)
1355 }
1356 datap, err := BytePtrFromString(data)
1357 if err != nil {
1358 return err
1359 }
1360 return mount(source, target, fstype, flags, datap)
1361}
1362
1363func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
1364 if raceenabled {
1365 raceReleaseMerge(unsafe.Pointer(&ioSync))
1366 }
1367 return sendfile(outfd, infd, offset, count)
1368}
1369
1370// Sendto
1371// Recvfrom
1372// Socketpair
1373
1374/*
1375 * Direct access
1376 */
1377//sys Acct(path string) (err error)
1378//sys AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
1379//sys Adjtimex(buf *Timex) (state int, err error)
1380//sys Chdir(path string) (err error)
1381//sys Chroot(path string) (err error)
1382//sys ClockGetres(clockid int32, res *Timespec) (err error)
1383//sys ClockGettime(clockid int32, time *Timespec) (err error)
1384//sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error)
1385//sys Close(fd int) (err error)
1386//sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
1387//sys DeleteModule(name string, flags int) (err error)
1388//sys Dup(oldfd int) (fd int, err error)
1389//sys Dup3(oldfd int, newfd int, flags int) (err error)
1390//sysnb EpollCreate1(flag int) (fd int, err error)
1391//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
1392//sys Eventfd(initval uint, flags int) (fd int, err error) = SYS_EVENTFD2
1393//sys Exit(code int) = SYS_EXIT_GROUP
1394//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
1395//sys Fchdir(fd int) (err error)
1396//sys Fchmod(fd int, mode uint32) (err error)
1397//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
1398//sys fcntl(fd int, cmd int, arg int) (val int, err error)
1399//sys Fdatasync(fd int) (err error)
1400//sys Fgetxattr(fd int, attr string, dest []byte) (sz int, err error)
1401//sys FinitModule(fd int, params string, flags int) (err error)
1402//sys Flistxattr(fd int, dest []byte) (sz int, err error)
1403//sys Flock(fd int, how int) (err error)
1404//sys Fremovexattr(fd int, attr string) (err error)
1405//sys Fsetxattr(fd int, attr string, dest []byte, flags int) (err error)
1406//sys Fsync(fd int) (err error)
1407//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
1408//sysnb Getpgid(pid int) (pgid int, err error)
1409
1410func Getpgrp() (pid int) {
1411 pid, _ = Getpgid(0)
1412 return
1413}
1414
1415//sysnb Getpid() (pid int)
1416//sysnb Getppid() (ppid int)
1417//sys Getpriority(which int, who int) (prio int, err error)
1418//sys Getrandom(buf []byte, flags int) (n int, err error)
1419//sysnb Getrusage(who int, rusage *Rusage) (err error)
1420//sysnb Getsid(pid int) (sid int, err error)
1421//sysnb Gettid() (tid int)
1422//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
1423//sys InitModule(moduleImage []byte, params string) (err error)
1424//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
1425//sysnb InotifyInit1(flags int) (fd int, err error)
1426//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
1427//sysnb Kill(pid int, sig syscall.Signal) (err error)
1428//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
1429//sys Lgetxattr(path string, attr string, dest []byte) (sz int, err error)
1430//sys Listxattr(path string, dest []byte) (sz int, err error)
1431//sys Llistxattr(path string, dest []byte) (sz int, err error)
1432//sys Lremovexattr(path string, attr string) (err error)
1433//sys Lsetxattr(path string, attr string, data []byte, flags int) (err error)
1434//sys MemfdCreate(name string, flags int) (fd int, err error)
1435//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
1436//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
1437//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
1438//sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
1439//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
1440//sysnb prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
1441//sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
1442//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
1443//sys read(fd int, p []byte) (n int, err error)
1444//sys Removexattr(path string, attr string) (err error)
1445//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
1446//sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
1447//sys RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error)
1448//sys Setdomainname(p []byte) (err error)
1449//sys Sethostname(p []byte) (err error)
1450//sysnb Setpgid(pid int, pgid int) (err error)
1451//sysnb Setsid() (pid int, err error)
1452//sysnb Settimeofday(tv *Timeval) (err error)
1453//sys Setns(fd int, nstype int) (err error)
1454
1455// issue 1435.
1456// On linux Setuid and Setgid only affects the current thread, not the process.
1457// This does not match what most callers expect so we must return an error
1458// here rather than letting the caller think that the call succeeded.
1459
1460func Setuid(uid int) (err error) {
1461 return EOPNOTSUPP
1462}
1463
1464func Setgid(uid int) (err error) {
1465 return EOPNOTSUPP
1466}
1467
1468//sys Setpriority(which int, who int, prio int) (err error)
1469//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
1470//sys Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
1471//sys Sync()
1472//sys Syncfs(fd int) (err error)
1473//sysnb Sysinfo(info *Sysinfo_t) (err error)
1474//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
1475//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
1476//sysnb Times(tms *Tms) (ticks uintptr, err error)
1477//sysnb Umask(mask int) (oldmask int)
1478//sysnb Uname(buf *Utsname) (err error)
1479//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
1480//sys Unshare(flags int) (err error)
1481//sys write(fd int, p []byte) (n int, err error)
1482//sys exitThread(code int) (err error) = SYS_EXIT
1483//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
1484//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
1485
1486// mmap varies by architecture; see syscall_linux_*.go.
1487//sys munmap(addr uintptr, length uintptr) (err error)
1488
1489var mapper = &mmapper{
1490 active: make(map[*byte][]byte),
1491 mmap: mmap,
1492 munmap: munmap,
1493}
1494
1495func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
1496 return mapper.Mmap(fd, offset, length, prot, flags)
1497}
1498
1499func Munmap(b []byte) (err error) {
1500 return mapper.Munmap(b)
1501}
1502
1503//sys Madvise(b []byte, advice int) (err error)
1504//sys Mprotect(b []byte, prot int) (err error)
1505//sys Mlock(b []byte) (err error)
1506//sys Mlockall(flags int) (err error)
1507//sys Msync(b []byte, flags int) (err error)
1508//sys Munlock(b []byte) (err error)
1509//sys Munlockall() (err error)
1510
1511// Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
1512// using the specified flags.
1513func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
1514 var p unsafe.Pointer
1515 if len(iovs) > 0 {
1516 p = unsafe.Pointer(&iovs[0])
1517 }
1518
1519 n, _, errno := Syscall6(SYS_VMSPLICE, uintptr(fd), uintptr(p), uintptr(len(iovs)), uintptr(flags), 0, 0)
1520 if errno != 0 {
1521 return 0, syscall.Errno(errno)
1522 }
1523
1524 return int(n), nil
1525}
1526
1527//sys faccessat(dirfd int, path string, mode uint32) (err error)
1528
1529func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
1530 if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 {
1531 return EINVAL
1532 }
1533
1534 // The Linux kernel faccessat system call does not take any flags.
1535 // The glibc faccessat implements the flags itself; see
1536 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
1537 // Because people naturally expect syscall.Faccessat to act
1538 // like C faccessat, we do the same.
1539
1540 if flags == 0 {
1541 return faccessat(dirfd, path, mode)
1542 }
1543
1544 var st Stat_t
1545 if err := Fstatat(dirfd, path, &st, flags&AT_SYMLINK_NOFOLLOW); err != nil {
1546 return err
1547 }
1548
1549 mode &= 7
1550 if mode == 0 {
1551 return nil
1552 }
1553
1554 var uid int
1555 if flags&AT_EACCESS != 0 {
1556 uid = Geteuid()
1557 } else {
1558 uid = Getuid()
1559 }
1560
1561 if uid == 0 {
1562 if mode&1 == 0 {
1563 // Root can read and write any file.
1564 return nil
1565 }
1566 if st.Mode&0111 != 0 {
1567 // Root can execute any file that anybody can execute.
1568 return nil
1569 }
1570 return EACCES
1571 }
1572
1573 var fmode uint32
1574 if uint32(uid) == st.Uid {
1575 fmode = (st.Mode >> 6) & 7
1576 } else {
1577 var gid int
1578 if flags&AT_EACCESS != 0 {
1579 gid = Getegid()
1580 } else {
1581 gid = Getgid()
1582 }
1583
1584 if uint32(gid) == st.Gid {
1585 fmode = (st.Mode >> 3) & 7
1586 } else {
1587 fmode = st.Mode & 7
1588 }
1589 }
1590
1591 if fmode&mode == mode {
1592 return nil
1593 }
1594
1595 return EACCES
1596}
1597
1598/*
1599 * Unimplemented
1600 */
1601// AfsSyscall
1602// Alarm
1603// ArchPrctl
1604// Brk
1605// Capget
1606// Capset
1607// ClockNanosleep
1608// ClockSettime
1609// Clone
1610// EpollCtlOld
1611// EpollPwait
1612// EpollWaitOld
1613// Execve
1614// Fork
1615// Futex
1616// GetKernelSyms
1617// GetMempolicy
1618// GetRobustList
1619// GetThreadArea
1620// Getitimer
1621// Getpmsg
1622// IoCancel
1623// IoDestroy
1624// IoGetevents
1625// IoSetup
1626// IoSubmit
1627// IoprioGet
1628// IoprioSet
1629// KexecLoad
1630// LookupDcookie
1631// Mbind
1632// MigratePages
1633// Mincore
1634// ModifyLdt
1635// Mount
1636// MovePages
1637// MqGetsetattr
1638// MqNotify
1639// MqOpen
1640// MqTimedreceive
1641// MqTimedsend
1642// MqUnlink
1643// Mremap
1644// Msgctl
1645// Msgget
1646// Msgrcv
1647// Msgsnd
1648// Nfsservctl
1649// Personality
1650// Pselect6
1651// Ptrace
1652// Putpmsg
1653// Quotactl
1654// Readahead
1655// Readv
1656// RemapFilePages
1657// RestartSyscall
1658// RtSigaction
1659// RtSigpending
1660// RtSigprocmask
1661// RtSigqueueinfo
1662// RtSigreturn
1663// RtSigsuspend
1664// RtSigtimedwait
1665// SchedGetPriorityMax
1666// SchedGetPriorityMin
1667// SchedGetparam
1668// SchedGetscheduler
1669// SchedRrGetInterval
1670// SchedSetparam
1671// SchedYield
1672// Security
1673// Semctl
1674// Semget
1675// Semop
1676// Semtimedop
1677// SetMempolicy
1678// SetRobustList
1679// SetThreadArea
1680// SetTidAddress
1681// Shmat
1682// Shmctl
1683// Shmdt
1684// Shmget
1685// Sigaltstack
1686// Signalfd
1687// Swapoff
1688// Swapon
1689// Sysfs
1690// TimerCreate
1691// TimerDelete
1692// TimerGetoverrun
1693// TimerGettime
1694// TimerSettime
1695// Timerfd
1696// Tkill (obsolete)
1697// Tuxcall
1698// Umount2
1699// Uselib
1700// Utimensat
1701// Vfork
1702// Vhangup
1703// Vserver
1704// Waitid
1705// _Sysctl