Skip to content

Commit 860c035

Browse files
authored
🐛 [platform] make sure command with privileges are run when passwords are not needed (#663)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description - fix problem with run command with privileges - fix problem with unlink when rm a socket on linux ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update).
1 parent 3c1f24b commit 860c035

File tree

9 files changed

+37
-7
lines changed

9 files changed

+37
-7
lines changed

.secrets.baseline

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,5 +272,5 @@
272272
}
273273
]
274274
},
275-
"generated_at": "2025-07-09T20:27:15Z"
275+
"generated_at": "2025-07-31T17:26:46Z"
276276
}

changes/20250731182237.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:bug: `[platform]` make sure command with privileges are run when passwords are not needed

changes/20250731182404.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:bug: `[filesystem]` make sure to unlink files when removal is called so that sockets are correctly closed

utils/filesystem/extendedosfs.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ package filesystem
88
import (
99
"context"
1010
"os"
11+
"syscall"
1112

1213
"github.com/spf13/afero"
1314

15+
"github.com/ARM-software/golang-utils/utils/commonerrors"
1416
"github.com/ARM-software/golang-utils/utils/platform"
1517
)
1618

@@ -19,6 +21,17 @@ type ExtendedOsFs struct {
1921
afero.OsFs
2022
}
2123

24+
func (c *ExtendedOsFs) Remove(name string) (err error) {
25+
err = commonerrors.Ignore(ConvertFileSystemError(c.OsFs.Remove(name)), commonerrors.ErrNotFound)
26+
if err != nil {
27+
return
28+
}
29+
// The following is to ensure sockets are correctly removed
30+
// https://stackoverflow.com/questions/16681944/how-to-reliably-unlink-a-unix-domain-socket-in-go-programming-language
31+
err = commonerrors.Ignore(ConvertFileSystemError(syscall.Unlink(name)), commonerrors.ErrNotFound)
32+
return
33+
}
34+
2235
func (c *ExtendedOsFs) ChownIfPossible(name string, uid int, gid int) error {
2336
return ConvertFileSystemError(c.OsFs.Chown(name, uid, gid))
2437
}

utils/filesystem/filesystem.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func ConvertFileSystemError(err error) error {
115115
return commonerrors.WrapError(commonerrors.ErrConflict, err, "")
116116
case commonerrors.CorrespondTo(err, "required privilege is not held") || commonerrors.CorrespondTo(err, "operation not permitted"):
117117
return commonerrors.WrapError(commonerrors.ErrForbidden, err, "")
118-
case os.IsNotExist(err) || commonerrors.Any(err, os.ErrNotExist, afero.ErrFileNotFound):
118+
case os.IsNotExist(err) || commonerrors.Any(err, os.ErrNotExist, afero.ErrFileNotFound) || IsPathNotExist(err) || commonerrors.CorrespondTo(err, "No such file or directory"):
119119
return commonerrors.WrapError(commonerrors.ErrNotFound, err, "")
120120
case commonerrors.Any(err, os.ErrNoDeadline):
121121
return commonerrors.WrapError(commonerrors.ErrUnsupported, err, "file type does not support deadline")

utils/platform/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func WithPrivileges(cmd *command.CommandAsDifferentUser) (cmdWithPrivileges *com
1515
if err != nil {
1616
return
1717
}
18-
if !hasPrivileges {
18+
if !hasPrivileges && hasPasswordlessPrivileges() {
1919
cmdWithPrivileges.Prepend(getRunCommandWithPrivileges())
2020
}
2121
return

utils/platform/cmd_posix.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
package platform
55

6-
import "github.com/ARM-software/golang-utils/utils/subprocess/command"
6+
import (
7+
"os/exec"
8+
9+
"github.com/ARM-software/golang-utils/utils/subprocess/command"
10+
)
711

812
var (
913
// sudoCommand describes the command to use to execute command as root
@@ -22,3 +26,8 @@ func DefineSudoCommand(args ...string) {
2226
func getRunCommandWithPrivileges() *command.CommandAsDifferentUser {
2327
return sudoCommand
2428
}
29+
30+
func hasPasswordlessPrivileges() bool {
31+
// See https://www.baeldung.com/linux/sudo-passwordless-check
32+
return exec.Command("sh", "-c", "sudo -n true 2>/dev/null || exit 1").Run() == nil
33+
}

utils/platform/cmd_windows.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
package platform
55

6-
import "github.com/ARM-software/golang-utils/utils/subprocess/command"
6+
import (
7+
"github.com/ARM-software/golang-utils/utils/subprocess/command"
8+
)
79

810
var (
911
// runAsAdmin describes the command to use to run command as Administrator
@@ -23,3 +25,7 @@ func DefineRunAsAdmin(args ...string) {
2325
func getRunCommandWithPrivileges() *command.CommandAsDifferentUser {
2426
return runAsAdmin
2527
}
28+
29+
func hasPasswordlessPrivileges() bool {
30+
return true
31+
}

utils/subprocess/command/cmd.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"sync"
77
)
88

9-
// CommandAsDifferentUser helps redefining commands so that they are run as a different user or with more privileges.
9+
// CommandAsDifferentUser helps to redefine commands so that they are run as a different user or with more privileges.
1010
type CommandAsDifferentUser struct {
1111
mu sync.RWMutex
1212
// changeUserCmd describes the command to use to execute any command as a different user
@@ -65,7 +65,7 @@ func (c *CommandAsDifferentUser) Prepend(cmd *CommandAsDifferentUser) *CommandAs
6565
return c
6666
}
6767

68-
// NewCommandAsDifferentUser defines a command wrapper which helps redefining commands so that they are run as a different user.
68+
// NewCommandAsDifferentUser defines a command wrapper which helps to redefine commands so that they are run as a different user.
6969
// e.g.
7070
// - switchUserCmd="sudo" to run commands as `root`
7171
// - switchUserCmd="su", "tom" if `tom` has enough privileges to run the command

0 commit comments

Comments
 (0)