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