Skip to content

Commit 0801b88

Browse files
authored
fix: explicitly set permissions for socket_vmnet dependencies (#363)
Issue #, if available: #57 *Description of changes:* Sets permissions explicitly for socket_vmnet dependencies, which will override a user's `umask` to ensure that Finch can use the files as needed. *Testing done:* ``` $ umask 077 $ make $ sudo rm -rf /opt/finch/bin/socket_vmnet* $ sudo rm -rf /etc/sudoers.d/finch-lima $ ./_output/bin/finch vm init ``` unit testing - [x] I've reviewed the guidance in CONTRIBUTING.md #### License Acceptance By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. Signed-off-by: Sam Berning <[email protected]>
1 parent 5e03a4d commit 0801b88

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

pkg/dependency/vmnet/binaries.go

+8
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ func (bin *binaries) Install() error {
122122
return fmt.Errorf("error changing owner of files in directory %s, err: %w", installationPathBinDir, err)
123123
}
124124

125+
// in most cases this should not be needed, as the permissions should be copied from the build artifacts,
126+
// but the permissions can end up being wrong when Finch is built on a shell that has a restrictive umask.
127+
chmodBinCmd := bin.cmdCreator.Create("sudo", "chmod", "755", bin.installationPathSocketVmnetExe())
128+
_, err = chmodBinCmd.Output()
129+
if err != nil {
130+
return fmt.Errorf("error setting correct permissions for socket_vmnet binary, err: %w", err)
131+
}
132+
125133
return nil
126134
}
127135

pkg/dependency/vmnet/binaries_test.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,13 @@ func TestBinaries_Install(t *testing.T) {
176176
{
177177
name: "happy path",
178178
mockSvc: func(cmd *mocks.Command, creator *mocks.CommandCreator) {
179-
cmd.EXPECT().Output().Times(4)
179+
cmd.EXPECT().Output().Times(5)
180180

181181
creator.EXPECT().Create("sudo", "mkdir", "-p", "/opt/finch").Return(cmd)
182182
creator.EXPECT().Create("sudo", "cp", "-rp", "mock_prefix/dependencies/lima-socket_vmnet/opt/finch", "/opt").Return(cmd)
183183
creator.EXPECT().Create("sudo", "chown", "root:wheel", "/opt/finch").Return(cmd)
184184
creator.EXPECT().Create("sudo", "chown", "-R", "root:wheel", "/opt/finch/bin").Return(cmd)
185+
creator.EXPECT().Create("sudo", "chmod", "755", "/opt/finch/bin/socket_vmnet").Return(cmd)
185186
},
186187
want: nil,
187188
},
@@ -230,6 +231,20 @@ func TestBinaries_Install(t *testing.T) {
230231
},
231232
want: fmt.Errorf("error changing owner of files in directory %s, err: %w", "/opt/finch/bin", errors.New("chown -R error")),
232233
},
234+
{
235+
name: "sudo chmod of the binary throws an error",
236+
mockSvc: func(cmd *mocks.Command, creator *mocks.CommandCreator) {
237+
cmd.EXPECT().Output().Times(4)
238+
cmd.EXPECT().Output().Return([]byte{}, errors.New("sudo chmod error"))
239+
240+
creator.EXPECT().Create("sudo", "mkdir", "-p", "/opt/finch").Return(cmd)
241+
creator.EXPECT().Create("sudo", "cp", "-rp", "mock_prefix/dependencies/lima-socket_vmnet/opt/finch", "/opt").Return(cmd)
242+
creator.EXPECT().Create("sudo", "chown", "root:wheel", "/opt/finch").Return(cmd)
243+
creator.EXPECT().Create("sudo", "chown", "-R", "root:wheel", "/opt/finch/bin").Return(cmd)
244+
creator.EXPECT().Create("sudo", "chmod", "755", "/opt/finch/bin/socket_vmnet").Return(cmd)
245+
},
246+
want: fmt.Errorf("error setting correct permissions for socket_vmnet binary, err: %w", errors.New("sudo chmod error")),
247+
},
233248
}
234249

235250
for _, tc := range testCases {

pkg/dependency/vmnet/sudoers_file.go

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ func (s *sudoersFile) Install() error {
7575
return fmt.Errorf("failed to write to the sudoers file: %w", err)
7676
}
7777

78+
// explicitly set permissions to ensure that the file is readable by the user
79+
_, err = s.execCmdCreator.Create("sudo", "chmod", "644", s.path()).Output()
80+
if err != nil {
81+
return fmt.Errorf("failed to set correct permissions for sudoers file: %w", err)
82+
}
83+
7884
return nil
7985
}
8086

pkg/dependency/vmnet/sudoers_file_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ func TestSudoers_Install(t *testing.T) {
133133
ec.EXPECT().Create("sudo", "tee", "/etc/sudoers.d/finch-lima").Return(cmd)
134134
cmd.EXPECT().SetStdin(bytes.NewReader(mockSudoersOut))
135135
cmd.EXPECT().Output().Return(mockSudoersOut, nil)
136+
ec.EXPECT().Create("sudo", "chmod", "644", "/etc/sudoers.d/finch-lima").Return(cmd)
137+
cmd.EXPECT().Output().Return([]byte{}, nil)
136138
},
137139
want: nil,
138140
},
@@ -166,6 +168,25 @@ func TestSudoers_Install(t *testing.T) {
166168
},
167169
want: fmt.Errorf("failed to write to the sudoers file: %w", errors.New("sudo tee command error")),
168170
},
171+
{
172+
name: "sudo chmod command throws err",
173+
mockSvc: func(t *testing.T, cmd *mocks.Command, mFs afero.Fs, ec *mocks.CommandCreator, lc *mocks.LimaCmdCreator) {
174+
sudoersData := []byte("test data")
175+
mockSudoersOut := []byte("mock_sudoers_out")
176+
177+
err := afero.WriteFile(mFs, "/etc/sudoers.d/finch-lima", sudoersData, 0o666)
178+
require.NoError(t, err)
179+
180+
lc.EXPECT().CreateWithoutStdio("sudoers").Return(cmd)
181+
cmd.EXPECT().Output().Return(mockSudoersOut, nil)
182+
ec.EXPECT().Create("sudo", "tee", "/etc/sudoers.d/finch-lima").Return(cmd)
183+
cmd.EXPECT().SetStdin(bytes.NewReader(mockSudoersOut))
184+
cmd.EXPECT().Output().Return(mockSudoersOut, nil)
185+
ec.EXPECT().Create("sudo", "chmod", "644", "/etc/sudoers.d/finch-lima").Return(cmd)
186+
cmd.EXPECT().Output().Return([]byte{}, errors.New("sudo chmod command error"))
187+
},
188+
want: fmt.Errorf("failed to set correct permissions for sudoers file: %w", errors.New("sudo chmod command error")),
189+
},
169190
}
170191

171192
for _, tc := range testCases {

0 commit comments

Comments
 (0)