Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nsexec spring cleaning part I #3982

Merged
merged 7 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ unittest: runcimage
-t --privileged --rm \
-v /lib/modules:/lib/modules:ro \
-v $(CURDIR):/go/src/$(PROJECT) \
$(RUNC_IMAGE) make localunittest TESTFLAGS=$(TESTFLAGS)
$(RUNC_IMAGE) make localunittest TESTFLAGS="$(TESTFLAGS)"

localunittest: all
$(GO) test -timeout 3m -tags "$(BUILDTAGS)" $(TESTFLAGS) -v ./...
Expand All @@ -115,7 +115,7 @@ integration: runcimage
-t --privileged --rm \
-v /lib/modules:/lib/modules:ro \
-v $(CURDIR):/go/src/$(PROJECT) \
$(RUNC_IMAGE) make localintegration TESTPATH=$(TESTPATH)
$(RUNC_IMAGE) make localintegration TESTPATH="$(TESTPATH)"

localintegration: all
bats -t tests/integration$(TESTPATH)
Expand Down
4 changes: 2 additions & 2 deletions contrib/cmd/recvtty/recvtty.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func handleSingle(path string, noStdin bool) error {
defer socket.Close()

// Get the master file descriptor from runC.
master, err := utils.RecvFd(socket)
master, err := utils.RecvFile(socket)
if err != nil {
return err
}
Expand Down Expand Up @@ -171,7 +171,7 @@ func handleNull(path string) error {
defer socket.Close()

// Get the master file descriptor from runC.
master, err := utils.RecvFd(socket)
master, err := utils.RecvFile(socket)
if err != nil {
return
}
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/configs/mount_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ type Mount struct {
// Note that, the underlying filesystem should support this feature to be
// used.
// Every mount point could have its own mapping.
UIDMappings []IDMap `json:"uidMappings,omitempty"`
UIDMappings []IDMap `json:"uid_mappings,omitempty"`

// GIDMappings is used to changing file group owners w/o calling chown.
// Note that, the underlying filesystem should support this feature to be
// used.
// Every mount point could have its own mapping.
GIDMappings []IDMap `json:"gidMappings,omitempty"`
GIDMappings []IDMap `json:"gid_mappings,omitempty"`
}

func (m *Mount) IsBind() bool {
Expand Down
2 changes: 1 addition & 1 deletion libcontainer/criu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@ func (c *Container) criuNotifications(resp *criurpc.CriuResp, process *Process,
defer master.Close()

// While we can access console.master, using the API is a good idea.
if err := utils.SendFd(process.ConsoleSocket, master.Name(), master.Fd()); err != nil {
if err := utils.SendFile(process.ConsoleSocket, master); err != nil {
return err
}
case "status-ready":
Expand Down
61 changes: 25 additions & 36 deletions libcontainer/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net"
"os"
"runtime"
Expand Down Expand Up @@ -121,11 +120,8 @@ func startInitialization() (retErr error) {
defer func() {
// If this defer is ever called, this means initialization has failed.
// Send the error back to the parent process in the form of an initError.
if err := writeSync(pipe, procError); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
if err := utils.WriteJSON(pipe, &initError{Message: retErr.Error()}); err != nil {
ierr := initError{Message: retErr.Error()}
if err := writeSyncArg(pipe, procError, ierr); err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
Expand Down Expand Up @@ -352,7 +348,6 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
if err != nil {
return err
}

// After we return from here, we don't need the console anymore.
defer pty.Close()

Expand All @@ -374,67 +369,61 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
}
}
// While we can access console.master, using the API is a good idea.
if err := utils.SendFd(socket, pty.Name(), pty.Fd()); err != nil {
if err := utils.SendRawFd(socket, pty.Name(), pty.Fd()); err != nil {
return err
}
runtime.KeepAlive(pty)

// Now, dup over all the things.
return dupStdio(slavePath)
}

// syncParentReady sends to the given pipe a JSON payload which indicates that
// the init is ready to Exec the child process. It then waits for the parent to
// indicate that it is cleared to Exec.
func syncParentReady(pipe io.ReadWriter) error {
func syncParentReady(pipe *os.File) error {
// Tell parent.
if err := writeSync(pipe, procReady); err != nil {
return err
}

// Wait for parent to give the all-clear.
return readSync(pipe, procRun)
}

// syncParentHooks sends to the given pipe a JSON payload which indicates that
// the parent should execute pre-start hooks. It then waits for the parent to
// indicate that it is cleared to resume.
func syncParentHooks(pipe io.ReadWriter) error {
func syncParentHooks(pipe *os.File) error {
// Tell parent.
if err := writeSync(pipe, procHooks); err != nil {
return err
}

// Wait for parent to give the all-clear.
return readSync(pipe, procResume)
}

// syncParentSeccomp sends to the given pipe a JSON payload which
// indicates that the parent should pick up the seccomp fd with pidfd_getfd()
// and send it to the seccomp agent over a unix socket. It then waits for
// the parent to indicate that it is cleared to resume and closes the seccompFd.
// If the seccompFd is -1, there isn't anything to sync with the parent, so it
// returns no error.
func syncParentSeccomp(pipe io.ReadWriter, seccompFd int) error {
if seccompFd == -1 {
// syncParentSeccomp sends the fd associated with the seccomp file descriptor
// to the parent, and wait for the parent to do pidfd_getfd() to grab a copy.
func syncParentSeccomp(pipe *os.File, seccompFd *os.File) error {
if seccompFd == nil {
return nil
}

// Tell parent.
if err := writeSyncWithFd(pipe, procSeccomp, seccompFd); err != nil {
unix.Close(seccompFd)
defer seccompFd.Close()

// Tell parent to grab our fd.
//
// Notably, we do not use writeSyncFile here because a container might have
// an SCMP_ACT_NOTIFY action on sendmsg(2) so we need to use the smallest
// possible number of system calls here because all of those syscalls
// cannot be used with SCMP_ACT_NOTIFY as a result (any syscall we use here
// before the parent gets the file descriptor would deadlock "runc init" if
// we allowed it for SCMP_ACT_NOTIFY). See seccomp.InitSeccomp() for more
// details.
if err := writeSyncArg(pipe, procSeccomp, seccompFd.Fd()); err != nil {
return err
}

// Wait for parent to give the all-clear.
if err := readSync(pipe, procSeccompDone); err != nil {
unix.Close(seccompFd)
return fmt.Errorf("sync parent seccomp: %w", err)
}

if err := unix.Close(seccompFd); err != nil {
return fmt.Errorf("close seccomp fd: %w", err)
}

return nil
// Wait for parent to tell us they've grabbed the seccompfd.
return readSync(pipe, procSeccompDone)
}

// setupUser changes the groups, gid, and uid for the user inside the container
Expand Down
4 changes: 2 additions & 2 deletions libcontainer/integration/execin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,9 @@ func TestExecInTTY(t *testing.T) {

done := make(chan (error))
go func() {
f, err := utils.RecvFd(parent)
f, err := utils.RecvFile(parent)
if err != nil {
done <- fmt.Errorf("RecvFd: %w", err)
done <- fmt.Errorf("RecvFile: %w", err)
return
}
c, err := console.ConsoleFromFile(f)
Expand Down
6 changes: 1 addition & 5 deletions libcontainer/nsenter/nsexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ void nsexec(void)
* some old kernel versions where clone(CLONE_PARENT | CLONE_NEWPID)
* was broken, so we'll just do it the long way anyway.
*/
try_unshare(config.cloneflags & ~CLONE_NEWCGROUP, "remaining namespaces (except cgroupns)");
try_unshare(config.cloneflags, "remaining namespaces");
update_timens_offsets(config.timensoffset, config.timensoffset_len);

/* Ask our parent to send the mount sources fds. */
Expand Down Expand Up @@ -1302,10 +1302,6 @@ void nsexec(void)
bail("setgroups failed");
}

if (config.cloneflags & CLONE_NEWCGROUP) {
try_unshare(CLONE_NEWCGROUP, "cgroup namespace");
}

write_log(DEBUG, "signal completion to stage-0");
s = SYNC_CHILD_FINISH;
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
Expand Down
Loading