1

我需要在我的主进程中以“nobody”用户身份运行一个子进程,代码如下:

# os.setuid(65534)  # out the set_id work fine!!

logging.warning(f"outside user: {getpass.getuser()}")
# output: outside user: root

def set_id() -> None:
    logging.warning(f"sub !sub! process user id is {os.getuid(), os.getgid(), os.getgroups()}!!!!!!!!!!!!")
    # output: root:sub !sub! process user id is (0, 0, [])!!!!!!!!!!!!
    assert os.getuid() == 0

    logging.warning(f"inside user: {getpass.getuser()}")
    # output: inside user: root

    # os.setgid(65534)  # work fine
    os.setuid(65534)  # can't work

pro = await asyncio.subprocess.create_subprocess_exec(
    # *tmp_cmd,
    "ls",
    stdout=asyncio.subprocess.PIPE,
    stdin=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE,
    cwd=self._cwd,
    preexec_fn=set_id,
    start_new_session=True,
    close_fds=True,
)

当我打电话时os.setuid(65534)引发一个错误 PermissionError: [Errno 13] Permission denied
os.setgid(65534) 工作正常。
额外信息:

  • set_id函数内部,os.getuid(), os.getgid(), os.getgroups()'out 是 (0, 0, [])
  • 外面set_idos.setuid(65534)工作正常。
  • getpass.getuser() == "root"

这就是为什么?我怎样才能解决这个问题?提前致谢。
追溯:

ERROR:uvicorn.error:Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/uvicorn/protocols/websockets/websockets_impl.py", line 153, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/usr/local/lib/python3.7/dist-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/fastapi/applications.py", line 149, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/applications.py", line 102, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/cors.py", line 68, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 550, in __call__
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 283, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 57, in app
    await func(session)
  File "/usr/local/lib/python3.7/dist-packages/fastapi/routing.py", line 209, in app
    await dependant.call(**values)
  File "/opt/MakerServer/app/api/routes/websockets_runner/runner.py", line 21, in wss_back
    process = await WSProcess.create(file_m, ws=websocket)
  File "/opt/MakerServer/app/services/processer.py", line 100, in create
    self.proc: asyncio.subprocess.Process = await self._create_sub_process()  # type: ignore
  File "/opt/MakerServer/app/services/processer.py", line 136, in _create_sub_process
    close_fds=True,
  File "/usr/lib/python3.7/asyncio/subprocess.py", line 217, in create_subprocess_exec
    stderr=stderr, **kwds)
  File "uvloop/loop.pyx", line 2749, in subprocess_exec
  File "uvloop/loop.pyx", line 2707, in __subprocess_run
  File "uvloop/handles/process.pyx", line 596, in uvloop.loop.UVProcessTransport.new
  File "uvloop/handles/process.pyx", line 98, in uvloop.loop.UVProcess._init
PermissionError: [Errno 13] Permission denied

4

1 回答 1

1

这个问题没有提供所有元素,但这是我会看到的:

  • os.setuid无法生成 13 的 errno。来自 的权限错误setuidEPERMerrno 1。
  • 因此,我相信它不是os.setuid产生异常的原因。
  • 我的猜测是,当 Popen 尝试以用户 65534 身份打开某个文件时(它可能是目标可执行文件、某个库或某些配置文件被加载到该行),您的函数返回会生成异常。set_id

如何着手解决这个问题:

  • try catch通过在 .周围添加一个块来确认问题os.setuid。我有 99% 的把握它不会触发。
  • 然后尝试以sunobody 用户身份从shell 运行您的命令。很可能你会得到同样的错误。

您还可以strace -f在程序上使用来查看哪个系统调用失败以及调用它的参数。那应该为您指明正确的方向。

于 2020-05-08T08:42:36.207 回答