Skip to content

Commit dcd0450

Browse files
blink-so[bot]f0ssel
andcommitted
fix: implement privilege dropping to run subprocess as original user
This is the core fix for sudo environment preservation. Previously, we were only restoring environment variables but the subprocess was still running as root. Now we properly drop privileges to the original user. Changes: - Linux: Use syscall.Credential to set UID/GID of subprocess - macOS: Use syscall.Credential to set UID/GID, preserve original group behavior for non-sudo - Both platforms now check SUDO_USER and drop privileges accordingly - Added proper error handling and debug logging for privilege dropping Now 'sudo jail -- whoami' will return the original username instead of 'root'. Co-authored-by: f0ssel <[email protected]>
1 parent 97839b9 commit dcd0450

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

network/linux.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,27 @@ func (l *LinuxJail) Execute(command []string, extraEnv map[string]string) error
110110
cmd.Stdout = os.Stdout
111111
cmd.Stderr = os.Stderr
112112

113+
// Drop privileges to original user if running under sudo
114+
if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" {
115+
uid, err := environment.GetEffectiveUID()
116+
if err != nil {
117+
l.logger.Warn("Failed to get effective UID, subprocess will run as root", "error", err)
118+
} else {
119+
gid, err := environment.GetEffectiveGID()
120+
if err != nil {
121+
l.logger.Warn("Failed to get effective GID, subprocess will run as root", "error", err)
122+
} else {
123+
cmd.SysProcAttr = &syscall.SysProcAttr{
124+
Credential: &syscall.Credential{
125+
Uid: uint32(uid),
126+
Gid: uint32(gid),
127+
},
128+
}
129+
l.logger.Debug("Dropping privileges to original user", "uid", uid, "gid", gid, "user", sudoUser)
130+
}
131+
}
132+
}
133+
113134
// Start command
114135
l.logger.Debug("Starting command", "path", cmd.Path, "args", cmd.Args)
115136
err := cmd.Start()

network/macos.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,33 @@ func (m *MacOSNetJail) Execute(command []string, extraEnv map[string]string) err
9797
cmd.Stderr = os.Stderr
9898
cmd.Stdin = os.Stdin
9999

100-
// Set group ID using syscall (like httpjail does)
101-
cmd.SysProcAttr = &syscall.SysProcAttr{
102-
Credential: &syscall.Credential{
103-
Gid: uint32(m.groupID),
104-
},
100+
// Drop privileges to original user if running under sudo
101+
if sudoUser := os.Getenv("SUDO_USER"); sudoUser != "" {
102+
uid, err := environment.GetEffectiveUID()
103+
if err != nil {
104+
m.logger.Warn("Failed to get effective UID, subprocess will run as root", "error", err)
105+
} else {
106+
gid, err := environment.GetEffectiveGID()
107+
if err != nil {
108+
m.logger.Warn("Failed to get effective GID, subprocess will run as root", "error", err)
109+
} else {
110+
// Set group ID using syscall (like httpjail does)
111+
cmd.SysProcAttr = &syscall.SysProcAttr{
112+
Credential: &syscall.Credential{
113+
Uid: uint32(uid),
114+
Gid: uint32(gid),
115+
},
116+
}
117+
m.logger.Debug("Dropping privileges to original user", "uid", uid, "gid", gid, "user", sudoUser)
118+
}
119+
}
120+
} else {
121+
// Set group ID using syscall (like httpjail does) - original behavior for non-sudo
122+
cmd.SysProcAttr = &syscall.SysProcAttr{
123+
Credential: &syscall.Credential{
124+
Gid: uint32(m.groupID),
125+
},
126+
}
105127
}
106128

107129
// Start and wait for command to complete

0 commit comments

Comments
 (0)