7
7
"log/slog"
8
8
"os"
9
9
"os/exec"
10
+ "os/user"
10
11
"strconv"
11
12
"strings"
12
13
"syscall"
@@ -84,16 +85,48 @@ func (m *MacOSNetJail) Execute(command []string, extraEnv map[string]string) err
84
85
env = append (env , fmt .Sprintf ("%s=%s" , key , value ))
85
86
}
86
87
88
+ // When running under sudo, restore essential user environment variables
89
+ if sudoUser := os .Getenv ("SUDO_USER" ); sudoUser != "" {
90
+ if user , err := user .Lookup (sudoUser ); err == nil {
91
+ // Set HOME to original user's home directory
92
+ env = append (env , fmt .Sprintf ("HOME=%s" , user .HomeDir ))
93
+ // Set USER to original username
94
+ env = append (env , fmt .Sprintf ("USER=%s" , sudoUser ))
95
+ // Set LOGNAME to original username (some tools check this instead of USER)
96
+ env = append (env , fmt .Sprintf ("LOGNAME=%s" , sudoUser ))
97
+ m .logger .Debug ("Restored user environment" , "home" , user .HomeDir , "user" , sudoUser )
98
+ }
99
+ }
100
+
87
101
cmd .Env = env
88
102
cmd .Stdout = os .Stdout
89
103
cmd .Stderr = os .Stderr
90
104
cmd .Stdin = os .Stdin
91
105
92
- // Set group ID using syscall (like httpjail does)
93
- cmd .SysProcAttr = & syscall.SysProcAttr {
94
- Credential : & syscall.Credential {
95
- Gid : uint32 (m .groupID ),
96
- },
106
+ // Drop privileges to original user if running under sudo
107
+ if sudoUID := os .Getenv ("SUDO_UID" ); sudoUID != "" {
108
+ if sudoGID := os .Getenv ("SUDO_GID" ); sudoGID != "" {
109
+ uid , err := strconv .Atoi (sudoUID )
110
+ if err != nil {
111
+ m .logger .Warn ("Invalid SUDO_UID, subprocess will run as root" , "sudo_uid" , sudoUID , "error" , err )
112
+ } else {
113
+ // Use original user ID but KEEP the jail group for network isolation
114
+ cmd .SysProcAttr = & syscall.SysProcAttr {
115
+ Credential : & syscall.Credential {
116
+ Uid : uint32 (uid ),
117
+ Gid : uint32 (m .groupID ), // Keep jail group, not original user's group
118
+ },
119
+ }
120
+ m .logger .Debug ("Dropping privileges to original user with jail group" , "uid" , uid , "jail_gid" , m .groupID )
121
+ }
122
+ }
123
+ } else {
124
+ // Set group ID using syscall (original behavior for non-sudo)
125
+ cmd .SysProcAttr = & syscall.SysProcAttr {
126
+ Credential : & syscall.Credential {
127
+ Gid : uint32 (m .groupID ),
128
+ },
129
+ }
97
130
}
98
131
99
132
// Start and wait for command to complete
@@ -334,4 +367,4 @@ func (m *MacOSNetJail) cleanupTempFiles() {
334
367
if m .mainRulesPath != "" {
335
368
os .Remove (m .mainRulesPath )
336
369
}
337
- }
370
+ }
0 commit comments