【问题标题】:Thread Access Permission线程访问权限
【发布时间】:2017-04-13 00:49:18
【问题描述】:

我正在尝试测试从公共进程创建的线程的虚拟内存空间的访问权限。 为了测试这一点,我创建了一个系统调用,它将进程 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 

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

【问题讨论】:

    标签: c multithreading linux-kernel kernel pthreads


    【解决方案1】:

    您的代码打印进程权限关于读、写和可执行等。

    创建进程时,用“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
    

    希望你能理解。

    【讨论】:

      【解决方案2】:

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

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

      如果代码注定只用于自省,您可以改用“当前”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-16
        • 1970-01-01
        • 1970-01-01
        • 2015-04-20
        • 2013-09-18
        • 1970-01-01
        • 2021-02-08
        • 2012-07-11
        相关资源
        最近更新 更多