我正在尝试测试从公共进程创建的线程的虚拟内存空间的访问权限。 为了测试这个,我创建了一个系统调用,它将进程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 :(得分: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是否存在且不会消失等。
如果代码注定只用于内省,则可以使用“当前”代替。