最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

linux - Why Does User ID Remain 65534 When Using Clone to Create a New User Namespace in Python Script? - Stack Overflow

programmeradmin1浏览0评论

I am trying to create a new user namespace using a Python script that utilizes the clone system call. My goal is to map the user ID of a newly spawned shell to a specific value, similar to how it's done with the unshare command.

When I run unshare --user sh, I can successfully update the UID mappings via:

echo '0 502 1' > /proc/[PID]/uid_map
echo '0 502 1' > /proc/[PID]/gid_map

After doing this, running id in the new shell shows the user as root.

However, when I attempt to do the same in a Python script using libc.clone, the shell still reports the user ID as 65534 (nobody) even after updating the UID and GID mappings. Here is my script:

import signal
import os
import ctypes
import sys

CLONE_NEWUTS = 0x04000000
CLONE_NEWUSER = 0x10000000

def write_file(path, content):
    try:
        with open(path, "w") as f:
            f.write(content)
    except Exception as e:
        sys.exit(f"[Error] Failed to write mapping {content} to {path}: {e}")

def child_func():
    input("...>")
    os.execlp("bash", "sh")  # Start a new shell

libc = ctypes.CDLL("libc.so.6", use_errno=True)
STACK_SIZE = 1024 * 1024
stack = ctypes.create_string_buffer(STACK_SIZE)

child_stack = ctypes.c_void_p(ctypes.addressof(stack) + STACK_SIZE)
pid = libc.clone(
    ctypes.CFUNCTYPE(ctypes.c_int)(child_func),
    child_stack,
    CLONE_NEWUTS | CLONE_NEWUSER | signal.SIGCHLD,
)

if pid == -1:
    sys.exit("Failed to create new namespace")

print(pid)
write_file(f"/proc/{pid}/setgroups", "deny\n")
write_file(f"/proc/{pid}/uid_map", f"0 502 1\n")
write_file(f"/proc/{pid}/gid_map", f"0 502 1\n")

os.waitpid(pid, 0)

What I have checked:

  • The script is executed with root privileges.
  • The UID and GID mapping files are updated after the clone call.

Despite these steps, the user inside the namespace remains nobody. What might I be missing? Any advice or insights would be appreciated.

I am trying to create a new user namespace using a Python script that utilizes the clone system call. My goal is to map the user ID of a newly spawned shell to a specific value, similar to how it's done with the unshare command.

When I run unshare --user sh, I can successfully update the UID mappings via:

echo '0 502 1' > /proc/[PID]/uid_map
echo '0 502 1' > /proc/[PID]/gid_map

After doing this, running id in the new shell shows the user as root.

However, when I attempt to do the same in a Python script using libc.clone, the shell still reports the user ID as 65534 (nobody) even after updating the UID and GID mappings. Here is my script:

import signal
import os
import ctypes
import sys

CLONE_NEWUTS = 0x04000000
CLONE_NEWUSER = 0x10000000

def write_file(path, content):
    try:
        with open(path, "w") as f:
            f.write(content)
    except Exception as e:
        sys.exit(f"[Error] Failed to write mapping {content} to {path}: {e}")

def child_func():
    input("...>")
    os.execlp("bash", "sh")  # Start a new shell

libc = ctypes.CDLL("libc.so.6", use_errno=True)
STACK_SIZE = 1024 * 1024
stack = ctypes.create_string_buffer(STACK_SIZE)

child_stack = ctypes.c_void_p(ctypes.addressof(stack) + STACK_SIZE)
pid = libc.clone(
    ctypes.CFUNCTYPE(ctypes.c_int)(child_func),
    child_stack,
    CLONE_NEWUTS | CLONE_NEWUSER | signal.SIGCHLD,
)

if pid == -1:
    sys.exit("Failed to create new namespace")

print(pid)
write_file(f"/proc/{pid}/setgroups", "deny\n")
write_file(f"/proc/{pid}/uid_map", f"0 502 1\n")
write_file(f"/proc/{pid}/gid_map", f"0 502 1\n")

os.waitpid(pid, 0)

What I have checked:

  • The script is executed with root privileges.
  • The UID and GID mapping files are updated after the clone call.

Despite these steps, the user inside the namespace remains nobody. What might I be missing? Any advice or insights would be appreciated.

Share Improve this question asked Feb 6 at 8:01 AoldguyAoldguy 111 silver badge1 bronze badge New contributor Aoldguy is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 0

The issue you're encountering lies in the timing of when the uid_map and gid_map are written in relation to the child process and its execution within the new user namespace. In your script, the mapping files are written after the clone system call is made, which means the new child process isn't aware of those mappings at the time it starts.

To solve this issue, the uid_map and gid_map should be written before the child process is executed inside the new user namespace. This ensures that the mappings are already set up by the time the child process is started.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论