linux project 中央大學資工系 碩士二年級 江瑞敏. outline how to compile linux kernel...

Post on 29-Dec-2015

229 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Linux Project

中央大學資工系 碩士二年級江瑞敏

Outline

• How to compile linux kernel• How to add a new system call• Some Projects Example and Way to Solve it

– System Call Hooking by Module– Project about Memory– Project about Process

Download Link

• wget https://kernel.org/pub/linux/kernel/linux-2.6.18.tar.bz2• tar xvf linux-2.6.18.tar.bz2

The Beginning of everything

Compile Linux Kernel

It is Hard?

No, If you understand the concept

The Basic Process

• 0. make mrproper• 1. make oldconfig• 2. make –j[n]• 3. make modules_install• 4. make install• 5. reboot

Do You Know What It Means?

make mrproer

• Clean up the environment• Will Remove almost everything, except….

make clean

• Almost the same as make mrproper.

make oldconfig

• Use the configuration file the current kernel is using.

• Some other alternative options.– Make menuconfig– …

Is config File Important?

Config file

• Determine which kind of kernel you are compiling

• Determine which modules you want the kernel to compile.

• Misconfiguration will lead to kernel crash.

make –j[n]

• Compile the whole source code according to your configuration

make modules_install

• Install the modules into the necessary folder.– /lib/modules/`uname –r`/

make install

• Install the image into the boot directory.• Sometimes, update grub is necessary.

What Is System Call

It’s a Bridge

Between

User

Device

Device

Device

Device

Why System Call

Pop Quiz :Write A Program To Print “Hello World”

What You May Write

What Actually Happened ….

User Application

Kernel Code

SystemCall

libc.soPrintf

Device DriverIO Device

What If There Is No System Call

Everything Will Bex86 instruction in and out

Let’s Focus On …User Application

Kernel Code

SystemCall

libc.soPrintf

Device DriverIO Device

Magic int 0x80

Before We Talk Further,Let’s Talk About X86 Architecture

X86 Architecture Is Interrupt Driven

CPU 8259 PIC

Kernel

Device DeviceDevice

User Application

Device

Device Driver

How The CPU Find The Address of The Device Driver Code

Callback Mechanism

CPU 8259 PIC

Device DeviceDevice Device

Device Driver

Device Driver

Device Driver

Device Driver

Interrupt Descriptor Table

…..

Kernel

Physical Device

How About System Call

Magic int 0x80

CPU 8259 PIC

Device DeviceDevice DevicePhysical Device

syscall_tableInterrupt Descriptor Table

…..

…..

0x80…..

System Call

Handler

System Call

Handler

System Call

Handler

int 0x80

CPU

Kernel

User Applicationint 0x80

csdsss

espeip…

Stack

cpu

CPU

User Applicationint 0x80

GDT

Get TSS

TSS

csdsss

espeip…

Stack

cpu

CPU

User Applicationint 0x80

GDT

Get TSS

TSS

csdsss

espeip…

Stack

cpu

CPU

User Applicationint 0x80

IDT

Get IDT

csdsss

espeip…

Stack

0x80

ENTRY(system_call)

cpu

sys_call_table

CPU

User Applicationint 0x80

IDT

Get IDT

csdsss

espeip…

Stack

0x80

ENTRY(system_call)

cpu

sys_call_table

CPU

User Applicationint 0x80

IDT

Get IDT

csdsss

espeip…

ssesp

eflagscseip…

Stack

0x80

ENTRY(system_call)

sys_call_table

cpu

How To Add A System Call

Add a System Call

• 1. cd $kernel_src• 2. cd arch/i386/kernel/syscall_table.S• 3. • ….• .long sys_tee /* 315 */

.long sys_vmsplice

.long sys_move_pages

.long sys_project /* 318 */• Kernel.org/pub/linux/kernel

Add a System Call

• cd linux/include/asm-i386/unistd.h• #define __NR_vmsplice 316

#define __NR_move_pages 317#define __NR_project 318

#ifdef __KERNEL__

#define NR_syscalls 319

Add a System Call• cd linux/include/linux/syscalls.h• asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,

size_t len);asmlinkage long sys_project( int i );

#endif

Add a System Call

