当为可执行文件设置set-user-ID时,`exec`如何以及何时更改有效用户ID

时间:2017-01-04 04:29:25

标签: linux unix system-calls

我的问题来自阅读APUE。

在Unix或Linux中,当进程通过调用exec函数执行可执行文件时,如果为可执行文件设置了set-user-ID位,exec将更改有效用户ID到文件的所有者。

  1. exec如何更改有效用户ID?

    exec是通过调用setuid还是通过其他功能进行更改?

  2. exec何时更改有效用户ID?

    exec是否会改变效果 内核执行之前 > 之前的进程的用户ID 是否允许执行进程的权限测试 文件?

    等同于上面的问题,在内核执行权限测试之前是否正确 允许进程执行文件,是有效的ID 处理之前的 之后 <{strong> exec更改效果 用户ID到文件的所有者?

  3. 感谢。

2 个答案:

答案 0 :(得分:2)

根据维基百科https://en.wikipedia.org/wiki/Setuid

  1. 我认为(不确定)没有明确涉及其他系统调用;但是exec()可能会对setuid代码进行内部调用。

  2. exec()在决定可以执行文件后更改有效用户ID 。否则,这将是无意义的。

答案 1 :(得分:2)

我将在这里报道UNIX V7。有几十个版本的UNIX,但它们的exec实现非常相似。

有效uid是per-process user structure中的字段,与process structure中的类似字段保持同步。在V7中,使用两个简单的赋值语句来更改有效uid:

/*
 * set SUID/SGID protections, if no tracing
 */
if ((u.u_procp->p_flag&STRC)==0) {
    if(ip->i_mode&ISUID)
        if(u.u_uid != 0) {
            u.u_uid = ip->i_uid;
            u.u_procp->p_uid = ip->i_uid;
        }
    if(ip->i_mode&ISGID)
        u.u_gid = ip->i_gid;
}

[练习:对(u.u_uid != 0)的检查结束了什么,以及为什么在后续版本的UNIX中从exec代码中删除了它?]

exec做的第一件事就是通过调用access来检查权限,if ((ip = namei(uchar, 0)) == NULL) return; if(access(ip, IEXEC)) goto bad; 使用进程的有效uid和gid。它甚至在查看文件的setuid位之前就已经这么做了。

/*
 * allocate and clear core
 * at this point, committed
 * to the new image
 */

uid更改在完成所有权限和幻数检查以及内存分配完成后完成。正如代码在分配和uid设置之前不久所说:

<?php
if(isset($_POST["loginbtn"])) {
  $u=$_POST['uname'];
  $p=$_POST['pword'];

  $conn=new mysqli("localhost", "root", "" , "M3_156020K_Syahri_SportFacility");
  $sql = "SELECT `role` FROM create_user WHERE username=? AND password=?";
  $stmt = $conn->prepare($sql);
  $stmt->bind_param('ss', $u, $p);
  $stmt->execute();
  $stmt->bind_result($role);
  $stmt->close();
  $conn->close();
  if($role) {
       session_start();
       $_SESSION['MM_Username']= $u; 
       if($role == 'Admin') {
           header("Location: login_admin.html");
       } else {
           header("Location: login_cust.html");
       }
  } else {
       header("Location: signin.html?uname=" . $u . "&pword=" . $p);
  }
  mysqli_close($conn);  
}
?><!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Check Login</title>
</head>

<body>