Skip to content

Commit 0b95793

Browse files
Kenoclaude
andcommitted
Fix Libc.getpwuid usage and use addenv for environment variables
- Fix Libc.getpwuid to use UInt conversion for the uid parameter - Use addenv instead of command interpolation for setting PATH and HOME - Properly retrieve user home directory from Libc.Passwd object 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 89983c2 commit 0b95793

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

src/tools/bash.jl

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,17 @@ Bash command execution tool for MCP
44

55
# Helper function to get user's home directory using getpwuid
66
function get_user_home(uid::Int)
7-
# Use Libc.getpwuid to get user info
8-
passwd = Libc.getpwuid(uid)
7+
# Use Libc.getpwuid to get user info - it returns a Libc.Passwd object or nothing
8+
# Convert to UInt as getpwuid expects unsigned
9+
passwd_info = Libc.getpwuid(UInt(uid))
910

10-
if passwd == C_NULL
11+
if passwd_info === nothing
1112
# Failed to get user info, return nothing
1213
return nothing
1314
end
1415

15-
# Extract home directory from the passwd struct
16-
# The Libc.Passwd struct has the homedir field
17-
pwd = unsafe_load(passwd)
18-
19-
if pwd.homedir == C_NULL
20-
return nothing
21-
end
22-
23-
return unsafe_string(pwd.homedir)
16+
# Libc.getpwuid returns a Libc.Passwd object with homedir field already as a string
17+
return passwd_info.homedir
2418
end
2519

2620
mutable struct BashTool <: MCPTool
@@ -78,19 +72,24 @@ function execute(tool::BashTool, params::Dict)
7872
# Get target user's home directory
7973
user_home = get_user_home(tool.uid)
8074

81-
# Build environment variables to set
82-
env_vars = ["PATH=$current_path"]
75+
# Build the sudo command
76+
# -E: preserve environment variables (but PATH and HOME are still reset by sudo)
77+
# -u #uid: run as the specified UID (# prefix tells sudo it's a UID not username)
78+
# sh -c: use shell to run the command
79+
cmd = Cmd(`sudo -E -u "#$(tool.uid)" sh -c $command`, ignorestatus=true, dir=tool.working_dir)
80+
81+
# Add environment variables that sudo resets
82+
# Since sudo passes through -E, we can use addenv to set them
83+
env_dict = Dict{String,String}()
84+
env_dict["PATH"] = current_path
8385
if user_home !== nothing
84-
push!(env_vars, "HOME=$user_home")
86+
env_dict["HOME"] = user_home
8587
end
86-
env_str = join(env_vars, " ")
8788

88-
# Use sudo to switch to the specified uid
89-
# -E: preserve environment variables (but PATH and HOME are still reset by sudo)
90-
# -u #uid: run as the specified UID (# prefix tells sudo it's a UID not username)
91-
# env PATH=... HOME=...: explicitly restore PATH and HOME inside sudo
92-
# Note: This requires the process to have appropriate permissions
93-
cmd = Cmd(`sudo -E -u "#$(tool.uid)" env $env_str sh -c $command`, ignorestatus=true, dir=tool.working_dir)
89+
# Apply environment variables
90+
if !isempty(env_dict)
91+
cmd = addenv(cmd, env_dict)
92+
end
9493
else
9594
# Use Cmd with ignorestatus to capture all output regardless of exit code
9695
cmd = Cmd(`sh -c $command`, ignorestatus=true, dir=tool.working_dir)

0 commit comments

Comments
 (0)