sudo源码分析(二)

本篇主要分析sudo的信号处理函数。

首先回顾下上篇博客分析的sudo执行的5个步骤:

  1. 修改信号处理函数:保存原来的信号处理函数,设置新的信号处理函数
  2. 调用setuid将实际用户设置为ROOT
  3. 恢复信号处理函数
  4. 设置用户程序指定的权限(默认ROOT),并设置其他运行环境参数
  5. 调用execve执行用户程序
将信号相关的部分单独列出来就是这样:
    (void) sigemptyset(&mask);
    (void) sigprocmask(SIG_SETMASK, &mask, NULL);
    save_signals();
    // do something check and prepare
    init_signals();
    // setuid(ROOT_ID);
    restore_signals();
    // seteuid and exec
除了一开始将所有信号都设置为非阻塞状态,主要就是save_signals()、init_signals()和restore_signals()三个函数,在分析这三个函数之前我们需要先了解一个数组:
static struct signal_state {
    int signo;
    int restore;
    sigaction_t sa;
} saved_signals[] = {
    { SIGALRM },    /* SAVED_SIGALRM */
    { SIGCHLD },    /* SAVED_SIGCHLD */
    { SIGCONT },    /* SAVED_SIGCONT */
    { SIGHUP },     /* SAVED_SIGHUP */
    { SIGINT },     /* SAVED_SIGINT */
    { SIGPIPE },    /* SAVED_SIGPIPE */
    { SIGQUIT },    /* SAVED_SIGQUIT */
    { SIGTERM },    /* SAVED_SIGTERM */
    { SIGTSTP },    /* SAVED_SIGTSTP */
    { SIGTTIN },    /* SAVED_SIGTTIN */
    { SIGTTOU },    /* SAVED_SIGTTOU */
    { SIGUSR1 },    /* SAVED_SIGUSR1 */
    { SIGUSR2 },    /* SAVED_SIGUSR2 */
    { -1 }
};
这个saved_signals数组保存了sudo在调用execve之前需要修改的信号处理函数。save_signals将上述信号的信号处理函数保存到数组中,restore_signals将保存的信号处理函数恢复。这个数组的每个元素是一个signal_state结构体,这个结构体包含信号值,该信号处理函数是否需要被恢复,以及一个sigaction_t变量。

首先看下save_signals函数,这个函数很简单,就是将saved_signals中初始化了的信号的信号处理函数取出并保存。将sigaction函数的第二个参数设置为NULL,就能在地撒个参数中得到对应信号的信号处理函数。
void
save_signals(void)
{
    struct signal_state *ss;
    debug_decl(save_signals, SUDO_DEBUG_MAIN)

    for (ss = saved_signals; ss->signo != -1; ss++) {
    if (sigaction(ss->signo, NULL, &ss->sa) != 0)
        sudo_warn(U_("unable to save handler for signal %d"), ss->signo);
    }

    debug_return;
}
然后是init_signals函数,这个函数首先创建一个非阻塞的管道(用处后面会说),然后将saved_signals中的信号的信号处理函数设置为sudo_handler,信号处理函数被调用时将阻塞所有信号以防函数重入,而且这些信号并不会中断系统的某些阻塞调用(flags=SA_RESTART)。另外,五个信号(SIGCHLD、SIGCONT、SIGPIPE、SIGTTIN和SIGTTOU)不设置新的信号处理函数,这几个信号的信号处理会在后面其他地方根据不同的需要进行设置。
void
init_signals(void)
{
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值