Какова цель uint64_t ps_pledge varibale в коде ядра OpenBSD?

Я играю с кодом ядра OpenBSD, особенно с этим файлом sys/kern/sched_bsd.c.

    void
    schedcpu(void *arg)
    {
......

......

    LIST_FOREACH(p, &allproc, p_list) {
        /*
         * Increment sleep time (if sleeping). We ignore overflow.
         */
        if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
            p->p_slptime++;
        p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT;
        /*
         * If the process has slept the entire second,
         * stop recalculating its priority until it wakes up.
         */
        if (p->p_slptime > 1)
            continue;
        SCHED_LOCK(s);
        /*
         * p_pctcpu is only for diagnostic tools such as ps.
         */
....

....
LIST_FOREACH(TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME);
The macro LIST_FOREACH traverses the list referenced by head in the forward direction, assigning each element in turn to var.

Теперь здесь p будет содержать адрес struct proc структуры eery процесса, который находится в файле

sys/sys/proc.h

Теперь снова эта структура содержит другую структуру struct process *p_p, которая обозначает свойства каждого процесса, такие как его pid, flags, threads и т. д.

    struct proc {
        TAILQ_ENTRY(proc) p_runq;
        LIST_ENTRY(proc) p_list;    /* List of all threads. */

        struct  process *p_p;       /* The process of this thread. */
        TAILQ_ENTRY(proc) p_thr_link;   /* Threads in a process linkage. */

        TAILQ_ENTRY(proc) p_fut_link;   /* Threads in a futex linkage. */
        struct  futex   *p_futex;   /* Current sleeping futex. */

        /* substructures: */
        struct  filedesc *p_fd;     /* copy of p_p->ps_fd */
        struct  vmspace *p_vmspace; /* copy of p_p->ps_vmspace */
#define p_rlimit    p_p->ps_limit->pl_rlimit

    ....

    ....

Теперь структура struct process содержит uint64_t ps_plegde.

struct process {
    /*
     * ps_mainproc is the original thread in the process.
     * It's only still special for the handling of p_xstat and
     * some signal and ptrace behaviors that need to be fixed.
     */
    struct  proc *ps_mainproc;
    struct  ucred *ps_ucred;    /* Process owner's identity. */

....

....

    u_short ps_acflag;      /* Accounting flags. */

    uint64_t ps_pledge;
    uint64_t ps_execpledge; 

....

....

Теперь я внес некоторые изменения в код функции void schedcpu().

void
schedcpu(void *arg)
{
    pid_t pid;
    uint64_t pledge_bit;
....

....


    LIST_FOREACH(p, &allproc, p_list) {

    pid=p->p_p->pid;
    pledge_bit=p->p_p->ps_pledge;

    if (pledge_bit) {
            printf("pid: %10d pledge_bit: %10llu pledge_xbit:%10llx\n",pid,pledge_bit,pledge_bit);
}

        /*
         * Increment sleep time (if sleeping). We ignore overflow.
         */
        if (p->p_stat == SSLEEP || p->p_stat == SSTOP)
            p->p_slptime++;
        p->p_pctcpu = (p->p_pctcpu * ccpu) >> FS 
....

....

Здесь журнал ядра.

pid:      37846 pledge_bit:     393359 pledge_xbit:      6008f
pid:      96037 pledge_bit:     393544 pledge_xbit:      60148
pid:      86032 pledge_bit:     264297 pledge_xbit:      40869
pid:      72264 pledge_bit:     393480 pledge_xbit:      60108
pid:      40102 pledge_bit:          8 pledge_xbit:          8
pid:        841 pledge_bit: 2148162527 pledge_xbit:   800a5bdf
pid:      49970 pledge_bit: 2148096143 pledge_xbit:   8009588f
pid:      68505 pledge_bit:         40 pledge_xbit:         28
pid:      46106 pledge_bit:         72 pledge_xbit:         48
pid:      77690 pledge_bit:     537161 pledge_xbit:      83249
pid:      44005 pledge_bit:     262152 pledge_xbit:      40008
pid:      82731 pledge_bit: 2148096143 pledge_xbit:   8009588f
pid:      71609 pledge_bit:     262472 pledge_xbit:      40148
pid:      54330 pledge_bit:     662063 pledge_xbit:      a1a2f
pid:      77764 pledge_bit:    1052776 pledge_xbit:     101068
pid:        699 pledge_bit: 2148096143 pledge_xbit:   8009588f
pid:      84265 pledge_bit:    1052776 pledge_xbit:     101068

....

....

Теперь, возможно ли узнать, какой процесс закладывает какие разрешения, глядя на залог_бит (десятичные или шестнадцатеричные значения), которые я получил из приведенного выше вывода?

Я взял шестнадцатеричное значение залога процесса dhclient, то есть 0x8009588f, затем я написал пример программы hello world с pledge("STDIO",NULL);, снова посмотрел на dmesg и получил тот же залог_бит для приветствия, мир, то есть 0x8009588f.

Затем, на этот раз я посмотрел исходный код dhclient и обнаружил, что код dhclient заложил pledge("stdio inet dns route proc", NULL).

Но как тогда можно получить один и тот же бит залога для разных параметров залога?


person bsdboy    schedule 10.02.2018    source источник
comment
Возможно вопрос слишком специфичен для SO, задавайте в [email protected].   -  person Rufo El Magufo    schedule 10.02.2018
comment
да я тоже так думаю. Спасибо за предложение.   -  person bsdboy    schedule 10.02.2018


Ответы (1)


Я получил свой ответ после повторного чтения исходного кода.

Итак, я просто хочу поделиться своими знаниями, чтобы будущие разработчики не столкнулись с какими-либо проблемами, связанными с этой проблемой или путаницей.

Первое понимание:

Я написал привет мир, как это,

void
main() {
pledge("STDIO", NULL);   /* wrong use of pledge call */
printf("Hello world\n");
}

Исправление кода выше:

void
main() {

if (pledge("stdio", NULL) == -1) {
        printf("Error\n");
}
printf("Hello world\n");
}

Я забыл проверить возвращаемое значение от залога().

Второе понимание:

dhclient.c код содержит вызов залога() как:

int
main(int argc, char *argv[])
{
    struct ieee80211_nwid    nwid;
    struct ifreq         ifr;
    struct stat      sb;
    const char      *tail_path = "/etc/resolv.conf.tail";
....

....


fork_privchld(ifi, socket_fd[0], socket_fd[1]);

....

....


    if ((cmd_opts & OPT_FOREGROUND) == 0) {
        if (pledge("stdio inet dns route proc", NULL) == -1)
            fatal("pledge");
    } else {
        if (pledge("stdio inet dns route", NULL) == -1)
            fatal("pledge");
    }

....

....

void
fork_privchld(struct interface_info *ifi, int fd, int fd2)
{
    struct pollfd    pfd[1];
    struct imsgbuf  *priv_ibuf;
    ssize_t      n;
    int      ioctlfd, routefd, nfds, rslt;

    switch (fork()) {
    case -1:
        fatal("fork");
        break;
    case 0:
        break;
    default:
        return;
    }
....

....

}

Теперь я написал пример кода hello world, который содержит те же параметры, что и dhclient:

void
main() {

if(pledge("stdio inet proc route dns", NULL) == -1) {
        printf("Error\n");
}

while(1) {}
}

Теперь я протестировал приведенный выше пример кода hello world и получил залог_бит как 0x101068 в шестнадцатеричном формате, что правильно.

Но, как я уже говорил вам ранее в своем вопросе, я запутался, когда увидел другой залог_бит для dhclient. Потому что, как вы, ребята, знаете, оба имеют одинаковые параметры в залоге().

Тогда как это возможно?

Теперь, вот улов,

Постоянно просматривая исходный код dhclient, я нашел одну функцию с именем fork_privchld().

Эта функция вызывается перед залогом в dhclient, поэтому для этой функции нет залога, поскольку она вызывается перед залогом.

Итак, просто для проверки я снова написал пример кода hello world, но на этот раз без системного вызова promise().

void
main() {
printf("hello\n");
}

И, знаете, я получил тот же залог_бит, что и 0x8009588f.

Таким образом, после этой проверки подтверждается, что функция fork_privchld() не имеет установленного бита залога, поскольку она вызывается до залога в dhclient.

Эта функция создает дочерний процесс [priv] для dhclient.

# ps aux|grep dhclient
root     26416  0.0  0.1   608   544 ??  Is     8:36AM    0:00.00 dhclient: em0 [priv] (dhclient)
_dhcp    33480  0.0  0.1   744   716 ??  Isp    8:36AM    0:00.00 dhclient: em0 (dhclient)

И я не знаю, почему я смотрел только на первый процесс, то есть [priv] (dhclient). Этот процесс создается функцией fork_privchld().

Вот почему этот процесс имеет бит залога 0x8009588f (из-за вызова до залога, поэтому на данный момент залога нет).

И когда я проверил второй процесс, т.е. _dhcp, я получил ожидаемый залог_бит, т.е. 0x101068 (из-за залога).

Итак, я надеюсь, что все прояснится после прочтения этого.

Примечание. Пожалуйста, сообщите мне, если я что-то забыл или пропустил.

person bsdboy    schedule 12.02.2018