簡體   English   中英

setuid程序在2.6內核上不起作用

[英]setuid program doesn't work on 2.6 kernel

我很難理解為什么我的setuid程序看起來好像實際上沒有提升權限,即使id似乎正確也是如此。 它在2.6內核上運行並失敗,但是完全可以在Ubuntu 14.04上完成相同的工作。 我需要一個程序,該程序在執行過程中的某些時候需要提升的權限,而默認權限是最低權限。

#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

static uid_t _orig_euid;

void save_privilege(void){
    _orig_euid = geteuid();
    printf("saved privilege: %d\n", _orig_euid);
}

void drop_privileges(void){
    if(seteuid(getuid()) == -1){
        exit(0);
    }
    printf("dropped privileges %d %d\n", getuid(), geteuid());
}

void reacquire_privileges(void){
    if(setuid(_orig_euid) == -1){
        exit(0);
    }
    printf("reacquired privileges %d %d\n", getuid(), geteuid());
}

void do_privileged(int rw){
    switch(rw){
        case 0:
            //read from driver
            system("dd if=/dev/myrandom bs=10 count=1");
        case 1:
            //write to driver
            system("dd if=/dev/zero of=/dev/myrandom");
        case 2:
            //change something in proc fs
            system("echo 3 > /proc/sys/vm/drop_caches");
        default:
            break;
    }
}

int main(int argc, char *argv[]){
    int i;

    if(argc != 2){
        printf("usage: %s testno\n", argv[0]);
        return 0;
    }

    i = atoi(argv[1]);

    save_privilege();

    do_privileged(i);

    drop_privileges();

    do_privileged(i);

    reacquire_privileges();

    do_privileged(i);

    return 0;
}

我的程序權限設置為:

ls -l
-rwsr-xr-x    1 root     root         6547 Sep 13 00:35 test

我當前的用戶ID是:

id
uid=1000(user) gid=1000(user)

我要寫的procfs條目是:

ls -l /proc/sys/vm/drop_caches
-rw-r--r--    1 root     root            0 Sep 13 00:36 /proc/sys/vm/drop_caches

運行程序時,我得到:

./test 2
saved privilege: 0
sh: cannot create /proc/sys/vm/drop_caches: Permission denied
dropped privileges 1000 1000
sh: cannot create /proc/sys/vm/drop_caches: Permission denied
reacquired privileges 1000 0
sh: cannot create /proc/sys/vm/drop_caches: Permission denied

但是,在Ubuntu 14.04上運行相同的程序可以正常工作-只有在刪除特權后,它才能修改procfs條目。

這是一個strace(./test_perm與./test相同)。

$ strace ./test_perm 2
execve("./test_perm", ["./test_perm", "2"], [/* 8 vars */]) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x40005000
open("/lib/libc.so.0", O_RDONLY)        = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=310348, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x40006000
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\260\256\0\0004\0\0\0"..., 4096) = 4096
mmap2(NULL, 360448, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4000e000
mmap2(0x4000e000, 303968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x4000e000
mmap2(0x40060000, 4972, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x4a) = 0x40060000
mmap2(0x40062000, 15112, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40062000
close(3)                                = 0
munmap(0x40006000, 4096)                = 0
stat("/lib/ld-uClibc.so.0", {st_mode=S_IFREG|0755, st_size=21200, ...}) = 0
mprotect(0x40060000, 4096, PROT_READ)   = 0
mprotect(0x4000c000, 4096, PROT_READ)   = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
geteuid32()                             = 1000
write(1, "saved privilege: 1000\n", 22saved privilege: 1000
) = 22
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [], 0}, 8) = 0
vfork(sh: cannot create /proc/sys/vm/drop_caches: Permission denied
)                                 = 1183
--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
wait4(1183, [{WIFEXITED(s) && WEXITSTATUS(s) == 2}], 0, NULL) = 1183
rt_sigaction(SIGQUIT, {SIG_DFL, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, 8) = 0
getuid32()                              = 1000
setresuid32(-1, 1000, -1)               = 0
getuid32()                              = 1000
geteuid32()                             = 1000
write(1, "dropped privileges 1000 1000\n", 29dropped privileges 1000 1000
) = 29
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_DFL, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_DFL, [INT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, 8) = 0
vfork(sh: cannot create /proc/sys/vm/drop_caches: Permission denied
)                                 = 1184
--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
wait4(1184, [{WIFEXITED(s) && WEXITSTATUS(s) == 2}], 0, NULL) = 1184
rt_sigaction(SIGQUIT, {SIG_DFL, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, 8) = 0
setuid32(1000)                          = 0
getuid32()                              = 1000
geteuid32()                             = 1000
write(1, "reacquired privileges 1000 1000\n", 32reacquired privileges 1000 1000
) = 32
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_DFL, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_DFL, [INT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, 8) = 0
vfork(sh: cannot create /proc/sys/vm/drop_caches: Permission denied
)                                 = 1185
--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
wait4(1185, [{WIFEXITED(s) && WEXITSTATUS(s) == 2}], 0, NULL) = 1185
rt_sigaction(SIGQUIT, {SIG_DFL, [QUIT], SA_RESTART|0x4000000}, {SIG_IGN, [QUIT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [INT], SA_RESTART|0x4000000}, {SIG_IGN, [INT], SA_RESTART|0x4000000}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, {SIG_DFL, [CHLD], SA_RESTART|0x4000000}, 8) = 0
exit(0)                                 = ?

在strace下調用程序會導致setuid位被忽略。

您嘗試使用ruid ==調用用戶ID來運行setuid二進制文件。 這不是很好。 但是,這似乎也不是您的主要問題。

永遠不要從setuid程序中調用system(),否則有人會執行SHELL=/tmp/evil your_setuid_program並擁有早餐的根源。

我什至要弄清楚您實際上在做什么錯,這會導致setuid位對您不起作用,因為您顯然不知道如何編寫setuid二進制文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM