[英]Permission denied with os.setuid() in uvloop
I need to run a subprocess in my main process as "nobody" user, code like this:我需要在我的主进程中以“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,
)
When I call os.setuid(65534)
, raise an error PermissionError: [Errno 13] Permission denied
.当我调用os.setuid(65534)
时,引发错误PermissionError: [Errno 13] Permission denied
。
But os.setgid(65534)
work fine.但是os.setgid(65534)
工作正常。
Extra info:额外信息:
set_id
function, os.getuid(), os.getgid(), os.getgroups()
's out is (0, 0, [])
在set_id
function 里面, os.getuid(), os.getgid(), os.getgroups()
的出来是(0, 0, [])
set_id
, os.setuid(65534)
work fine.在set_id
之外, os.setuid(65534)
工作正常。getpass.getuser() == "root"
That's why?这就是为什么? How can I fix this?我怎样才能解决这个问题? Thanks in advance.提前致谢。
Traceback:追溯:
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
The question does not provide all the elements, but here is what I would see:这个问题没有提供所有元素,但这是我会看到的:
os.setuid
cannot generate an errno of 13. A permission error from setuid
would be EPERM
, which is errno 1. os.setuid
无法生成 13 的 errno。来自setuid
的权限错误将是EPERM
,即 errno 1。os.setuid
that generates the exception.因此,我相信不是os.setuid
会产生异常。set_id
function returns, when Popen tries to open some file as user 65534 (it could be the target executable, some library or some config file that gets loaded down the line).我的猜测是在您的set_id
function 返回后生成异常,当 Popen 尝试以用户 65534 身份打开某个文件(它可能是目标可执行文件、某个库或某个配置文件被加载到该行)。How to proceed to solve this:如何着手解决这个问题:
try
catch
block around os.setuid
.通过在os.setuid
周围添加try
catch
块来确认问题。 I'm 99% sure it won't trigger.我有 99% 的把握它不会触发。su
as nobody user.然后尝试从 shell 以su
为无人用户运行您的命令。 Most likely you'll get the same error.很可能你会得到同样的错误。 You can also use strace -f
on your program to see which system call fails and what parameters it is invoked with.您还可以在程序上使用strace -f
来查看哪个系统调用失败以及调用它的参数。 That should point you in the right direction.那应该为您指明正确的方向。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.