• cd linux/kernel• touch project.c• Makefile• obj-y = project.o sched.o fork.o

exec_domain.o panic.o printk.o profile.o

Add a System Call

• Project.c• #include <linux/linkage.h>

#include <linux/kernel.h>

asmlinkage long sys_project( int i ){ printk( "Success!! -- %d\n", i ); return 0;}

Add a System Call

• Recompile linux kernel• Reboot• Create a new file “test.c”

• #include<syscall.h>

int main(){ syscall( 318, 2 ); return 0;}

Add a System call

• http://in1.csie.ncu.edu.tw/~hsufh/COURSES/FALL2007/syscall.html

About 64 bits

• The Idea is the same• There are many online references • Therefore, I will not cover in this ppt.

System Call Hooking by Module

System Call Hooking

57

sys_call_table

正常的 execve程式碼

Usermode 程式呼叫系統呼叫 NR_execve

System Call Hooking

58

sys_call_table

正常的 execve程式碼

Usermode 程式呼叫系統呼叫 NR_execve

Hooking Code

System Call Hooking

59

sys_call_table

Usermode 程式呼叫系統呼叫 NR_execve

Hooking Code

正常的 execve程式碼

Modified execve

Source code links

• http://pastebin.com/rShUxvB5• http://pastebin.com/KEJxgLGq

Project about Memory

Level 1:Dump the virtual address of a process

Some Question U may Ask

Where to Start?

Maybe Add a New System Call

1. How to find the process you want?

Process List

• task_struct• for_each_process()• If u pay attention in class, these two are not

stranger.

2. How about Virtual Address that is being used by the current process?

The Data Structure

• mm_struct• vm_area_structlxr.linux.no

How it looks like

The rest is some basic programming skill

Too easy,Let’s make it a little bit harder

Level 2:Dump the physical frame that is

associate with the virtual address.

New Problem, New question

How to transfer Virtual Address to Physical Address?

Some Reminder and Hints

Some Reminder and Hints

Where is CR3?

Now We Have CR3,Then?

Calculate By Yourselfor

Something Smarter

follow_page()

Push Yourself More

Level 3:Log these information to a file

Ok, let’s type

dmesg || grep “myproject” >> log.txt

DudeAre you…

…. From Kernel of course

Can We Do That???

How to write file in User Mode

• fd = open(filename, “w”);• write(ptr, string, strlen(string));• close(fd);

How about Kernel Mode

open -> do_sys_open

Write -> sys_write()

Close -> sys_close()

Is that all?

The magic __user

It tell kernel that the parameter should pass from user mode

It’s a protection mechanism

Final Step About this Project

Level 4:Modify The PTE r/w flagfrom read/write to read

http://in1.csie.ncu.edu.tw/~hsufh/COURSES/FALL2012/linux_project1.html

Structures of Page Directories And Page Tables Entries

Wow, Looks Simple :D

Basic Idea

• 1. loop through the translation table of a process according to the virtual address.

• 2. After finding the pte, change the read/write flag

• 3. Done

• pte_wrprotect()

Code Implement

