github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/runc/libcontainer/nsenter/nsenter_test.go (about) 1 package nsenter 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "strings" 12 "syscall" 13 "testing" 14 15 "github.com/opencontainers/runc/libcontainer" 16 "github.com/vishvananda/netlink/nl" 17 ) 18 19 type pid struct { 20 Pid int `json:"Pid"` 21 } 22 23 func TestNsenterValidPaths(t *testing.T) { 24 args := []string{"nsenter-exec"} 25 parent, child, err := newPipe() 26 if err != nil { 27 t.Fatalf("failed to create pipe %v", err) 28 } 29 30 namespaces := []string{ 31 // join pid ns of the current process 32 fmt.Sprintf("pid:/proc/%d/ns/pid", os.Getpid()), 33 } 34 cmd := &exec.Cmd{ 35 Path: os.Args[0], 36 Args: args, 37 ExtraFiles: []*os.File{child}, 38 Env: []string{"_LIBCONTAINER_INITPIPE=3"}, 39 Stdout: os.Stdout, 40 Stderr: os.Stderr, 41 } 42 43 if err := cmd.Start(); err != nil { 44 t.Fatalf("nsenter failed to start %v", err) 45 } 46 // write cloneFlags 47 r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) 48 r.AddData(&libcontainer.Int32msg{ 49 Type: libcontainer.CloneFlagsAttr, 50 Value: uint32(syscall.CLONE_NEWNET), 51 }) 52 r.AddData(&libcontainer.Bytemsg{ 53 Type: libcontainer.NsPathsAttr, 54 Value: []byte(strings.Join(namespaces, ",")), 55 }) 56 if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil { 57 t.Fatal(err) 58 } 59 60 decoder := json.NewDecoder(parent) 61 var pid *pid 62 63 if err := cmd.Wait(); err != nil { 64 t.Fatalf("nsenter exits with a non-zero exit status") 65 } 66 if err := decoder.Decode(&pid); err != nil { 67 dir, _ := ioutil.ReadDir(fmt.Sprintf("/proc/%d/ns", os.Getpid())) 68 for _, d := range dir { 69 t.Log(d.Name()) 70 } 71 t.Fatalf("%v", err) 72 } 73 74 p, err := os.FindProcess(pid.Pid) 75 if err != nil { 76 t.Fatalf("%v", err) 77 } 78 p.Wait() 79 } 80 81 func TestNsenterInvalidPaths(t *testing.T) { 82 args := []string{"nsenter-exec"} 83 parent, child, err := newPipe() 84 if err != nil { 85 t.Fatalf("failed to create pipe %v", err) 86 } 87 88 namespaces := []string{ 89 // join pid ns of the current process 90 fmt.Sprintf("pid:/proc/%d/ns/pid", -1), 91 } 92 cmd := &exec.Cmd{ 93 Path: os.Args[0], 94 Args: args, 95 ExtraFiles: []*os.File{child}, 96 Env: []string{"_LIBCONTAINER_INITPIPE=3"}, 97 } 98 99 if err := cmd.Start(); err != nil { 100 t.Fatal(err) 101 } 102 // write cloneFlags 103 r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) 104 r.AddData(&libcontainer.Int32msg{ 105 Type: libcontainer.CloneFlagsAttr, 106 Value: uint32(syscall.CLONE_NEWNET), 107 }) 108 r.AddData(&libcontainer.Bytemsg{ 109 Type: libcontainer.NsPathsAttr, 110 Value: []byte(strings.Join(namespaces, ",")), 111 }) 112 if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil { 113 t.Fatal(err) 114 } 115 116 if err := cmd.Wait(); err == nil { 117 t.Fatalf("nsenter exits with a zero exit status") 118 } 119 } 120 121 func TestNsenterIncorrectPathType(t *testing.T) { 122 args := []string{"nsenter-exec"} 123 parent, child, err := newPipe() 124 if err != nil { 125 t.Fatalf("failed to create pipe %v", err) 126 } 127 128 namespaces := []string{ 129 // join pid ns of the current process 130 fmt.Sprintf("net:/proc/%d/ns/pid", os.Getpid()), 131 } 132 cmd := &exec.Cmd{ 133 Path: os.Args[0], 134 Args: args, 135 ExtraFiles: []*os.File{child}, 136 Env: []string{"_LIBCONTAINER_INITPIPE=3"}, 137 } 138 139 if err := cmd.Start(); err != nil { 140 t.Fatal(err) 141 } 142 // write cloneFlags 143 r := nl.NewNetlinkRequest(int(libcontainer.InitMsg), 0) 144 r.AddData(&libcontainer.Int32msg{ 145 Type: libcontainer.CloneFlagsAttr, 146 Value: uint32(syscall.CLONE_NEWNET), 147 }) 148 r.AddData(&libcontainer.Bytemsg{ 149 Type: libcontainer.NsPathsAttr, 150 Value: []byte(strings.Join(namespaces, ",")), 151 }) 152 if _, err := io.Copy(parent, bytes.NewReader(r.Serialize())); err != nil { 153 t.Fatal(err) 154 } 155 156 if err := cmd.Wait(); err == nil { 157 t.Fatalf("nsenter exits with a zero exit status") 158 } 159 } 160 161 func init() { 162 if strings.HasPrefix(os.Args[0], "nsenter-") { 163 os.Exit(0) 164 } 165 return 166 } 167 168 func newPipe() (parent *os.File, child *os.File, err error) { 169 fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) 170 if err != nil { 171 return nil, nil, err 172 } 173 return os.NewFile(uintptr(fds[1]), "parent"), os.NewFile(uintptr(fds[0]), "child"), nil 174 }