macos 10 setuid无缘无故失败

时间:2014-12-16 16:11:27

标签: macos setuid

我正在运行此代码来更改真正的uid(如果进程:

#include <cstdlib>
#include <cstdio>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>

void printstat()
{
    printf("uid: %d, euid: %d\n",getuid(),geteuid());
}

int main(int argc, char** argv)
{
    if (argc < 2)
    {
            return -1;
    }
    int m_targetUid = atoi(argv[1]);
    printstat();
    uid_t realUID = getuid();
    printf("Setting effective uid to %d\n",m_targetUid);
    seteuid(m_targetUid);
    printstat();
    if (m_targetUid != realUID)
    {
            printf("Setting real uid to %d\n",m_targetUid);
            int res = setuid(m_targetUid);
            printf("setuid(%d) returned: %d\n",m_targetUid,res);
            if (0 > setuid(m_targetUid))
            {
                    printf("setuid(%d) failed: %d, getuid() returned %d, geteuid returned %d\n",m_targetUid,errno,realUID,geteuid());
                    exit(-1);
            }
    }
}

根据手册页,如果有效用户标识等于指定的uid,则setuid functino不会失败,但由于某种原因,它会失败。任何想法?

手册页:

    The setuid() function sets the real and effective user IDs and the saved set-user-ID of the current process to the specified value.  The setuid() function is permitted if the effective user ID is that of the
    super user, or if the specified user ID is the same as the effective user ID.  If not, but the specified user ID is the same as the real user ID, setuid() will set the effective user ID to the real user ID.

这是我以root身份运行时的输出:

nnlnb-mm-041: root# /tmp/setuidBug 70
uid: 0, euid: 0
Setting effective uid to 70
uid: 0, euid: 70
Setting real uid to 70
setuid(70) returned: -1
setuid(70) failed: 1, getuid() returned 0, geteuid returned 70

1 个答案:

答案 0 :(得分:0)

我终于设法解决了它,显然在macos中你必须将有效的uid设置回root才能工作。代码如下。

#include <cstdlib>
#include <cstdio>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>

void printstat()
{
    printf("uid: %d, euid: %d\n",getuid(),geteuid());
}

int main(int argc, char** argv)
{
    if (argc < 2)
    {
            return -1;
    }
    int m_targetUid = atoi(argv[1]);
    printstat();
    uid_t realUID = getuid();
    printf("Setting effective uid to %d\n",m_targetUid);
    seteuid(m_targetUid);
    printstat();
    printf("Setting effective uid to 0\n");
    seteuid(0);
    printstat();
    if (m_targetUid != realUID)
    {
            printf("Setting real uid to %d\n",m_targetUid);
            int res = setuid(m_targetUid);
            printf("setuid(%d) returned: %d\n",m_targetUid,res);
            if (0 > setuid(m_targetUid))
            {
                    printf("setuid(%d) failed: %d, getuid() returned %d, geteuid returned     %d\n",m_targetUid,errno,realUID,geteuid());
                    exit(-1);
            }
    }
    printstat();
}

现在的输出是:

    uid: 0, euid: 0
    Setting effective uid to 70
    uid: 0, euid: 70
    Setting effective uid to 0
    uid: 0, euid: 0
    Setting real uid to 70
    setuid(70) returned: 0
    uid: 70, euid: 70