From 6e4298ee9e289d82626fc2c7fb8e96f99b7b2127 Mon Sep 17 00:00:00 2001
From: Jonathon Anderson <janderson@ciq.com>
Date: Fri, 27 Sep 2024 14:06:36 -0600
Subject: [PATCH] Update copy.DirCopy to not unlink sockets

- Closes #2113

`copy.DirCopy` contains code to create named sockets matching those on
the source; however, this operation closes the socket, removing it
implicitly from the destination and causing later chown and chmod
operations to fail.

This commit creates matching file system nodes directly without opening
a socket or invoking the auto-removal semantics of a listener.

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
---
 drivers/copy/copy_linux.go | 5 +----
 drivers/copy/copy_test.go  | 6 ++++++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/copy/copy_linux.go b/drivers/copy/copy_linux.go
index caf07602ba..8c0bbed618 100644
--- a/drivers/copy/copy_linux.go
+++ b/drivers/copy/copy_linux.go
@@ -16,7 +16,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"net"
 	"os"
 	"path/filepath"
 	"strings"
@@ -199,11 +198,9 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
 			}
 
 		case mode&os.ModeSocket != 0:
-			s, err := net.Listen("unix", dstPath)
-			if err != nil {
+			if err := unix.Mknod(dstPath, stat.Mode, int(stat.Rdev)); err != nil {
 				return err
 			}
-			s.Close()
 
 		case mode&os.ModeDevice != 0:
 			if unshare.IsRootless() {
diff --git a/drivers/copy/copy_test.go b/drivers/copy/copy_test.go
index 9c69908840..8243d2243c 100644
--- a/drivers/copy/copy_test.go
+++ b/drivers/copy/copy_test.go
@@ -5,6 +5,7 @@ package copy
 import (
 	"fmt"
 	"math/rand"
+	"net"
 	"os"
 	"path/filepath"
 	"syscall"
@@ -83,6 +84,11 @@ func randomMode(baseMode int) os.FileMode {
 
 func populateSrcDir(t *testing.T, srcDir string, remainingDepth int) {
 	if remainingDepth == 0 {
+		socketPath := filepath.Join(srcDir, "srcsocket")
+		s, err := net.ListenUnix("unix", &net.UnixAddr{Name: socketPath, Net: "unix"})
+		assert.NilError(t, err)
+		s.SetUnlinkOnClose(false)
+		s.Close()
 		return
 	}
 	aTime := time.Unix(rand.Int63(), 0)