summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/fd/fd.go16
-rw-r--r--runsc/fsgofer/filter/config.go28
-rw-r--r--runsc/fsgofer/fsgofer.go73
3 files changed, 96 insertions, 21 deletions
diff --git a/pkg/fd/fd.go b/pkg/fd/fd.go
index 83bcfe220..c3acd0fe2 100644
--- a/pkg/fd/fd.go
+++ b/pkg/fd/fd.go
@@ -22,6 +22,7 @@ import (
"runtime"
"sync/atomic"
"syscall"
+ "net"
)
// ReadWriter implements io.ReadWriter, io.ReaderAt, and io.WriterAt for fd. It
@@ -185,6 +186,21 @@ func OpenAt(dir *FD, path string, flags int, mode uint32) (*FD, error) {
return New(f), nil
}
+// OpenUnix TODO: DOC
+func OpenUnix(path string) (*FD, error) {
+ addr, _ := net.ResolveUnixAddr("unix", path)
+ f, err := net.DialUnix("unix", nil, addr); if err != nil {
+ return nil, fmt.Errorf("unable to open socket: %q, err: %v", path, err)
+ }
+ fConnd, err := f.File(); if err != nil {
+ return nil, fmt.Errorf("unable to convert to os.File: %q, err: %v", path, err)
+ }
+ fdConnd, err := NewFromFile(fConnd); if err != nil {
+ return nil, fmt.Errorf("unable to convert os.File to fd.FD: %q, err: %v", path, err)
+ }
+ return fdConnd, nil
+}
+
// Close closes the file descriptor contained in the FD.
//
// Close is safe to call multiple times, but will return an error after the
diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go
index 8ddfa77d6..71f387bd0 100644
--- a/runsc/fsgofer/filter/config.go
+++ b/runsc/fsgofer/filter/config.go
@@ -26,6 +26,31 @@ import (
// allowedSyscalls is the set of syscalls executed by the gofer.
var allowedSyscalls = seccomp.SyscallRules{
syscall.SYS_ACCEPT: {},
+ syscall.SYS_SOCKET: []seccomp.Rule{
+ {
+ seccomp.AllowValue(syscall.AF_UNIX),
+ },
+ },
+ syscall.SYS_CONNECT: []seccomp.Rule{
+ {
+ seccomp.AllowAny{},
+ },
+ },
+ syscall.SYS_SETSOCKOPT: []seccomp.Rule{
+ {
+ seccomp.AllowAny{},
+ },
+ },
+ syscall.SYS_GETSOCKNAME: []seccomp.Rule{
+ {
+ seccomp.AllowAny{},
+ },
+ },
+ syscall.SYS_GETPEERNAME: []seccomp.Rule{
+ {
+ seccomp.AllowAny{},
+ },
+ },
syscall.SYS_ARCH_PRCTL: []seccomp.Rule{
{seccomp.AllowValue(linux.ARCH_GET_FS)},
{seccomp.AllowValue(linux.ARCH_SET_FS)},
@@ -83,6 +108,9 @@ var allowedSyscalls = seccomp.SyscallRules{
seccomp.AllowAny{},
seccomp.AllowValue(syscall.F_GETFD),
},
+ {
+ seccomp.AllowAny{},
+ },
},
syscall.SYS_FSTAT: {},
syscall.SYS_FSTATFS: {},
diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go
index 7c4d2b94e..3a78d20a3 100644
--- a/runsc/fsgofer/fsgofer.go
+++ b/runsc/fsgofer/fsgofer.go
@@ -54,6 +54,7 @@ const (
regular fileType = iota
directory
symlink
+ socket
unknown
)
@@ -66,6 +67,8 @@ func (f fileType) String() string {
return "directory"
case symlink:
return "symlink"
+ case socket:
+ return "socket"
}
return "unknown"
}
@@ -124,30 +127,56 @@ func (a *attachPoint) Attach() (p9.File, error) {
if err != nil {
return nil, fmt.Errorf("stat file %q, err: %v", a.prefix, err)
}
- mode := syscall.O_RDWR
- if a.conf.ROMount || (stat.Mode&syscall.S_IFMT) == syscall.S_IFDIR {
- mode = syscall.O_RDONLY
- }
- // Open the root directory.
- f, err := fd.Open(a.prefix, openFlags|mode, 0)
- if err != nil {
- return nil, fmt.Errorf("unable to open file %q, err: %v", a.prefix, err)
- }
+ // Apply the S_IFMT bitmask so we can detect file type appropriately
+ fmtStat := stat.Mode & syscall.S_IFMT
- a.attachedMu.Lock()
- defer a.attachedMu.Unlock()
- if a.attached {
- f.Close()
- return nil, fmt.Errorf("attach point already attached, prefix: %s", a.prefix)
- }
+ switch fmtStat{
+ case syscall.S_IFSOCK:
+ // Attempt to open a connection. Bubble up the failures.
+ f, err := fd.OpenUnix(a.prefix); if err != nil {
+ return nil, err
+ }
- rv, err := newLocalFile(a, f, a.prefix, stat)
- if err != nil {
- return nil, err
+ // Close the connection if the UDS is already attached.
+ a.attachedMu.Lock()
+ defer a.attachedMu.Unlock()
+ if a.attached {
+ f.Close()
+ return nil, fmt.Errorf("attach point already attached, prefix: %s", a.prefix)
+ }
+ a.attached = true
+
+ // Return a localFile object to the caller with the UDS FD included.
+ return newLocalFile(a, f, a.prefix, stat)
+
+ default:
+ // Default to Read/Write permissions.
+ mode := syscall.O_RDWR
+ // If the configuration is Read Only & the mount point is a directory,
+ // set the mode to Read Only.
+ if a.conf.ROMount || fmtStat == syscall.S_IFDIR {
+ mode = syscall.O_RDONLY
+ }
+
+ // Open the mount point & capture the FD.
+ f, err := fd.Open(a.prefix, openFlags|mode, 0)
+ if err != nil {
+ return nil, fmt.Errorf("unable to open file %q, err: %v", a.prefix, err)
+ }
+
+ // If the mount point has already been attached, close the FD.
+ a.attachedMu.Lock()
+ defer a.attachedMu.Unlock()
+ if a.attached {
+ f.Close()
+ return nil, fmt.Errorf("attach point already attached, prefix: %s", a.prefix)
+ }
+ a.attached = true
+
+ // Return a localFile object to the caller with the mount point FD
+ return newLocalFile(a, f, a.prefix, stat)
}
- a.attached = true
- return rv, nil
}
// makeQID returns a unique QID for the given stat buffer.
@@ -304,6 +333,8 @@ func getSupportedFileType(stat syscall.Stat_t) (fileType, error) {
ft = directory
case syscall.S_IFLNK:
ft = symlink
+ case syscall.S_IFSOCK:
+ ft = socket
default:
return unknown, syscall.EPERM
}
@@ -1026,7 +1057,7 @@ func (l *localFile) Flush() error {
// Connect implements p9.File.
func (l *localFile) Connect(p9.ConnectFlags) (*fd.FD, error) {
- return nil, syscall.ECONNREFUSED
+ return fd.OpenUnix(l.hostPath)
}
// Close implements p9.File.