2016-11-29 5 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); 

} 

で、私は、彼らはいくつかの操作を実行するグ​​ローバル配列を共有する5つの異なるスレッドを作成します。各スレッドは、上記のシステムコールを呼び出してアクセス許可を取得します。 以下は、複数のスレッドを作成するためのコードです。

#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; 
} 

この実験から得られる出力は次のとおりです。 私が理解できないことは、以下のスレッドが多くの仮想メモリ空​​間を共有しますが、そのメモリ空間に対するアクセス許可は共有されていないことです。スレッドがグローバルリストに書き込んでいるので、メモリセグメントの少なくとも1つがプロセス間で共有されるという印象を受けました。 また、最初のスレッドの合計アドレス空間は異なりますが、残りのスレッドは同じ量のメモリを共有しますが、すべてのスレッドは最終的に同じ量のデータを処理します。

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で区別します.1つのプロセスによって生成されるすべてのスレッドは、同じ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を共有していることがわかります。したがって、すべてのスレッドを繰り返し処理する場合は、常に最初に同じmmにアクセスします。

また、カーネルコードが間違っています。適切なロックとエラーチェックが実行可能でないことがあります。例えば、タスクがなくなっていないことを確認するための手順はありません。mmはそこにあり、そこから離れることはありません。

コードがイントロスペクションのためにのみ使用されることになっていた場合は、代わりに 'current' 。