safe system(linux)

一个简单的system指令,用于替换系统的system,避免注入,信号等问题

 

// safe_system.c
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>

int safe_system(const char* cmd) {
    // check cmd
    if (strpbrk(cmd, "&|;$`\"'\\*?[]{}<>~#%^")) {
        errno = EINVAL;
        return -1;
    }
    
    pid_t pid = fork();
    if (pid == -1) return -1;
    
    if (pid == 0) {
        // clear env
        extern char** environ;
        char* minimal_env[] = {"PATH=/usr/bin:/bin", NULL};
        environ = minimal_env;
        
        
        execl("/bin/sh", "sh", "-c", cmd, (char*)NULL);
        _exit(126);
    }
        
    sigset_t mask, oldmask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);
    
    int status;
    while (waitpid(pid, &status, 0) == -1) {
        if (errno != EINTR) {
            //waitpid error
            sigprocmask(SIG_SETMASK, &oldmask, NULL);
            return -1;
        }
    }
    
    sigprocmask(SIG_SETMASK, &oldmask, NULL);
    if (WIFEXITED(status)) { 
        int code = WEXITSTATUS(status);        
        if (code == 126 || code == 127) {
            errno = (code == 126) ? ENOEXEC : ENOENT;
            return -1;
        } else if (code != 0) {
            // application error(all) return -1
            errno = EIO;
            return -1;
        }
    } else if (WIFSIGNALED(status)) {
        // SIGNALED INTR
        errno = EINTR;
        return -1;
    } else {
        errno = EIO;
        return -1;
    }
    
    return status;
}

 

posted @ 2025-11-19 11:21  sciapex  阅读(8)  评论(0)    收藏  举报