LinuxOS Project2 = ###### tags: `Course - Linux OS` ## 小組名單 - 第20組 108502532 丁麒源 108502533 廖宥霖 108502530 曹鈞翔 ## Question * Write a program using the system call you wrote in Project 1 to check how memory areas are ==shared by two processes== that execute this program simultaneously. * The memory areas include code segments, data segments, BSS segments, heap segments, libraries, stack segments. ### Hint: * When making your check, both related processes must be in progress. Hence you may need to use function ==sleep()== to guarantee this requirement. * Inside the Linux kernel, you need to use function ==copy_from_user()== and function ==copy_to_user()== to copy data from/to a user address buffer. ## 補交? * sleep() * strace * library address ## ==執行結果== * ==only code segments are the same in two processes== * ==data and bss segments are the same in their process after translate to physical address== ``` thread: main (pid 566) addresses of variables: <code()>: '0x5569db57a229' -> '0x2a99000' -> '0x2a99000' <data>: '0x5569db57d010' -> '0x842aa000' -> '0x842aa000' <bss>: '0x5569db57d016' -> '0x842aa000' -> '0x842aa000' <heap>: '0x5569dcf122a0' -> '0x9a21d000' -> '0x9a21d000' <mmmap>: '0x7efc352a2000' -> '0x2e576000' -> '0x2e576000' <stack>: '0x7fff480cadd2' -> '0x9a1d8000' -> '0x9a1d8000' virtual addresses of segment pointers: Code Segment: <start_code>: '0x5569db57a000' <end_code>: '0x5569db57a67d' Data Segment: <start_data>: '0x5569db57cd80' <end_data>: '0x5569db57d015' Heap Segment: <start_brk>: '0x5569dcf12000' <brk>: '0x5569dcf33000' Stack Segment: <start_stack>: '0x7fff480caf10' mmap Segment: <mmap_base>: '0x7efc352a7000' ================================================================== thread: main (pid 572) addresses of variables: <code()>: '0x560ef8ccd229' -> '0x2a99000' -> '0x2a99000' <data>: '0x560ef8cd0010' -> '0x9a18c000' -> '0x9a18c000' <bss>: '0x560ef8cd0016' -> '0x9a18c000' -> '0x9a18c000' <heap>: '0x560ef8f822a0' -> '0x23025000' -> '0x23025000' <mmmap>: '0x7f5cd7ecf000' -> '0x23021000' -> '0x23021000' <stack>: '0x7ffe0e7fb752' -> '0x9a19a000' -> '0x9a19a000' virtual addresses of segment pointers: Code Segment: <start_code>: '0x560ef8ccd000' <end_code>: '0x560ef8ccd67d' Data Segment: <start_data>: '0x560ef8ccfd80' <end_data>: '0x560ef8cd0015' Heap Segment: <start_brk>: '0x560ef8f82000' <brk>: '0x560ef8fa3000' Stack Segment: <start_stack>: '0x7ffe0e7fb890' mmap Segment: <mmap_base>: '0x7f5cd7ed4000' ``` ## ==Kernel space code== ### `get_segment_info.c` ```c= #include <linux/types.h> #include <linux/syscalls.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/ptrace.h> #include <linux/thread_info.h> #include <linux/mm.h> #include <linux/io.h> #include <asm/current.h> #include <asm/page.h> struct segment_info { unsigned long start_code, end_code; unsigned long start_data, end_data; unsigned long start_brk, brk; unsigned long start_stack; unsigned long mmap_base; }; SYSCALL_DEFINE1(get_segment_info, void *, dsi) { struct segment_info si = { .start_code = current->mm->start_code, .end_code = current->mm->end_code, .start_data = current->mm->start_data, .end_data = current->mm->end_data, .start_brk = current->mm->start_brk, .brk = current->mm->brk, .start_stack = current->mm->start_stack, .mmap_base = current->mm->mmap_base, }; if (copy_to_user((struct segment_info *)dsi, &si, sizeof(si))) return -1; return current->pid; } SYSCALL_DEFINE1(virt_to_phys, unsigned long, vaddr) { return page_to_phys(follow_page(current->mm->mmap, vaddr, 0)); } SYSCALL_DEFINE1(virtual_to_physical, unsigned long, vaddr) { pgd_t *pgd_tmp; p4d_t *p4d_tmp; pud_t *pud_tmp; pmd_t *pmd_tmp; pte_t *pte_tmp; pgd_tmp = pgd_offset(current->mm, vaddr); p4d_tmp = p4d_offset(pgd_tmp, vaddr); pud_tmp = pud_offset(p4d_tmp, vaddr); pmd_tmp = pmd_offset(pud_tmp, vaddr); pte_tmp = pte_offset_kernel(pmd_tmp, vaddr); return pte_val(*pte_tmp) & PAGE_MASK; } ``` ## ==User space code== ### `main.c` ```c= #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/syscall.h> #define __NR_get_segment_info 449 #define __NR_virt_to_phys 450 #define __NR_virtual_to_physical 451 struct segment_info { unsigned long start_code, end_code; unsigned long start_data, end_data; unsigned long start_brk, brk; unsigned long start_stack; unsigned long mmap_base; }; char *code() { return "code"; } void print_segment_info(char *thread_name) { static char data[5] = "data"; static char bss[4]; char *heap = (char *)malloc(sizeof(char) * 5); char *mmmap = mmap(NULL, 5 * sizeof(char), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); *mmmap = "mmmap"; char stack[6] = "stack"; struct segment_info si; printf("thread: %s (pid %d)\n", thread_name, syscall(__NR_get_segment_info, &si)); printf("addresses of variables:\n"); printf("<code()>:\t'%p' -> '%p' -> '%p'\n", code, syscall(__NR_virt_to_phys, &code), syscall(__NR_virtual_to_physical, &code)); printf("<data>:\t\t'%p' -> '%p' -> '%p'\n", data, syscall(__NR_virt_to_phys, &data), syscall(__NR_virtual_to_physical, &data)); printf("<bss>:\t\t'%p' -> '%p -> '%p'\n", bss, syscall(__NR_virt_to_phys, &bss), syscall(__NR_virtual_to_physical, &bss)); printf("<heap>:\t\t'%p' -> '%p' -> '%p'\n", heap, syscall(__NR_virt_to_phys, heap), syscall(__NR_virtual_to_physical, heap)); printf("<mmmap>:\t'%p' -> '%p' -> '%p'\n", mmmap, syscall(__NR_virt_to_phys, mmmap), syscall(__NR_virtual_to_physical, mmmap)); printf("<stack>:\t'%p' -> '%p' -> '%p'\n", stack, syscall(__NR_virt_to_phys, &stack), syscall(__NR_virtual_to_physical, &stack)); printf("virtual addresses of segment pointers:\n"); printf("Code Segment:\n"); printf("<start_code>:\t'%p'\n", si.start_code); printf("<end_code>:\t'%p'\n", si.end_code); printf("Data Segment:\n"); printf("<start_data>:\t'%p'\n", si.start_data); printf("<end_data>:\t'%p'\n", si.end_data); printf("Heap Segment:\n"); printf("<start_brk>:\t'%p'\n", si.start_brk); printf("<brk>:\t\t'%p'\n", si.brk); printf("Stack Segment:\n"); printf("<start_stack>:\t'%p'\n", si.start_stack); printf("mmap Segment:\n"); printf("<mmap_base>:\t'%p'\n", si.mmap_base); printf("===========================================\n"); free(heap); } int main() { print_segment_info("main"); sleep(10); } ``` ## 參考資料 Virt_to_phys address: https://blog.51cto.com/u_15265005/2896420 https://blog.csdn.net/weixin_41028621/article/details/104506478 Add new system call: https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8 Replacing the WSL Kernel: https://blog.dan.drown.org/replacing-the-wsl-kernel/ problems and solutions: https://blog.csdn.net/qq_36393978/article/details/124274364 https://blog.csdn.net/m0_48958478/article/details/121620449 https://blog.csdn.net/bby1987/article/details/104264285 Others: 奔跑吧 CH 3.1 進程的誕生 https://hackmd.io/@PIFOPlfSS3W_CehLxS3hBQ/S14tx4MqP?fbclid=IwAR2yZqy4A92NegOZUj5frnDXKr_8XG_Y8mXJZXq5lboJG2S3OodFTSmACXg OS Process & Thread (user/kernel) 筆記 https://medium.com/@yovan/os-process-thread-user-kernel-%E7%AD%86%E8%A8%98-aa6e04d35002 linux 内存管理(8) —内存描述符(mm_struct) https://blog.csdn.net/weixin_41028621/article/details/104455327 Linux进程地址管理之mm_struct https://www.cnblogs.com/rofael/archive/2013/04/13/3019153.html Do memory mapping segment and heap grow until they meet each other? https://unix.stackexchange.com/questions/466443/do-memory-mapping-segment-and-heap-grow-until-they-meet-each-other mmap() https://unix.stackexchange.com/questions/466443/do-memory-mapping-segment-and-heap-grow-until-they-meet-each-other https://ithelp.ithome.com.tw/articles/10187260?sc=rss.iron https://www.quora.com/What-factors-decides-the-load-address-of-shared-libraries-like-libc setvbut() https://stackoverflow.com/questions/5876373/using-setvbuf-with-stdin-stream How The Kernel Manages Your Memory https://manybutfinite.com/post/how-the-kernel-manages-your-memory/ malloc() in multi-thread program https://hackmd.io/@ljP_AG30SzmQE5qO-cjcpQ/HkICAjeJg?type=view#%E8%83%8C%E6%99%AF%E7%9F%A5%E8%AD%98%E8%88%87gblic-Malloc%E5%8E%9F%E7%90%86 系統呼叫(system call)的剖析(上) https://alittleresearcher.blogspot.com/2015/02/anatomy-of-a-system-call-part-1.html 什麼是 "asmlinkage"? https://www.jollen.org/blog/2006/10/_asmlinkage.html Linux CVE-2009-0029 漏洞解析 https://blog.csdn.net/hxmhyp/article/details/22619729 Linux 筆記 3 https://hackmd.io/@combo-tw/Linux-%E8%AE%80%E6%9B%B8%E6%9C%83/%2F%40a29654068%2FHyD4Lu_Dr Linux 讀書會 - Virtual Memory https://hackmd.io/@combo-tw/Linux-%E8%AE%80%E6%9B%B8%E6%9C%83/%2F%40combo-tw%2FBJlTwJUABB