浏览代码

make sure privileges cannot be restored after setuid

Ask Solem 12 年之前
父节点
当前提交
eccbdb733e
共有 1 个文件被更改,包括 16 次插入0 次删除
  1. 16 0
      celery/platforms.py

+ 16 - 0
celery/platforms.py

@@ -504,11 +504,27 @@ def maybe_drop_privileges(uid=None, gid=None):
             gid = pwd.getpwuid(uid).pw_gid
             gid = pwd.getpwuid(uid).pw_gid
         # Must set the GID before initgroups(), as setgid()
         # Must set the GID before initgroups(), as setgid()
         # is known to zap the group list on some platforms.
         # is known to zap the group list on some platforms.
+
+        # setgid must happen before setuid (otherwise the setgid operation
+        # may fail because of insufficient privileges and possibly stay
+        # in a privileged group).
         setgid(gid)
         setgid(gid)
         initgroups(uid, gid)
         initgroups(uid, gid)
 
 
         # at last:
         # at last:
         setuid(uid)
         setuid(uid)
+        # ... and make sure privileges cannot be restored:
+        try:
+            setuid(0)
+        except OSError:
+            if get_errno(exc) != errno.EPERM:
+                raise
+            pass  # Can not restore privileges.
+        else:
+            if uid:
+                raise RuntimeError(
+                    'non-root user able to restore privileges after setuid.')
+
     else:
     else:
         gid and setgid(gid)
         gid and setgid(gid)