Setuid-bit和apt-get奇怪的行为

时间:2015-10-29 18:30:07

标签: c apt-get setuid

我的覆盆子pi有一种奇怪的行为。

我写了一个小型C程序来更新RPi。 它只需通过system()" apt-get update&& apt-get dist-upgrade&& apt-get upgrade&& rpi-update&&重启"

使用setuid-bit,程序将以root身份运行。

为什么选择c程序?因为setuid-bit不适用于bash脚本。

作为超级用户,没有问题。

如果我以普通用户身份运行程序,那么在" apt-get update"之后我就会收到此错误。 (对不起德语版):

 E: Unable to write to /var/cache/apt/               
E: The package lists or status file could not be parsed or opened.

setuid-bit已设置且可执行文件的所有者为root。 那为什么我有另一种行为呢?

以下是代码:

main.c中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {
        int status = 0;

        if (status == 0) {
                status = system("apt-get -y update");        }

        if (status == 0) {
                status = system("apt-get -y dist-upgrade");
}
        if (status == 0) {
                status = system("apt-get -y upgrade");
        }

        if (status == 0) {
                status = system("rpi-update");
        }

        if (status == 0) {
                status = system("reboot");
        }
        return status;
}

生成文件:

CC=gcc
TARGET=update-system
PREFIX=/usr/bin

all: main.o
        ${CC} -o ${TARGET} main.c
        make clean

main.o: main.c
        ${CC} -c main.c

.PHONY: clean
clean:
        rm ./*.o 
install:
        chown root ${TARGET} 
        chgrp root ${TARGET} 
        chmod +s ${TARGET}
        mv ${TARGET} ${PREFIX}

2 个答案:

答案 0 :(得分:2)

当您的程序运行时,有效用户ID为root,但真实用户ID是您自己。然后,当您致电system时,真实有效的用户ID将由apt-get继承。

apt-get似乎在检查权限时查看真实用户ID。因此,您需要在main

的开头将实际用户ID设置为root
setuid(0);

话虽这么说,使用sudo比运行setuid-root程序更安全,因为你可以控制谁有权这样做。

答案 1 :(得分:0)

你需要sudo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void) {
    int status = 0;

    if (status == 0) {
        status = system("sudo apt-get -y update");        }

    if (status == 0) {
        status = system("sudo apt-get -y dist-upgrade");
    }

    if (status == 0) {
        status = system("sudo apt-get -y upgrade");
    }

    if (status == 0) {
        status = system("sudo rpi-update");
    }

    if (status == 0) {
        status = system("sudo reboot");
    }
    return status;
}

确保用户具有root权限。