os.openpty() 在 os.seteuid() 之后不允许从 root 到用户的操作
os.openpty() Operation not permitted after os.seteuid() from root to a user
如果我们seteuid(123) 从root 到用户123,它将失败。但是直接以用户123的身份运行 os.openpty(),就可以成功了。有什么提示吗?
在 python 2.7 或 3.6 中相同。在 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
来自 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 后备) ... 您需要多便携?
如果我们seteuid(123) 从root 到用户123,它将失败。但是直接以用户123的身份运行 os.openpty(),就可以成功了。有什么提示吗?
在 python 2.7 或 3.6 中相同。在 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
来自 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 后备) ... 您需要多便携?