From c011b6ad793080761795cdd20bdc3ac7ccad3202 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Wed, 1 Nov 2023 11:09:02 -0700 Subject: [PATCH] runsc: use a pipe for the NAT blob This is just a little easier than creating and deleting a temp file. PiperOrigin-RevId: 578575893 --- runsc/boot/network.go | 3 --- runsc/sandbox/network.go | 3 +-- runsc/sandbox/network_unsafe.go | 25 +++++++++++-------------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/runsc/boot/network.go b/runsc/boot/network.go index 2b8f73120..c6b00c78a 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -451,9 +451,6 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct // Set NAT table rules if necessary. if args.NATBlob { log.Infof("Replacing NAT table") - if _, err := unix.Seek(int(args.FilePayload.Files[fdOffset].Fd()), 0, unix.SEEK_SET); err != nil { - return fmt.Errorf("failed to seek: %v", err) - } iptReplaceBlob, err := io.ReadAll(args.FilePayload.Files[fdOffset]) if err != nil { return fmt.Errorf("failed to read iptables blob: %v", err) diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index c96116103..1189771c0 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -322,11 +322,10 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, conf *con // Pass the host's NAT table if requested. if conf.ReproduceNAT { args.NATBlob = true - f, cleanup, err := writeNATBlob() + f, err := writeNATBlob() if err != nil { return fmt.Errorf("failed to write NAT blob: %v", err) } - defer cleanup() args.FilePayload.Files = append(args.FilePayload.Files, f) } diff --git a/runsc/sandbox/network_unsafe.go b/runsc/sandbox/network_unsafe.go index f7614fdb6..1a8e92469 100644 --- a/runsc/sandbox/network_unsafe.go +++ b/runsc/sandbox/network_unsafe.go @@ -57,11 +57,11 @@ func isGSOEnabled(fd int, intf string) (bool, error) { return val.val != 0, nil } -func writeNATBlob() (*os.File, func(), error) { +func writeNATBlob() (*os.File, error) { // Open a socket to use with iptables. iptSock, err := unix.Socket(unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_ICMP) if err != nil { - return nil, nil, fmt.Errorf("failed to open socket for iptables: %v", err) + return nil, fmt.Errorf("failed to open socket for iptables: %v", err) } defer unix.Close(iptSock) @@ -78,7 +78,7 @@ func writeNATBlob() (*os.File, func(), error) { uintptr(unsafe.Pointer(&natInfoLen)), 0) if errno != 0 { - return nil, nil, fmt.Errorf("failed to call IPT_SO_GET_INFO: %v", err) + return nil, fmt.Errorf("failed to call IPT_SO_GET_INFO: %v", err) } // Get the iptables entries. @@ -94,7 +94,7 @@ func writeNATBlob() (*os.File, func(), error) { uintptr(unsafe.Pointer(&entriesBufLen)), 0) if errno != 0 { - return nil, nil, fmt.Errorf("failed to call IPT_SO_GET_ENTRIES: %v", errno) + return nil, fmt.Errorf("failed to call IPT_SO_GET_ENTRIES: %v", errno) } var gotEntries linux.IPTGetEntries gotEntries.UnmarshalUnsafe(entriesBuf[:unsafe.Sizeof(entries)]) @@ -119,17 +119,14 @@ func writeNATBlob() (*os.File, func(), error) { panic(fmt.Sprintf("failed to populate entry table: copied %d bytes, but wanted to copy %d", n, natInfo.Size)) } - // Write blob to file. - blobFile, err := os.CreateTemp("", "iptables-blob-") + // Write blob to a pipe. + reader, writer, err := os.Pipe() if err != nil { - return nil, nil, fmt.Errorf("failed to create iptables blob file: %v", err) + return nil, fmt.Errorf("failed to create iptables blob pipe: %v", err) } - if n, err := blobFile.Write(replaceBuf); n != len(replaceBuf) || err != nil { - os.Remove(blobFile.Name()) - return nil, nil, fmt.Errorf("failed to write iptables blob: wrote %d bytes (%d expected) and got error: %v", n, len(replaceBuf), err) + defer writer.Close() + if n, err := writer.Write(replaceBuf); n != len(replaceBuf) || err != nil { + return nil, fmt.Errorf("failed to write iptables blob: wrote %d bytes (%d expected) and got error: %v", n, len(replaceBuf), err) } - cleanup := func() { - os.Remove(blobFile.Name()) - } - return blobFile, cleanup, nil + return reader, nil }