root priv は、seteuid の後でも Python にドロップできません。バグ?
編集の要約: gid をドロップするのを忘れていました。ただし、受け入れられた回答が役立つ場合があります。
やあ。Linux の Python 3.2 で root 権限を削除できません。実際、seteuid(1000) の後でも、root 所有の 400 モード ファイルを読み取ることができます。euid は確実に 1000 に設定されています。
空の os.fork() 呼び出しの後に、特権アクセスが正しく拒否されていることがわかりました。(しかし、それは親だけです。子供はまだ違法に読むことができます。)それはPythonのバグですか、それともLinuxのバグですか?
以下のコードを試してください。一番下の 3 行のうちの 1 行をコメントアウトし、root として実行します。
事前に感謝します。
#!/usr/bin/python3
# Python seteuid pitfall example.
# Run this __as__ the root.
# Here, access to root-owned files /etc/sudoers and /etc/group- are tried.
# Simple access to them *succeeds* even after seteuid(1000) which should fail.
# Three functions, stillRoot(), forkCase() and workAround() are defined.
# The first two seem wrong. In the last one, access fails, as desired.
# ***Comment out*** one of three lines at the bottom before execution.
# If your python is < 3.2, comment out the entire def of forkCase()
import os
def stillRoot():
"""Open succeeds, but it should fail."""
os.seteuid(1000)
open('/etc/sudoers').close()
def forkCase():
"""Child can still open it. Wow."""
# setresuid needs python 3.2
os.setresuid(1000, 1000, 0)
pid = os.fork()
if pid == 0:
# They're surely 1000, not 0!
print('uid: ', os.getuid(), 'euid: ', os.geteuid())
open('/etc/sudoers').close()
print('open succeeded in child.')
exit()
else:
print('child pid: ', pid)
open('/etc/group-').close()
print('parent succeeded to open.')
def workAround():
"""So, a dummy fork after seteuid is necessary?"""
os.seteuid(1000)
pid = os.fork()
if pid == 0:
exit(0)
else:
os.wait()
open('/etc/group-').close()
## Run one of them.
# stillRoot()
# forkCase()
# workAround()