# Linux lab 1 note (Journal) ###### tags: `linux`, `linux-2022-autumn` </br> > linux & windows 基本上不使用 segment descriptor > 因此 virtual address 和 linear address 基本上一樣 ``` sudo virsh net-start default ``` obj-y (in kernel) obj-m (module) https://hackmd.io/@combo-tw/Linux-%E8%AE%80%E6%9B%B8%E6%9C%83/%2F%40combo-tw%2FBJPoAcqQS [install qemu-kvm](https://medium.com/codemonday/setup-virt-manager-qemu-libvert-and-kvm-on-ubuntu-20-04-fa448bdecde3) ``` sudo apt install libvirt-daemon-driver-lxc ``` https://askubuntu.com/questions/858649/how-can-i-copypaste-from-the-host-to-a-kvm-guest ``` make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop. make: *** [Makefile:1809: certs] Error 2 # solution scripts/config --disable SYSTEM_TRUSTED_KEYS scripts/config --disable SYSTEM_REVOCATION_KEYS ``` ```sh # in gust os sudo apt install spice-vdagent ``` ## KVM qemu https://github.com/jedi4ever/veewee/issues/996 ``` # /etc/libvirt/qemu.conf user = "wasabi-neko" group = "wasabi-neko" ``` mode: squash ``` sudo mount -t 9p -o trans=virtio /sharepoint ~/share ``` ## fedora preparation ```sh sudo dnf group install "Development Tools" sudo dnf install ncurses-devel bison flex elfutils-libelf-devel openssl-devel ``` ``` sudo dnf install dwarves ``` ### problem when compiling kernel https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8 disable most of the modules ``` ld: arch/x86/entry/syscall_64.o:(.rodata+0xe08): undefined reference to `__x64_sys_hello_world' BTF .btf.vmlinux.bin.o ``` https://stackoverflow.com/questions/68413677/kernel-make-generates-ld-arch-x86-entry-syscall-64-o-rodata0xdc0-undefine ``` make menuconfig make -j8 # i should able do it on host sudo make modules_install -j8 sudo make install -j8 sudo reboot now ``` ``` make -j12 1148.20s user 124.99s system 882% cpu 2:24.21 total ``` ### 第三次 成功 install 進去 新的 kernel 但是 hello_world 一值出問題 ### 第四次 嘗試在 host compile kernel 然後在 guest make install 在 host compile 只需要 25m36sec 出現 libcrpt.o file not found error & xxxx error 一段時間後進入 emergency mode 等等查查看這個 bug,以及把 security option 關掉看看 ### 5 compile directily on my machine hope my computer won't catch on fire after this https://askubuntu.com/questions/1329538/compiling-the-kernel-5-11-11 ```bash $ sudo make install -j12 ... Error! Bad return status for module build on kernel: 5.15.77 (x86_64) Consult /var/lib/dkms/nvidia/520.56.06/build/make.log for more information. ``` ```bash $ uname -r 5.15.0-52-generic ``` tyring compile the linux-5.15.77 ```bash $ view /var/lib/dkms/nvidia/520.56.06/build/make.log DKMS make.log for nvidia-520.56.06 for kernel 5.15.77 (x86_64) Sun 06 Nov 2022 04:37:27 AM CST make[1]: warning: -j12 forced in submake: resetting jobserver mode. Makefile:18: /Kbuild: No such file or directory make[1]: *** No rule to make target '/Kbuild'. Stop. ``` Maybe just nvidia driver's problem. make install anyway The Most scary part is comming... `sudo reboot now` #### NICE it dead ``` The initrd is too big ... ... [ end kernel panic not syncing:VFS: Unable to mount root fs on unkown-block] ``` use grub to boot my old 15.15.0, and try to fix it ``` # in /etc/initramfs-tools/initramfs.conf, Change "MODULES=most" to "MODULES=dep" update-initramfs -u -k all ``` IT WORKS !!! the version is now 5.15.77 and ofcourse nvidia driver i broken ### add hello world syscall 跟著接學做 稍微刪減一些不會用到的功能後 build ``` ld: arch/x86/entry/syscall_64.o:(.rodata+0xa78): undefined reference to `__x64_sys_hello_world' ld: arch/x86/entry/syscall_x32.o:(.rodata+0xa78): undefined reference to `__x64_sys_hello_world' BTF .btf.vmlinux.bin.o pahole: .tmp_vmlinux.btf: No such file or directory LD .tmp_vmlinux.kallsyms1 .btf.vmlinux.bin.o: file not recognized: file format not recognized make: *** [Makefile:1216: vmlinux] Error 1 ``` https://dev.to/jasper/adding-a-system-call-to-the-linux-kernel-5-8-1-in-ubuntu-20-04-lts-2ga8 this version using 5.x https://www.kernel.org/doc/html/latest/process/adding-syscalls.html#designing-the-api-planning-for-extension the offical doc? can't understand at all kernel panic not syncing attempted to kill init! ### 嘗試單獨消減 module build 成功 看來 nvidia driver 每次 compile 都會爆炸,不過裝好之後再重裝就 ok 了 ### 嘗試加入 hello_world syscall 改成 449 問題:should i make clean? https://hackmd.io/@PIFOPlfSS3W_CehLxS3hBQ/S14tx4MqP ### check vm-area_struct 用 `get_pid_task` 取得當前 process 的 `task_struct` `task_struct->mmstruct.mmap->vm_area_struct` ![](https://i.imgur.com/PwkAo9J.png) ![](https://i.imgur.com/LnKgOM5.png) ![](https://i.imgur.com/XqFGuNF.png) ### Write a script to find informations of segment 從之前寫好的 system call 可以得知每個 segment 的 `start address`, `end address`, `size`, `flag` 和 `prot` 等資訊,但是還不清楚 segment 實際上所對應的是 process 的哪個部分。 而從原本的 multithread program 的實驗結果可以看到各個變數所在的記憶體位置,並且也可以查看兩者的 segment 有哪些是共用的。 ![](https://i.imgur.com/KHPFiZU.png) 有了這些資訊,接下來就可以寫一個簡單的 script 來比對資訊,並且輸出 segment 對應關係的 table。 ```= Hello World! size: 00001000, start: 55a8ad927000, end: 55a8ad928000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 55a8ad928000, end: 55a8ad929000, flag: 8000075, prot: 0000000000000025 <-main_text, thread1_text, thread2_text size: 00001000, start: 55a8ad929000, end: 55a8ad92a000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 55a8ad92a000, end: 55a8ad92b000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 55a8ad92b000, end: 55a8ad92c000, flag: 8100073, prot: 8000000000000025 <-bss, data size: 00021000, start: 55a8ae20b000, end: 55a8ae22c000, flag: 8100073, prot: 8000000000000025 <-main_heap size: 00021000, start: 7f81f8000000, end: 7f81f8021000, flag: 8200073, prot: 8000000000000025 <-thread1_heap, thread2_heap size: 03fdf000, start: 7f81f8021000, end: 7f81fc000000, flag: 8200070, prot: 0000000000000120 size: 00001000, start: 7f81fca1b000, end: 7f81fca1c000, flag: 8000070, prot: 0000000000000120 size: 00800000, start: 7f81fca1c000, end: 7f81fd21c000, flag: 8100073, prot: 8000000000000025 <-thread2_stack size: 00003000, start: 7f81fd21c000, end: 7f81fd21f000, flag: 8000071, prot: 8000000000000025 size: 00012000, start: 7f81fd21f000, end: 7f81fd231000, flag: 8000075, prot: 0000000000000025 size: 00004000, start: 7f81fd231000, end: 7f81fd235000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f81fd235000, end: 7f81fd236000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f81fd236000, end: 7f81fd237000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f81fd237000, end: 7f81fd238000, flag: 8000070, prot: 0000000000000120 size: 00803000, start: 7f81fd238000, end: 7f81fda3b000, flag: 8100073, prot: 8000000000000025 <-thread1_stack size: 00022000, start: 7f81fda3b000, end: 7f81fda5d000, flag: 8000071, prot: 8000000000000025 size: 00178000, start: 7f81fda5d000, end: 7f81fdbd5000, flag: 8000075, prot: 0000000000000025 size: 0004e000, start: 7f81fdbd5000, end: 7f81fdc23000, flag: 8000071, prot: 8000000000000025 size: 00004000, start: 7f81fdc23000, end: 7f81fdc27000, flag: 8100071, prot: 8000000000000025 size: 00002000, start: 7f81fdc27000, end: 7f81fdc29000, flag: 8100073, prot: 8000000000000025 size: 00004000, start: 7f81fdc29000, end: 7f81fdc2d000, flag: 8100073, prot: 8000000000000025 size: 00006000, start: 7f81fdc2d000, end: 7f81fdc33000, flag: 8000071, prot: 8000000000000025 size: 00011000, start: 7f81fdc33000, end: 7f81fdc44000, flag: 8000075, prot: 0000000000000025 size: 00006000, start: 7f81fdc44000, end: 7f81fdc4a000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f81fdc4a000, end: 7f81fdc4b000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f81fdc4b000, end: 7f81fdc4c000, flag: 8100073, prot: 8000000000000025 size: 00006000, start: 7f81fdc4c000, end: 7f81fdc52000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f81fdc6e000, end: 7f81fdc6f000, flag: 8000071, prot: 8000000000000025 size: 00023000, start: 7f81fdc6f000, end: 7f81fdc92000, flag: 8000075, prot: 0000000000000025 size: 00008000, start: 7f81fdc92000, end: 7f81fdc9a000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f81fdc9b000, end: 7f81fdc9c000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f81fdc9c000, end: 7f81fdc9d000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f81fdc9d000, end: 7f81fdc9e000, flag: 8100073, prot: 8000000000000025 size: 00021000, start: 7ffe943af000, end: 7ffe943d0000, flag: 0100173, prot: 8000000000000025 <-main_stack size: 00004000, start: 7ffe943f3000, end: 7ffe943f7000, flag: c044411, prot: 8000000000000025 size: 00002000, start: 7ffe943f7000, end: 7ffe943f9000, flag: 8040075, prot: 0000000000000025 ``` 另一種取得 vm_area 的方法: ``` $ cat /proc/$pid/maps ``` ```= #address perms offset device inode pathname 5595acc05000-5595acc06000 r--p 00000000 103:0a 530447 /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out 5595acc06000-5595acc07000 r-xp 00001000 103:0a 530447 /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out 5595acc07000-5595acc08000 r--p 00002000 103:0a 530447 /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out 5595acc08000-5595acc09000 r--p 00002000 103:0a 530447 /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out 5595acc09000-5595acc0a000 rw-p 00003000 103:0a 530447 /home/wasabi-neko/Documents/NCU/2022-autumn/linux/project/test-thread/hello2.out 5595ad1aa000-5595ad1cb000 rw-p 00000000 00:00 0 [heap] 7f6e18000000-7f6e18021000 rw-p 00000000 00:00 0 7f6e18021000-7f6e1c000000 ---p 00000000 00:00 0 7f6e20000000-7f6e20021000 rw-p 00000000 00:00 0 7f6e20021000-7f6e24000000 ---p 00000000 00:00 0 7f6e26b2d000-7f6e26b2e000 ---p 00000000 00:00 0 7f6e26b2e000-7f6e2732e000 rw-p 00000000 00:00 0 7f6e2732e000-7f6e2732f000 ---p 00000000 00:00 0 7f6e2732f000-7f6e27b32000 rw-p 00000000 00:00 0 7f6e27b32000-7f6e27b54000 r--p 00000000 103:0a 6948009 /usr/lib/x86_64-linux-gnu/libc-2.31.so 7f6e27b54000-7f6e27ccc000 r-xp 00022000 103:0a 6948009 /usr/lib/x86_64-linux-gnu/libc-2.31.so 7f6e27ccc000-7f6e27d1a000 r--p 0019a000 103:0a 6948009 /usr/lib/x86_64-linux-gnu/libc-2.31.so 7f6e27d1a000-7f6e27d1e000 r--p 001e7000 103:0a 6948009 /usr/lib/x86_64-linux-gnu/libc-2.31.so 7f6e27d1e000-7f6e27d20000 rw-p 001eb000 103:0a 6948009 /usr/lib/x86_64-linux-gnu/libc-2.31.so 7f6e27d20000-7f6e27d24000 rw-p 00000000 00:00 0 7f6e27d24000-7f6e27d25000 r--p 00000000 103:0a 6953248 /usr/lib/x86_64-linux-gnu/libdl-2.31.so 7f6e27d25000-7f6e27d27000 r-xp 00001000 103:0a 6953248 /usr/lib/x86_64-linux-gnu/libdl-2.31.so 7f6e27d27000-7f6e27d28000 r--p 00003000 103:0a 6953248 /usr/lib/x86_64-linux-gnu/libdl-2.31.so 7f6e27d28000-7f6e27d29000 r--p 00003000 103:0a 6953248 /usr/lib/x86_64-linux-gnu/libdl-2.31.so 7f6e27d29000-7f6e27d2a000 rw-p 00004000 103:0a 6953248 /usr/lib/x86_64-linux-gnu/libdl-2.31.so 7f6e27d2a000-7f6e27d30000 r--p 00000000 103:0a 6960663 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so 7f6e27d30000-7f6e27d41000 r-xp 00006000 103:0a 6960663 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so 7f6e27d41000-7f6e27d47000 r--p 00017000 103:0a 6960663 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so 7f6e27d47000-7f6e27d48000 r--p 0001c000 103:0a 6960663 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so 7f6e27d48000-7f6e27d49000 rw-p 0001d000 103:0a 6960663 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so 7f6e27d49000-7f6e27d4f000 rw-p 00000000 00:00 0 7f6e27d6b000-7f6e27d6c000 r--p 00000000 103:0a 6947394 /usr/lib/x86_64-linux-gnu/ld-2.31.so 7f6e27d6c000-7f6e27d8f000 r-xp 00001000 103:0a 6947394 /usr/lib/x86_64-linux-gnu/ld-2.31.so 7f6e27d8f000-7f6e27d97000 r--p 00024000 103:0a 6947394 /usr/lib/x86_64-linux-gnu/ld-2.31.so 7f6e27d98000-7f6e27d99000 r--p 0002c000 103:0a 6947394 /usr/lib/x86_64-linux-gnu/ld-2.31.so 7f6e27d99000-7f6e27d9a000 rw-p 0002d000 103:0a 6947394 /usr/lib/x86_64-linux-gnu/ld-2.31.so 7f6e27d9a000-7f6e27d9b000 rw-p 00000000 00:00 0 7fff30d81000-7fff30da2000 rw-p 00000000 00:00 0 [stack] 7fff30de5000-7fff30de9000 r--p 00000000 00:00 0 [vvar] 7fff30de9000-7fff30deb000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] ``` 推測有 inode 的 segment 為該 file map 來 memory 的。 ```bash $ ls -i /usr/lib/x86_64-linux-gnu/libc-2.31.so 6948009 ``` vm_flag in `include/linux/mm.h` ``` #define VM_NONE 0x00000000 #define VM_READ 0x00000001 /* currently active flags */ #define VM_WRITE 0x00000002 #define VM_EXEC 0x00000004 #define VM_SHARED 0x00000008 #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ #define VM_UFFD_MISSING 0x00000200 /* missing pages tracking */ #define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ #define VM_UFFD_WP 0x00001000 /* wrprotect pages tracking */ #define VM_LOCKED 0x00002000 #define VM_IO 0x00004000 /* Memory mapped I/O or similar */ /* Used by sys_madvise() */ #define VM_SEQ_READ 0x00008000 /* App will access data sequentially */ #define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */ #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ #define VM_LOCKONFAULT 0x00080000 /* Lock the pages covered when they are faulted in */ #define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */ #define VM_NORESERVE 0x00200000 /* should the VM suppress accounting */ #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_SYNC 0x00800000 /* Synchronous page faults */ #define VM_ARCH_1 0x01000000 /* Architecture-specific flag */ #define VM_WIPEONFORK 0x02000000 /* Wipe VMA contents in child. */ #define VM_DONTDUMP 0x04000000 /* Do not include in the core dump */ ``` ==TODO:== how about page info ?? check `/proc/$pid/status` https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html 可以觀察出: thread1 and thread2 位於不同 vm area thread1 thread2 heap 位於同一個 vm area, 但是與 main 位於不同 area !!! 在後來幾次跑程式的時候發現 thread1_heap and thread2_heap might not be in same segment ```= Hello World! size: 00001000, start: 55a37da32000, end: 55a37da33000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 55a37da33000, end: 55a37da34000, flag: 8000075, prot: 0000025 <-main_text, thread1_text, thread2_text size: 00001000, start: 55a37da34000, end: 55a37da35000, flag: 8000071, prot: 8000000000000025 <-.rodata size: 00001000, start: 55a37da35000, end: 55a37da36000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 55a37da36000, end: 55a37da37000, flag: 8100073, prot: 8000000000000025 <-bss, data size: 00021000, start: 55a37f214000, end: 55a37f235000, flag: 8100073, prot: 8000000000000025 <-main_heap, main_big_heap size: 00021000, start: 7f8c64000000, end: 7f8c64021000, flag: 8200073, prot: 8000000000000025 <-thread2_smol_heap, thread2_big_heap size: 03fdf000, start: 7f8c64021000, end: 7f8c68000000, flag: 8200070, prot: 0000120 size: 00001000, start: 7f8c6b7ff000, end: 7f8c6b800000, flag: 8000070, prot: 0000120 size: 00800000, start: 7f8c6b800000, end: 7f8c6c000000, flag: 8100073, prot: 8000000000000025 <-thread2_stack size: 00021000, start: 7f8c6c000000, end: 7f8c6c021000, flag: 8200073, prot: 8000000000000025 <-thread1_smol_heap, thread1_big_heap size: 03fdf000, start: 7f8c6c021000, end: 7f8c70000000, flag: 8200070, prot: 0000120 size: 00001000, start: 7f8c70329000, end: 7f8c7032a000, flag: 8000070, prot: 0000120 size: 00803000, start: 7f8c7032a000, end: 7f8c70b2d000, flag: 8100073, prot: 8000000000000025 <-thread1_stack size: 00022000, start: 7f8c70b2d000, end: 7f8c70b4f000, flag: 8000071, prot: 8000000000000025 size: 00178000, start: 7f8c70b4f000, end: 7f8c70cc7000, flag: 8000075, prot: 0000025 <-libc size: 0004e000, start: 7f8c70cc7000, end: 7f8c70d15000, flag: 8000071, prot: 8000000000000025 size: 00004000, start: 7f8c70d15000, end: 7f8c70d19000, flag: 8100071, prot: 8000000000000025 size: 00002000, start: 7f8c70d19000, end: 7f8c70d1b000, flag: 8100073, prot: 8000000000000025 <-libc-var size: 00004000, start: 7f8c70d1b000, end: 7f8c70d1f000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f8c70d1f000, end: 7f8c70d20000, flag: 8000071, prot: 8000000000000025 size: 00002000, start: 7f8c70d20000, end: 7f8c70d22000, flag: 8000075, prot: 0000025 size: 00001000, start: 7f8c70d22000, end: 7f8c70d23000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f8c70d23000, end: 7f8c70d24000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f8c70d24000, end: 7f8c70d25000, flag: 8100073, prot: 8000000000000025 size: 00006000, start: 7f8c70d25000, end: 7f8c70d2b000, flag: 8000071, prot: 8000000000000025 size: 00011000, start: 7f8c70d2b000, end: 7f8c70d3c000, flag: 8000075, prot: 0000025 size: 00006000, start: 7f8c70d3c000, end: 7f8c70d42000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f8c70d42000, end: 7f8c70d43000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f8c70d43000, end: 7f8c70d44000, flag: 8100073, prot: 8000000000000025 size: 00006000, start: 7f8c70d44000, end: 7f8c70d4a000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f8c70d66000, end: 7f8c70d67000, flag: 8000071, prot: 8000000000000025 size: 00023000, start: 7f8c70d67000, end: 7f8c70d8a000, flag: 8000075, prot: 0000025 size: 00008000, start: 7f8c70d8a000, end: 7f8c70d92000, flag: 8000071, prot: 8000000000000025 size: 00001000, start: 7f8c70d93000, end: 7f8c70d94000, flag: 8100071, prot: 8000000000000025 size: 00001000, start: 7f8c70d94000, end: 7f8c70d95000, flag: 8100073, prot: 8000000000000025 size: 00001000, start: 7f8c70d95000, end: 7f8c70d96000, flag: 8100073, prot: 8000000000000025 size: 00021000, start: 7fffbb3b5000, end: 7fffbb3d6000, flag: 0100173, prot: 8000000000000025 <-main_stack, argv, env size: 00004000, start: 7fffbb3d7000, end: 7fffbb3db000, flag: c044411, prot: 8000000000000025 size: 00002000, start: 7fffbb3db000, end: 7fffbb3dd000, flag: 8040075, prot: 0000025 ``` ``` libc 0x7f8c70b73a40 libc-var 0x7f8c70d1a6a0 main_stack 0x7fffbb3d3648 main_heap 0x55a37f2142a0 main_big_heap 0x55a37f2142a0 main_text 0x55a37da33309 bss 0x55a37da36030 data 0x55a37da36010 .rodata 0x55a37da34004 argv 0x7fffbb3d3798 env 0x7fffbb3d58c5 thread1_stack 0x7f8c70b28ed4 thread1_smol_heap 0x7f8c6c000b80 thread1_big_heap 0x7f8c6c000b60 thread1_text 0x55a37da33320 thread2_stack 0x7f8c6bffeed4 thread2_smol_heap 0x7f8c64000b80 thread2_big_heap 0x7f8c64000b60 thread2_text 0x55a37da33320 ``` ```c= #define _GNU_SOURCE /* for RTLD_NEXT */ #include <dlfcn.h> #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> #include <string.h> const int global_constant = 0xc8763; // .rodata char global_str[] = "Global Str."; // Data segment char global_var; // Bss segment void (*func_ptr)(); void foo() { // Text segment printf("foo func here!\n"); } void* func4thread1(void *arg) { int local = 0xdeadbeef; int *smol_heap_ptr = (int*) malloc(5); int *big_heap_ptr = (int*) malloc(10000); smol_heap_ptr[0] = 0xc8763; big_heap_ptr[0] = 0xc8763; // func_ptr = foo; // printf("This is thread1.\n"); printf("thread1_stack %p\n", &local); printf("thread1_smol_heap %p\n", big_heap_ptr); printf("thread1_big_heap %p\n", smol_heap_ptr); printf("thread1_text %p\n", func4thread1); // printf("Address of global_str \"%s\": %p\n", global_str, global_str); // printf("Address of global_var: %p\n", &global_var); // printf("Address of foo: %p\n", func_ptr); // printf("Address of str_in_heap \"%s\": %p\n", (char *)arg, arg); fflush(stdout); sleep(100000); pthread_exit(NULL); } void* func4thread2(void *arg) { int local = 0xdeadbeef; int *smol_heap_ptr = (int*) malloc(5); int *big_heap_ptr = (int*) malloc(10000); // func_ptr = foo; // printf("This is thread2.\n"); printf("thread2_stack %p\n" , &local); printf("thread2_smol_heap %p\n", big_heap_ptr); printf("thread2_big_heap %p\n", smol_heap_ptr); printf("thread2_text %p\n", func4thread1); // printf("Address of global_str \"%s\": %p\n", global_str, global_str); // printf("Address of global_var: %p\n", &global_var); // printf("Address of foo: %p\n", func_ptr); // printf("Address of str_in_heap \"%s\": %p\n", (char *)arg, arg); fflush(stdout); sleep(10000); pthread_exit(NULL); } int main(int argc, char **argv) { pid_t pid = getpid(); pthread_t t1, t2; char str[] = "str in heap."; char *str_in_heap = (char *)malloc(sizeof(char) * 12); char *big_str_in_heap = (char *)malloc(sizeof(char) * 1000); strncpy(str_in_heap, str, 12); void (*exit_addr)(int) = dlsym(RTLD_NEXT, "exit"); char *env_home = getenv("HOME"); printf("libc %p\n", exit_addr); printf("libc-var %p\n", stdout); printf("main_stack %p\n", &pid); printf("main_heap %p\n", str_in_heap); printf("main_big_heap %p\n", str_in_heap); printf("main_text %p\n", foo); // printf("main_heap2 %p\n", heap_ptr); printf("bss %p\n", &global_var); printf("data %p\n", global_str); printf(".rodata %p\n", &global_constant); printf("argv %p\n", argv); printf("env %p\n", env_home); fflush(stdout); // call the syscall before createing the thread long retval = syscall(449, pid); pthread_create(&t1, NULL, func4thread1, (void *)str_in_heap); sleep(1); pthread_create(&t2, NULL, func4thread2, (void *)str_in_heap); sleep(1); retval = syscall(449, pid); pthread_join(t1, NULL); pthread_join(t2, NULL); // sleep(10000); int a; scanf("%d", &a); return 0; } ``` </br> </br> </br> </br> ### PGD、P4D、PUD、PMD、PTE --- # 不相關 ![](https://upload.wikimedia.org/wikipedia/commons/e/e4/ELF_Executable_and_Linkable_Format_diagram_by_Ange_Albertini.png) what's the diffence between section in elf and segment https://stackoverflow.com/questions/14361248/whats-the-difference-of-section-and-segment-in-elf-file-format ==TODO:== Write a program to translate virtual address into physical address :::info **Basic Idea** 使用 `mm_struct` 中的 `pgd` ::: get_current() pthread 用了哪些 syscall ## Days after ### others There's so many same macros/functions being define in different header files with different impelementation. i'm so confusing rn `syd_get_mem_layout` -> `sys_get_mem_layout` stupid **PCB (processing control block) 通常也稱為 struct tast_struct** Wow idk `taskc_struct` IS PCB ### current ```c // arch/x86/include/asm/current.h static __always_inline struct task_struct *get_current(void) { return this_cpu_read_stable(current_task); } #define current get_current() ``` ```c // arch/x86/include/asm/percpu.h /* * this_cpu_read() makes gcc load the percpu variable every time it is * accessed while this_cpu_read_stable() allows the value to be cached. * this_cpu_read_stable() is more efficient and can be used if its value * is guaranteed to be valid across cpus. The current users include * get_current() and get_thread_info() both of which are actually * per-thread variables implemented as per-cpu variables and thus * stable for the duration of the respective task. */ #define this_cpu_read_stable_1(pcp) percpu_stable_op(1, "mov", pcp) #define this_cpu_read_stable_2(pcp) percpu_stable_op(2, "mov", pcp) #define this_cpu_read_stable_4(pcp) percpu_stable_op(4, "mov", pcp) #define this_cpu_read_stable_8(pcp) percpu_stable_op(8, "mov", pcp) #define this_cpu_read_stable(pcp) __pcpu_size_call_return(this_cpu_read_stable_, pcp) ``` ### virt_to_phys https://linux-kernel-labs.github.io/refs/heads/master/lectures/address-space.html https://zhuanlan.zhihu.com/p/436879901 ```c // this not really work in linux 5.15.77 struct * page; pgd_t pgd; pmd_t pmd; pud_t pud; pte_t pte; void *laddr, *paddr; pgd = pgd_offset(mm, vaddr); pud = pud_offet(pgd, vaddr); pmd = pmd_offset(pud, vaddr); pte = pte_offset(pmd, vaddr); page = pte_page(pte); laddr = page_address(page); paddr = virt_to_phys(laddr); ``` ```c #define __for_each_thread(signal, t) \ list_for_each_entry_rcu(t, &(signal)->thread_head, thread_node) #define for_each_thread(p, t) \ __for_each_thread((p)->signal, t) /* Careful: this is a double loop, 'break' won't work as expected. */ #define for_each_process_thread(p, t) \ for_each_process(p) for_each_thread(p, t) ``` ```c #define list_for_each_entry_rcu(pos, head, member, cond...) \ for (__list_check_rcu(dummy, ## cond, 0), \ pos = list_entry_rcu((head)->next, typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) ``` ### copy kernel to user space keyword: high memory > However, highmem is also used on 64bit systems but the use-case there is mainly to allow arbitrary mappings in kernel space. `void __user *buffer` ```c copy_to_user(user_buffer, ktmp, sizeof(struct my_struct)) copy_from_user(user_buffer, ktmp, sizeof(struct my_struct)) ``` ### pid ? tid? user space 不同 thread 的 pid 一樣, 但是在 kernel space 可以發現他們有不同的 pid ```bash $ ps -H -m | grep hello 17528 pts/0 0 119 1 84574 21144 - 552 - - - ./hello3.out 17528 pts/0 0 6 1 84574 21144 - 552 - - - ./hello3.out 17528 pts/0 0 1 1 84574 21144 - 552 - - - ./hello3.out ``` ```bash $ dmesg [ 1294.741433] pid: 17530, tgid: 17528 [ 1294.741458] pid: 17528, tgid: 17528 [ 1296.741409] pid: 17531, tgid: 17528 ``` 中間發生了什麼事?? ### same vma list ??? 因為 phys 轉出來很奇怪便嘗試分析 thread 間的差異 但是不同 thread 的 task_struct->mm->vma list 居然一樣?? HOW WHY WHAT IDK brain smash detected, code dump kernel panic