2016-11-29 79 views
0

我想測試從一個公共進程創建的線程的虛擬內存空間的訪問權限。 爲了測試這一點,我創建了一個系統調用,它將進程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 

我無法理解這一點,任何解釋都會有用。

回答

0

您的代碼約讀印刷過程的權限,寫和執行等

創建一個進程時,它是由「結構的task_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 

希望你能理解。

0

你在哪裏看到什麼差異?如果你檢查內核代碼,你會看到線程共享毫米。所以如果你遍歷所有線程,你總是首先訪問相同的mm。

此外內核代碼是錯誤的。它缺乏適當的鎖定和錯誤檢查是可行的。例如,沒有采取措施確保任務不會消失,毫米就在那裏,並且不會消失等等。

如果代碼註定僅用於內省,則可以使用「current」代替。