- 論壇徽章:
- 0
|
系統(tǒng)調(diào)用跳轉(zhuǎn)表 sys_call_table[] 一個函數(shù)指針數(shù)組
所有表中不支持的系統(tǒng)調(diào)用號,全部指向sys_ni_call()(僅返回出錯代碼-ENOSYS)
宏調(diào)用GET_CURRENT(%ebx)使%ebx指向當(dāng)前進程的task_struct,然后檢查%eax中的系統(tǒng)調(diào)用號是否超出范圍。
task_struct結(jié)構(gòu)中有字段flags,其中有一標(biāo)志位PT_TRACESYS,一個進程可通過系統(tǒng)調(diào)用ptrace()將一個子進程的該標(biāo)志位設(shè)置為1,從而跟中該子進程的系統(tǒng)調(diào)用(系統(tǒng)命令strace即如此)。
------------------------
系統(tǒng)調(diào)用返回時,會檢查返回值(%eax),若處于-1~-4095之間,則表示出錯,轉(zhuǎn)向__syscall_error()(libc.a)
在__syscall_error()中
1. %eax 取負(fù)值 ---> 堆棧
2. __errno_location() 全局errono地址 ---> %eax
3. 堆棧 : 出錯代碼 ---> %ecx
---> 全局errono
4. -1 改寫 ---> %eax
-----------------------------------------------------------
以sethostname調(diào)用做例子
asmlinkage long sys_sethostname(char* name, int len)
{
...
/*
sethostname是特權(quán)用戶才可進行的操作,所以一開始就做權(quán)限檢查
capable(CAP_SYS_ADMIN)檢查當(dāng)前進程是否有CAP_SYS_ADMIN的授權(quán)
*/
if( !capable(CAP_SYS_ADMIN) )
return -EPERM;
//檢查字符串長度
if( len __NEW_UTS_LEN )
return -EINVAL;
//sethostname要操作的是臨界區(qū),這里在操作前,必須加信號量,防止race condition出現(xiàn)
down_write(&uts_sem);
...
up_write(&uts_sem);
/*
在以上的臨界區(qū)操作中,使用了宏調(diào)用copy_from_user(to,from,n):
copy_from_user(system_utsname.nodename, name, len)
*/
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u3/109164/showart_2137213.html |
|