# Linux 作業系統 作業二(Namespace) ## Team 5 + 108522028 謝明諺 + 108522041 李文郁 + 104502509 李唯源 ## 開發環境和版本資訊 + Virtual Machine: Virtual Box + Linux Release: Ubuntu 16.04 (32-bit) + Kernel Version: Linux-3.9.1 (32-bit no PAE) ## 加入 system call ```shell= sudo apt-get install libncurses5-dev cd ~/linux-3.9.1 mkdir proj2_1 cd proj2_1 vim hw1.c並寫入自訂的system call function vim Makefile 並寫入 obj-y := hw1.o cd ~/linux-3.9.1 mkdir proj2_2 cd proj2_2 vim hw2.c並寫入自訂的system call function vim Makefile 並寫入 obj-y := hw2.o cd ~/linux-3.9.1/arch/x86/syscalls vim syscall_32.tbl 裡加入在最後兩行 351 i386 get_process_zero_session_group sys_get_process_zero_session_group 352 i386 get_process_session_group sys_get_process_session_group cd ~/linux-3.9.1/include/linux vim syscalls.h 裡加入在最後一行 asmlinkage int sys_get_process_zero_session_group(unsigned int *result,int size) asmlinkage int sys_get_process_session_group(unsigned int *result,int size) 重啟動電腦後選擇 3.9.1 kernel version ``` ## 編譯linux kernel步驟 ```shell= cd ~/linux-3.9.1 sudo make menuconfig sudo make -j8 sudo make modules_install sudo make install sudo update-grub ``` ## HW Result ### get_process_zero_session_group * 左邊是syscall輸出的結果,右邊是用`ps -afej`來驗證結果 * [result.txt](https://drive.google.com/file/d/1YDtbSBjT5bW3-obmdMOdNefxaVcqpfJm/view?usp=sharing) ![sys_get_process_zero_session_group](https://i.imgur.com/cnFalx2.jpg) ### get_process_session_group * 在執行get_process_session_group這個syscall的那支process跟他相同login session的process只有我的shell(zsh),又兩個沒有在第二層之後的namespace,所以local pid = global pid * 圖左上是user program執行結果 * 圖左下是用demsg直接看由printk輸出的資料 * 圖右邊是`ps -afej`來驗證結果 * [result2.txt](https://drive.google.com/file/d/16N2DylFHt5vIeHoTP7VvlQgPDduAReot/view?usp=sharing) ![sys_get_process_session_group](https://i.imgur.com/3y8WKVk.jpg) ### get_process_session_group (a namespace test) * 由於單純使用`get_process_session_group`看不出namespace結果,所以我自己寫了一個簡單驗證local pid的program驗證`get_process_session_group`是否正確,這支program會建一個namespace然後這個namespace底下會有四個process * 圖左上是user program執行結果,建了一個pid namespace,有四個process在這個namespace中 * 圖左下是用`ps -afej`來驗證是否在同個login session底下 * 圖右邊是用printk直接看syscall輸出的資料 ![sys_get_process_session_group](https://i.imgur.com/mcu6Z6E.jpg) ## kernel function code + syscall : sys_get_process_zero_session_group ```cpp= #include<linux/init.h> #include<linux/kernel.h> #include<linux/module.h> #include<linux/sched.h> #include<asm/io.h> #include<linux/init_task.h> asmlinkage int sys_get_process_zero_session_group(unsigned int *result,int size) { struct pid_link *first; struct pid_link *lnext; int *ptr2pid = 0; int tmp = 0; int n = 0; printk("[*] init_task PID : %d\n",init_task.pid); first = (struct pid_link *)(init_task.pids[0].pid->tasks[2].first); tmp = first; tmp = tmp - 80; ptr2pid = tmp; printk("[+] PID : %d \n",*ptr2pid); //result[n] = ptr2pid; //n++; lnext = first->node.next; while(lnext) { tmp = lnext; tmp = tmp - 80; ptr2pid = tmp; printk("[+] PID : %d \n",*ptr2pid); if(n < size){ result[n] = *ptr2pid; n++; } lnext = lnext->node.next; } return n; } ``` + syscall : sys_get_process_session_group ```cpp= #include<linux/init.h> #include<linux/kernel.h> #include<linux/module.h> #include<linux/sched.h> #include<asm/io.h> #include<linux/init_task.h> asmlinkage int sys_get_process_session_group(unsigned int *result,int size) { struct pid_link *first; struct pid_link *lnext; struct pid *find_pid; struct task_struct *find_task; pid_t find_pid_t = 0; struct pid_namespace *ns; int *ptr2pid = 0; int tmp = 0; int n = 0; printk("[*] current PID : %d\n",current->pid); find_task = pid_task(find_vpid(current->pid),0); find_pid = task_pid(find_task); find_pid_t = pid_nr_ns(find_pid,task_active_pid_ns(find_task)); printk("[*] current local PID : %d\n",find_pid_t); first = (struct pid_link *)(current->pids[2].pid->tasks[2].first); tmp = first; tmp = tmp - 80; ptr2pid = tmp; printk("[+] PID : %d \n",*ptr2pid); find_task = pid_task(find_vpid(*ptr2pid),0); find_pid = task_pid(find_task); find_pid_t = pid_nr_ns(find_pid,task_active_pid_ns(find_task)); printk("[+] local PID : %d\n",find_pid_t); lnext = first->node.next; while(lnext) { tmp = lnext; tmp = tmp - 80; ptr2pid = tmp; printk("[+] PID : %d \n",*ptr2pid); find_task = pid_task(find_vpid(*ptr2pid),0); find_pid = task_pid(find_task); find_pid_t = pid_nr_ns(find_pid,task_active_pid_ns(find_task)); printk("[+] local PID : %d\n",find_pid_t); lnext = lnext->node.next; } return 0; } ``` ## Test Program + sys_get_process_zero_session_group test program ```cpp= #include<stdio.h> #include<syscall.h> #include<sys/types.h> #include<unistd.h> #define SIZE 100 int main() { unsigned int results[SIZE]; int j,k; k = syscall(351,results, SIZE); if(k){ printf("What follows are the PIDs of the processes that are in the same login sesson of process 0\n"); for(j=0;j<k && j<SIZE;j++) { printf("[%d] %u \n",j,results[j]); } } else { printf("There is an error when executing this system call.\n"); } return 0; } ``` + sys_get_process_session_group test program ```cpp= #include<stdio.h> #include<syscall.h> #include<sys/types.h> #include<unistd.h> #define SIZE 100 int main() { unsigned int results[SIZE]; int j,k; k = syscall(352,results, SIZE); if(k){ printf("What follows are the local PIDs of the processes that are in the same login sesson of this process.\n"); for(j=0;j<k && j<SIZE;j++) { printf("[%d] %u \n",j,results[j]); } } else { printf("There is an error when executing this system call.\n"); } return 0; } ``` + PID namespace test ```cpp= #define _GNU_SOURCE #include <sched.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <signal.h> #include <stdlib.h> #include <errno.h> #define SIZE 100 char child_stack[5000]; int child(void* arg) { int pid; pid = fork(); if(fork()){ printf("clone parent PID : %d\n", getpid()); } else { printf("clone child PID : %d\n", getpid()); } while(1); return 1; } int main() { unsigned int results[SIZE]; int k; int pid; printf("Main Parent PID : %d\n",getpid()); pid = clone(child, child_stack+5000, CLONE_NEWPID, NULL); if (pid == -1) { perror("clone:"); exit(1); } waitpid(pid, NULL, 0); printf("Main child PID : %d\n", pid); sleep(1); k = syscall(352,results, SIZE); // sys_get_process_session_group while(1); return 0; } ```