Skip to content

Instantly share code, notes, and snippets.

@ShawnHuang
Last active October 19, 2015 08:03
Show Gist options
  • Save ShawnHuang/72139e959a9e4901f7a4 to your computer and use it in GitHub Desktop.
Save ShawnHuang/72139e959a9e4901f7a4 to your computer and use it in GitHub Desktop.
linux project

Project 1

Total Score: 110 Points

#I. Introduction: The purpose of this project is to let you configure and modify the kernel by yourself. In this project you will learn: Some data structures that Linux kernel uses to maintain virtual addresses and physical addresses of a process. Some functions and macros related to virtual addresses, physical addresses, and processes.

In the following project description, you can use Google to find the meanings of words or phrases prefixed with the tag.

###II. Project Description : ####1. Add a new system call in Linux kernel. (10 points in this part) New system call prototype : int sys_project(long pid);

: Add a new system call in Linux

The following tasks need to be done inside your new system call which is in the kernel address space.

####2. Find the process according to the pid parameter. Print the image name of the process. (10 points) For example, if you execute an executable file called “project.out,” the result that you print out should be “project.out”.

: struct task_struct

####3. Dump the process virtual address space areas. The output may be similar to the following figure.

Print the vm_start and vm_end of all virtual address areas of the process. (15 points). If a file is associated with a virtual address area, print the name of the file. (15 points)

: struct mm_struct, struct vm_area_struct : you can use the /proc/$pid/maps to verify your result.

####4. Dump the physical frame addresses that the process is using (15 points).

: struct page and related functions and macro.

####5. Optional Bonus Point: (10 points) Add a new system call int nonwritable(unsigned long begin, unsigned long end)which specifies a virtual address range between begin and end as non-writable. You can use program project_user_2.c in appendix to verify your code.

: Change a page table entry from read-write to read-only.

: struct vm_area_struct, vm_flag, page fault

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *ptr = (char *)malloc(0x1000);
    unsigned int i;

    for(i = 0; i < 0x1000; i++) 
        ptr[i] = 'a';

    for( i = 0; i < 10; i++) 
        printf("%c ", ptr[i]);

    nonwritable(ptr, ptr+0x1000-1);

    /* verify read permission */
    for( i = 0; i < 10; i++) 
        printf("%c ", ptr[i]);

    /* write permission */
    ptr[0] = 'w';
    printf("if u see this message, you missed 15 points\n");
}

###III. TA Q & A ( 20 points) : ####1. Describe how you finished the project and the problems you encountered. ####2. Describe how you verify the result in step 4.

###IV. Report Content ( 15 points):

@ShawnHuang
Copy link
Author

First, we modify the pte to read-only permission after calling "pte_wrprotect(*pte)" and we are sure that the value has changed. In fact, if we assign a value to not only the ptr that is set only-read permission but other variables in c code, the pte's permission resumes after doing that .

So we add "ptep_set_wrprotect(mm, PtrToUlong((void *)ptr), &pte)" to our code. The pte doesn't resume anymore. However, we execute "ptr[0]='w'", the result is still the same.

Therefore we introduce it has an mechanism in Linux kernel to avoid pte fault and find an approach named "copy on write" after tracing those functions "handle_mm_fault, handle_pte_fault, do_page_fault". We think we change the page's protection and rewrite the vm_flags will let cow not to happen. After doing that, we still not get the error message,"segmentation fault" on kernel 3.14.25. Maybe we miss something else so we will continue to find the solution.

@ShawnHuang
Copy link
Author

[Sat Dec 13 13:23:01 2014] vm_ops ffffffff81814440
[Sat Dec 13 13:23:01 2014] vm_page_prot 25
[Sat Dec 13 13:23:01 2014] vm_page_prot 8000000000000027
[Sat Dec 13 13:23:01 2014] vm_flags 8001875
[Sat Dec 13 13:23:01 2014] vm_flags 8001875
[Sat Dec 13 13:23:01 2014] pte is writable!!
[Sat Dec 13 13:23:01 2014] before bit: 80000001f561e067
[Sat Dec 13 13:23:01 2014] before bit address: ffff880229a37f50
[Sat Dec 13 13:23:01 2014] after bit: 80000001f561e065
[Sat Dec 13 13:23:01 2014] after bit address: ffff880229a37f50
[Sat Dec 13 13:23:01 2014] flush bit: 80000001f561e065
[Sat Dec 13 13:23:01 2014] flush bit address: ffff880229a37f50
[Sat Dec 13 13:23:01 2014] page_mkwrite 0
[Sat Dec 13 13:23:01 2014] vm_ops ffffffff81814440
[Sat Dec 13 13:23:01 2014] vm_page_prot 8000000000000027
[Sat Dec 13 13:23:01 2014] vm_page_prot 8000000000000027
[Sat Dec 13 13:23:01 2014] vm_flags 8001875
[Sat Dec 13 13:23:01 2014] vm_flags 8001875
[Sat Dec 13 13:23:01 2014] before bit: 80000001f561e065
[Sat Dec 13 13:23:01 2014] before bit address: ffff880229a37f50
[Sat Dec 13 13:23:01 2014] after bit: 80000001f561e065
[Sat Dec 13 13:23:01 2014] after bit address: ffff880229a37f50
[Sat Dec 13 13:23:01 2014] flush bit: 80000001f561e065
[Sat Dec 13 13:23:01 2014] flush bit address: ffff880229a37f50

Copy link

ghost commented Jul 2, 2015

Copy link

ghost commented Jul 2, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment