---
# System prepended metadata

title: LinuxOS Project2
tags: [Course - Linux OS]

---

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
