首页 > 解决方案 > os.openpty() Operation not permitted after os.seteuid() from root to a user

问题描述

If we seteuid(123) from root to user 123, it will fail. However to run os.openpty() directly as user 123, it will be successful. Any hints?

Same in both python 2.7 or 3.6. On Redhat 7:

>>> os.openpty()
(3, 4)
>>> os.seteuid(12345)
>>> os.openpty()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
PermissionError: [Errno 1] Operation not permitted

标签: pythonlinuxpty

解决方案


strace输出(最好使用 C 版本):

setresuid(-1, 123, -1)                  = 0
open("/dev/ptmx", O_RDWR)               = 3
statfs("/dev/pts", {f_type=DEVPTS_SUPER_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_NOSUID|ST_NOEXEC|ST_RELATIME}) = 0
ioctl(3, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, TIOCGPTN, [6])                 = 0
stat("/dev/pts/6", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 6), ...}) = 0
getuid()                                = 0
chown("/dev/pts/6", 0, 5)               = -1 EPERM (Operation not permitted)
close(3)                                = 0

由于geteuid()不再是 root,因此无法将 TTY 更改为getuid().

您的选择是:

  • 更改 UID,而不仅仅是 EUID
  • openpty在通话前立即重置 EUID ,chown自己重置,然后再次更改 EUID
  • 实现openpty自己...在 Linux 上这非常简单(您不需要可怕的 BSD 后备)...您需要多便携?

推荐阅读