Skip to content

Commit

Permalink
Merge pull request #1394 from cyphar/sendfd-convert-to-sysunix
Browse files Browse the repository at this point in the history
libcontainer: rewrite cmsg to use sys/unix
  • Loading branch information
Mrunal Patel authored Apr 3, 2017
2 parents 653207b + cbc4f98 commit f990e58
Show file tree
Hide file tree
Showing 197 changed files with 122,046 additions and 202 deletions.
148 changes: 0 additions & 148 deletions libcontainer/utils/cmsg.c

This file was deleted.

74 changes: 56 additions & 18 deletions libcontainer/utils/cmsg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package utils

/*
* Copyright 2016 SUSE LLC
* Copyright 2016, 2017 SUSE LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,40 +18,78 @@ package utils
* limitations under the License.
*/

/*
#include <errno.h>
#include <stdlib.h>
#include "cmsg.h"
*/
import "C"

import (
"fmt"
"os"
"unsafe"

"golang.org/x/sys/unix"
)

// MaxSendfdLen is the maximum length of the name of a file descriptor being
// sent using SendFd. The name of the file handle returned by RecvFd will never
// be larger than this value.
const MaxNameLen = 4096

// oobSpace is the size of the oob slice required to store a single FD. Note
// that unix.UnixRights appears to make the assumption that fd is always int32,
// so sizeof(fd) = 4.
var oobSpace = unix.CmsgSpace(4)

// RecvFd waits for a file descriptor to be sent over the given AF_UNIX
// socket. The file name of the remote file descriptor will be recreated
// locally (it is sent as non-auxiliary data in the same payload).
func RecvFd(socket *os.File) (*os.File, error) {
file, err := C.recvfd(C.int(socket.Fd()))
// For some reason, unix.Recvmsg uses the length rather than the capacity
// when passing the msg_controllen and other attributes to recvmsg. So we
// have to actually set the length.
name := make([]byte, MaxNameLen)
oob := make([]byte, oobSpace)

sockfd := socket.Fd()
n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0)
if err != nil {
return nil, err
}
defer C.free(unsafe.Pointer(file.name))
return os.NewFile(uintptr(file.fd), C.GoString(file.name)), nil

if n >= MaxNameLen || oobn != oobSpace {
return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
}

// Truncate.
name = name[:n]
oob = oob[:oobn]

scms, err := unix.ParseSocketControlMessage(oob)
if err != nil {
return nil, err
}
if len(scms) != 1 {
return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
}
scm := scms[0]

fds, err := unix.ParseUnixRights(&scm)
if err != nil {
return nil, err
}
if len(fds) != 1 {
return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
}
fd := uintptr(fds[0])

return os.NewFile(fd, string(name)), nil
}

// SendFd sends a file descriptor over the given AF_UNIX socket. In
// addition, the file.Name() of the given file will also be sent as
// non-auxiliary data in the same payload (allowing to send contextual
// information for a file descriptor).
func SendFd(socket, file *os.File) error {
var cfile C.struct_file_t
cfile.fd = C.int(file.Fd())
cfile.name = C.CString(file.Name())
defer C.free(unsafe.Pointer(cfile.name))
name := []byte(file.Name())
if len(name) >= MaxNameLen {
return fmt.Errorf("sendfd: filename too long: %s", file.Name())
}
oob := unix.UnixRights(int(file.Fd()))

_, err := C.sendfd(C.int(socket.Fd()), cfile)
return err
return unix.Sendmsg(int(socket.Fd()), name, oob, nil, 0)
}
36 changes: 0 additions & 36 deletions libcontainer/utils/cmsg.h

This file was deleted.

1 change: 1 addition & 0 deletions vendor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
github.com/syndtr/gocapability/capability e7cb7fa329f456b3855136a2642b197bad7366ba
github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
github.com/vishvananda/netlink 1e2e08e8a2dcdacaae3f14ac44c5cfa31361f270
golang.org/x/sys 9a7256cb28ed514b4e1e5f68959914c4c28a92e0 https://github.com/golang/sys
27 changes: 27 additions & 0 deletions vendor/golang.org/x/sys/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions vendor/golang.org/x/sys/PATENTS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions vendor/golang.org/x/sys/README

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions vendor/golang.org/x/sys/unix/asm_darwin_386.s

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f990e58

Please sign in to comment.