Extracting pledge information from kernel code for every process.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Extracting pledge information from kernel code for every process.

Neeraj Pal
Hello, Tech,

I am doing some hands-on with OpenBSD Kernel code especially with
"sys/kern/kern_sched.c".

I am trying to extract pledge information from kernel code for every process.

In below function, I am doing some modifications for that,

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.
         */
....

....

}

Now, here, after reading some little source code, I found that
LIST_FOREACH macro will traverse from the head (&allproc) and put it
on var (p).

Now, here, p will contain the address of struct proc structure of
every process which is in the file sys/sys/proc.h.

Now, again, this structure contains another struct process *p_p
structure, which denotes the properties of every process like its pid,
flags, threads etc.

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

....

....

}


Now, structure struct process contains 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;

....

....


}


Now, I wrote some modification in void schedcpu() function code.

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
....

....

}

Here, Kernel log

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

....

....


Is it possible to know which process pledges what permissions,
from looking at pledge_bit (decimal or hex values) that I got from
above output?

I took pledge hex value of dhclient process i.e 0x8009588f, then, I
wrote a simple hello world program with a pledge("STDIO",NULL); and
again I looked at dmesg and got the same pledge_bit for hello world
i.e 0x8009588f.

Then, this time I looked at dhclient source code and found out that,
dhclient code pledged pledge("stdio inet dns route proc", NULL).

But, then, how is it possible to get same pledge hex bit for different
pledge parameters?

Or, Is there some other pledge variable in kernel which keeps track of
permission bits that pass from user-space code using pledge()?


Is it the correct way that I did above to extract pledge information
or Am I missing or doing it wrong?



--
Thank you,

Neeraj Pal ツ
 +91-8130344470