线程访问权限

时间:2016-11-29 06:06:24

标签: c multithreading linux-kernel kernel pthreads

我正在尝试测试从公共进程创建的线程的虚拟内存空间的访问权限。 为了测试这个,我创建了一个系统调用,它将进程ID作为输入,查找虚拟内存空间并为给定的地址空间提供READ,WRITE,EXECUTE,SHARE和MAY_SHARE权限。

以下是系统调用代码

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/mm.h>
#include <asm/page.h>
#include <linux/fs.h>
#include <linux/path.h>

asmlinkage void sys_varstats(int PID)
{
    struct task_struct *task;
    struct pid *pid_struct;

    struct mm_struct *mm;
    struct vm_area_struct *vma;

     //size of virtual memory area
    unsigned long size_area;
    //size of virtual address space
    unsigned long size_space = 0;

    pid_struct=find_get_pid(PID);
    task=pid_task(pid_struct,PIDTYPE_PID);

    printk("\nProcess ID = %d \n", task->pid);
    mm = task->mm;

    vma = mm ->mmap;
    printk("Starting_Address   Size      Permission\n");

    do {
        size_area = (vma->vm_end - vma->vm_start);
        printk("%-19lu%-10lu", vma->vm_start, size_area);

        if ((vma->vm_flags) & VM_READ)
            printk("r");
        else
            printk("-");

        if ((vma->vm_flags) & VM_WRITE)
            printk("w");
        else
            printk("-");

        if ((vma->vm_flags) & VM_EXEC)
            printk("x");
        else
            printk("-");

        if ((vma->vm_flags) & VM_SHARED)
            printk("s");
        else
            printk("-");

        if ((vma->vm_flags) & VM_MAYSHARE)
            printk("m");
        else
            printk("-");


        printk("\n");
        size_space += size_area;
        vma = vma->vm_next;

    }
    while(vma != NULL);
    printk("Total Space = %lu \n", size_space);

}

现在,我创建了五个不同的线程,它们共享一个全局数组,并执行某些操作。每个线程还调用上面的系统调用来获取访问权限。 以下是用于创建多个线程的代码。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <stdio.h>
#define __NR_varstats 337
#define NTHREADS 5

int global_arr[1000000];
const int s=1000000;
 void *num(void *threadid)
 {
        int n=s/NTHREADS;
    int tid = (int)threadid;
    printf("Beginning Thread %ld\n",tid);
        for(int i=tid*n;i<(tid+1)*n;i++)
        {
                global_arr[i]=tid;
                if (i==(tid*n)+(n/2))
                {
                        pid_t systid=syscall(SYS_gettid);
                        printf("PID %d %ld\n",systid,tid);
                        syscall(__NR_varstats, systid);
                }
        }
    pthread_exit(NULL);
 }

int main(int argc, char *argv[])
{
    pthread_t threads[NTHREADS];
    void *status;

    for(int t=0; t<NTHREADS; t++)
    {
       int return_code = pthread_create(&threads[t], NULL, num, (void *)t);
       if (return_code){
          printf("ERROR; return code from pthread_create() is %d\n", return_code);
          exit(-1);
       }
    }
    for(int t=0; t<NTHREADS; t++)
    {
        printf("Joining Thread %d\n",t);
        pthread_join(threads[t], &status);
    }
        printf("Parent Process PID %d\n",getpid());
        return 0;
}

我从这个实验得到的输出如下。 我无法理解的是,下面的线程共享许多虚拟内存空间,但仍然不共享该内存空间的访问权限。我的印象是,由于线程正在写入全局列表,因此至少有一个内存段将在进程之间共享。 此外,第一个线程的总地址空间不同,但其余线程共享相同数量的内存,尽管所有线程最终都在处理相同数量的数据。

Process ID = 9402 
Starting_Address   Size      Permission
4911104            122880    r-x--
5033984            4096      r----
5038080            4096      rw---
5066752            1642496   r-x--
6709248            8192      r----
6717440            4096      rw---
6721536            12288     rw---
6770688            94208     r-x--
6864896            4096      r----
6868992            4096      rw---
6873088            8192      rw---
134512640          4096      r-x--
134516736          4096      rw---
134520832          3997696   rw---
153894912          135168    rw---
3037425664         4096      -----
3037429760         8388608   rw---
3045818368         4096      -----
3045822464         8388608   rw---
3054211072         4096      -----
3054215168         8388608   rw---
3062603776         4096      -----
3062607872         8388608   rw---
3070996480         4096      -----
3071000576         8392704   rw---
3079450624         8192      rw---
3079458816         4096      r-x--
3220262912         86016     rw---
Total Space = 48115712 

