2014-12-23 20 views
0

據我瞭解系統控制變量,kernel.printk中的第一個值是內核消息必須小於要寫入控制檯的數量。所以,如果是4,那麼由此產生的消息纔可見與dmesg什麼讓printk()寫入控制檯,即使它以KERN_INFO開頭?

printk(KERN_INFO "This is a kernel message."); 

將出現在控制檯上的消息的唯一情況是如果它是由KERN_ERRKERN_CRITKERN_INFO,或KERN_EMERG前面。即使內核模塊發生問題,我也希望像上面這樣的消息不會出現在我的屏幕上。

我正在嘗試的一件事是系統調用攔截。有些人完美無瑕,其他人沒有。但有幾次,我的不成功的內核模塊標有KERN_INFO的消息堵塞了我的控制檯,並沒有給我足夠的時間在消息之間卸載它們。螺釘向上在這些代碼行中某處出現:

… 
#define INODE_IS_DEVICE(inode) (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) 
#define INODE_IS_RAW(inode) (imajor(inode) == RAW_MAJOR) 
#define INODE_IS_RAW_DEVICE(inode) (INODE_IS_DEVICE(inode) || INODE_IS_RAW(inode)) 
#define TEST_OPEN_FLAGS(flags) ((flags & O_WRONLY) || (flags & O_RDWR)) 
… 
struct inode *current_inode; 
… 
struct inode* get_inode_from_pathname(const char pathname) { 
    struct path path; 
    kern_path(pathname, LOOKUP_FOLLOW, &path); 
    return path.dentry->d_inode; 
} 

asmlinkage int (*real_open)(const char* __user, int, int); 

asmlinkage int custom_open(const char* __user file_name, int flags, int mode) { 
    current_inode = get_inode_from_pathname(file_name); 
    printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode); 
    if (INODE_IS_RAW_DEVICE(inode) && TEST_OPEN_FLAGS(flags)) { 
     printk(KERN_INFO "Intercepted call to write to block device %s.\n", file_name); 
    } 
    return real_open(file_name, flags, mode); 
} 
… 
void hack(void) { 
    make_rw((unsigned_long)sys_call_table); 
    real_open = (void*)*(sys_call_table + __NR_open); 
    *(sys_call_table + __NR_open) = (unsigned_long)custom_open; 
    make_ro((unsigned_long)sys_call_table); 
} 

void restore(void) { 
    make_rw((unsigned_long)sys_call_table); 
    *(sys_call_table + __NR_open) = (unsigned_long)real_open; 
    make_ro((unsigned_long)sys_call_table); 
} 

的代碼make_rwmake_ro是相同的那些發現here。編譯這段代碼給了我沒有任何錯誤,但是加載模塊會導致消息被放到控制檯以及某種類型的崩潰或錯誤。請注意,當代碼裏面custom_open塊替換

printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode); 
    if (file_name == "/dev/sda" && TEST_OPEN_FLAGS(flags)) { 
     printk("Intercepted call to write to block device."); 
     return -EPERM; 
    } 
    return real_open(file_name, flags, mode); 

一切正常,我想它的方式。用print(KERN_INFO "i_mode of %s: %hu\n", file_name, current_inode->i_mode);代替custom_open的控制流程語句會產生完全相同的問題。

我不確定這裏產生的錯誤是什麼。任何見解?

+0

'cat/proc/sys/kernel/printk'說什麼? – Armali

回答

0

內核變量DEFAULT_MESSAGE_LOGLEVEL決定什麼是內核的默認日誌級別。要知道它的當前值是什麼,請檢查內核配置文件中CONFIG_DEFAULT_MESSAGE_LOGLEVEL的值。

這會給你線索爲什麼KERN_INFO要來到終端。

0

注意,那個時候的代碼中custom_open塊被替換 與

printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode); 
    if (file_name == "/dev/sda" && TEST_OPEN_FLAGS(flags)) { 
     printk("Intercepted call to write to block device."); 
     return -EPERM; 
    } 
    return real_open(file_name, flags, mode); 

一切正常,我想它的方式。

你錯了。你看到上面的代碼沒有輸出並不意味着printk不輸出到控制檯;很可能printk從不執行,因爲函數參數file_name很可能不會指向字符串文字"/dev/sda"的內存位置 - 請記住,要比較字符串,將使用strcmp

+1

'dmesg'的輸出說不然。它顯示在內核日誌緩衝區中,在這種情況下它不會打印到控制檯/終端。 – Melab

相關問題