• for(loop_count = addr; loop_count < end; loop_count+=PAGE_SIZE){• pgd = pgd_offset(mm, loop_count);• if (pgd_none(*pgd)){• printk("pgd none happened\n");• continue;• }• pud = pud_offset(pgd, loop_count);• pmd = pmd_offset(pud, loop_count);• pte = pte_offset_map_lock(mm, pmd, loop_count, &ptl);• if(operation == 1){• *pte = pte_mkwrite(*pte);• } else{• *pte = pte_wrprotect(*pte);• }

Code Implement(Cont. )

Result

Result

What!?

Use Printk to Verify

Printk Tell Us Two Things

1. we have change the pte r/w flag

2. only one entry being change back, other didn’t in most cases.

Magic Happened ?

Now,Imagine you are CPU

What will happened whensome process try to access a read

only area

Page Fault Happened

The Question Becomes,How Linux Handle Page Fault

U might Ask,What is Page Fault

From CPU point of view

1. present flag of pgd or pte is clear.2. code running in user mode attempts to write to a read only page.– More detailed check intel programmer manual.

From Kernel Point of View

1. present flag is clear:• A. Access the first time.• B. Page is being swap out.

2. write to a read only page:• A. is a process really write to a read only page • B. is a page-fault optimization such as copy on write.

How Does Linux Kernel Determine These Kind of Difference

Well, First….

And This

Then This

What The FxxK…….

This Time Let’s Look Closer

Now We Know An Important Thing

Linux Kernel Will Compare The vm_flag

Some Useful Knowledge

How Linux Implement COW

Cow??

Moo ?

• 1. COW refer to copy on write• 2. google and wiki are your friend• 3. how linux implement copy on write.

– A. pte r/w flag disable– B. vm_flag & VM_WRITE == true

Our project accidently match the above conditions!

• 1. same page table entry of parent and child process point to the same pfn

• 2. set r/w flag of both pte to read only• 3. when page fault happened, page fault handler will

check the vm_flag of the current virtual address.• 4. if vm_flag has VM_WRITE, page fault handler will

refer this situation as a COW condition.• 5. assign a new pfn with r/w flag enable if there are

two pte point to it.

Copy on Write linux implement

parent

child

Task_struct

Task_struct

pte

ptePhysical address

Pfn N

Pfn (N+1)

Pfn (N+2)Fork(…)pgd

pgd

R/W RO

RO

Parent AccessPage Fault

VM_WRITE

VM_WRITE

_map_count=01

Child Access

R/W

A New Idea of The Project

1. Change PTE r/w flag as we just did

2. Change the vm_flag as well

• down_write(&current->mm->mmap_sem);• vma = find_vma(mm, addr);• vm_start = vma->vm_start;• vm_end = vma->vm_end;• mask = VM_READ|VM_WRITE|VM_EXEC|VM_SHARED;• new_flags = VM_READ;• old_flags = vma->vm_flags;• if(old_flags&VM_WRITE){• old_flags &= ~(VM_WRITE);• new_flags |= old_flags;• } else{• new_flags |= old_flags;• } • prot = protection_map[new_flags & mask];• vma->vm_flags = new_flags;• vma->vm_page_prot = prot;• up_write(&current->mm->mmap_sem);• addr &= PAGE_MASK; • change_pte(addr, end, operation);

Code Implementation

Result

Where is the “press enter to continue” ?

It’s time to use GDB

Set a break point before syscall happened

Seems like this time printf cause the error

Here is the problem.

Think Slowly

Calling printf will need to push some parameters

Recall From The Last Code

• we have changed vm_flag for the whole vm_area_struct which means the entire block of linear address.

• Address of the array is not always align to 4kb.

Consider The following Conditions

Start address alignEnd address align

Start Address AlignEnd Address Not Align

Start addr

End addr Total need 3 pages

Area problem may occur

Test_array

low

high

Start Address Not AlignEnd Address Align

Start addr

End addrTotal need 3 pages

Area problem may occur

low

high

Test array

Start Address Not AlignEnd Address Not Align

Start addr

End addr

Area problem may occur

Area problem may occur

Total need 4 pages

Test_array

low

high

Our case

The parameter is right hereSince the page is RO.

low

high

Assembly code:…..Call syscall;Push $string;Call printf;

R/WR only

DOOMED

• Rewrite the user mode program. This time use malloc instead of local variable.(Heap instead of stack)

• Char *test_array;• Test_array = (char *)malloc(ARRAY_SIZE)

Verify Our Thoughts (Test case 1)

Test Case 1 Result

• Char test1[0x2000];• Char test_array[ARRAY_SIZE];• Char test2[0x2000];• This can also bypass the conditions that I just

mentioned.

Verify Our Thoughts (Test case 2)

Test Case 2 Result

Also work~~

• 1. basically, the idea is the same. – A. change vm_flag– B. change pte r/w flag

• 2. Some hints:– A. Strongly recommend reading Text Book

• Chapter 8: Memory Management• Chapter 9: Process Address Space

– B. code to change vma_flag is in mprotect_fixup(). – C. the code to loop through the translation table starts from

change_protection(….) -> change_pud(….) -> change_pmd(…..) -> change_pte_range(…..)

How About Mprotect.c

Full Source

• Level 1 and 2 :http://pastebin.com/wEVLaQyg• Level 3:http://pastebin.com/HFW8WTN5

top related