Process ID = 9403 
Starting_Address   Size      Permission
4911104            122880    r-x--
5033984            4096      r----
5038080            4096      rw---
5066752            1642496   r-x--
6709248            8192      r----
6717440            4096      rw---
6721536            12288     rw---
6770688            94208     r-x--
6864896            4096      r----
6868992            4096      rw---
6873088            8192      rw---
134512640          4096      r-x--
134516736          4096      rw---
134520832          3997696   rw---
153894912          135168    rw---
1275813888         118784    r-x--
1275932672         4096      rw---
3035627520         135168    rw---
3035762688         913408    -----
3037425664         4096      -----
3037429760         8388608   rw---
3045818368         4096      -----
3045822464         8388608   rw---
3054211072         4096      -----
3054215168         8388608   rw---
3062603776         4096      -----
3062607872         8388608   rw---
3070996480         4096      -----
3071000576         8392704   rw---
3079450624         8192      rw---
3079458816         4096      r-x--
3220262912         86016     rw---
Total Space = 49287168 

Process ID = 9401 
Starting_Address   Size      Permission
4911104            122880    r-x--
5033984            4096      r----
5038080            4096      rw---
5066752            1642496   r-x--
6709248            8192      r----
6717440            4096      rw---
6721536            12288     rw---
6770688            94208     r-x--
6864896            4096      r----
6868992            4096      rw---
6873088            8192      rw---
134512640          4096      r-x--
134516736          4096      rw---
134520832          3997696   rw---
153894912          135168    rw---
1275813888         118784    r-x--
1275932672         4096      rw---
3035627520         135168    rw---
3035762688         913408    -----
3037425664         4096      -----
3037429760         8388608   rw---
3045818368         4096      -----
3045822464         8388608   rw---
3054211072         4096      -----
3054215168         8388608   rw---
3062603776         4096      -----
3062607872         8388608   rw---
3070996480         4096      -----
3071000576         8392704   rw---
3079450624         8192      rw---
3079458816         4096      r-x--
3220262912         86016     rw---
Total Space = 49287168 

Process ID = 9400 
Starting_Address   Size      Permission
4911104            122880    r-x--
5033984            4096      r----
5038080            4096      rw---
5066752            1642496   r-x--
6709248            8192      r----
6717440            4096      rw---
6721536            12288     rw---
6770688            94208     r-x--
6864896            4096      r----
6868992            4096      rw---
6873088            8192      rw---
134512640          4096      r-x--
134516736          4096      rw---
134520832          3997696   rw---
153894912          135168    rw---
1275813888         118784    r-x--
1275932672         4096      rw---
3035627520         135168    rw---
3035762688         913408    -----
3037425664         4096      -----
3037429760         8388608   rw---
3045818368         4096      -----
3045822464         8388608   rw---
3054211072         4096      -----
3054215168         8388608   rw---
3062603776         4096      -----
3062607872         8388608   rw---
3070996480         4096      -----
3071000576         8392704   rw---
3079450624         8192      rw---
3079458816         4096      r-x--
3220262912         86016     rw---
Total Space = 49287168 

Process ID = 9399 
Starting_Address   Size      Permission
4911104            122880    r-x--
5033984            4096      r----
5038080            4096      rw---
5066752            1642496   r-x--
6709248            8192      r----
6717440            4096      rw---
6721536            12288     rw---
6770688            94208     r-x--
6864896            4096      r----
6868992            4096      rw---
6873088            8192      rw---
134512640          4096      r-x--
134516736          4096      rw---
134520832          3997696   rw---
153894912          135168    rw---
1275813888         118784    r-x--
1275932672         4096      rw---
3035627520         135168    rw---
3035762688         913408    -----
3037425664         4096      -----
3037429760         8388608   rw---
3045818368         4096      -----
3045822464         8388608   rw---
3054211072         4096      -----
3054215168         8388608   rw---
3062603776         4096      -----
3062607872         8388608   rw---
3070996480         4096      -----
3071000576         8392704   rw---
3079450624         8192      rw---
3079458816         4096      r-x--
3220262912         86016     rw---
Total Space = 49287168 

我无法理解这一点,任何解释都会有用。

2 个答案:

答案 0 :(得分:0)

您的代码打印过程中有关读,写和可执行文件等的权限。

创建进程时,它由“struct task_struct”表示,新创建的进程的内存地址空间由“struct vm_area_struct * vma”表示; vm_area_struct维护应用程序中每个段的起始和结束地址。随着约有许可标志。

无论何时创建线程,线程都被视为内核中的进程。所有线程都有自己的pid,因此每个线程都有自己的vm_area_struct。这就是你看到vm_area_struct正在调用每个线程的方式。

内核通过tgid区分线程和进程,由单个进程生成的所有线程将具有相同的tgid但差异为pid。

task_struct contains a pointer to struct mm_struct.
struct mm_struct contains a pointer to vm_area_struct.

所以你需要初始化

mm = task->mm;
vma = mm->vma

希望你明白。

答案 1 :(得分:0)

你在哪里看到各种各样的差异?如果检查内核代码,您将看到线程共享mm。因此,如果您遍历所有线程,则始终首先访问相同的mm。

内核代码也错了。它缺乏正确的锁定和错误检查是可行的。例如,没有采取任何措施来确保任务不会消失,mm是否存在且不会消失等。

如果代码注定只用于内省,则可以使用“当前”代替。