有一天我編譯內核模塊驅動的時候發現如下錯誤 Linux kernel版本:4.1.15 代碼如下: 當我做這樣的修改後: 編譯就不報錯了 這樣讓我很是奇怪,接下來咱們跟入代碼一看究竟 首先我們看下__ATTR的實現: 繼續跟入,我們發現如下的演算法,顯而易見,此版本的內核對許可權做了一個小小的演算法,如下 ...
有一天我編譯內核模塊驅動的時候發現如下錯誤
Linux kernel版本:4.1.15
error: negative width in bit-field '<anonymous>'
代碼如下:
static struct device_attribute sysfs_keypad_list[] = { __ATTR(virt_key, 0666, keypad_show_error, keypad_virt_key_store), };
當我做這樣的修改後:
static struct device_attribute sysfs_keypad_list[] = { __ATTR(virt_key, 0665, keypad_show_error, keypad_virt_key_store), };
編譯就不報錯了
這樣讓我很是奇怪,接下來咱們跟入代碼一看究竟
首先我們看下__ATTR的實現:
繼續跟入,我們發現如下的演算法,顯而易見,此版本的內核對許可權做了一個小小的演算法,如下演算法大家可以寫一個簡單的c代碼進行解讀
當我傳入perms=0x666的時候,BUILD_BUG_ON_ZERO(perms & 2) 這個會報錯,因為如下:
為什麼 BUILD_BUG_ON_ZERO( (0x666) & 2 )會報錯呢?
我們可以寫這樣的代碼來驗證一下:
#include <stdio.h> int main() { struct a { int: -1; }; return 0; }
運行:
出現了同樣的錯誤,那麼我們應該明白了吧,gcc會在編譯的時候對位域的定義進行檢查,struct {int: -1}這樣的定義編譯器會認為是錯誤的
那至於為什麼會列印這樣的錯誤呢?這就需要對編譯器進行瞭解了,也就是編譯器是如何檢查結構體位域的定義的,這塊我沒有深入研究過
如有人有這塊的資料和信息歡迎評論和分享。
如下引用一段話,摘自網上(https://stackoverflow.com/questions/31395602/giving-s-iwugo-permission-to-module-parameter-results-in-compilation-error-whil)
Linux probably refuses to make module parameters world-writable for security reasons.
You should be able to use narrower permissions such as S_IWUSR | S_IWGRP
通俗的理解就是內核希望這樣做的安全一點,減少其他組的寫許可權,體現在 BUILD_BUG_ON_ZERO(perms & 2)這個設計上
那麼我們如何修改呢?
有如下兩種方式的思路給大家借鑒:
第一種:
這樣設計的思路是為了遵循作者的思想,保障安全(但__ATTR這個巨集的用法不同版本是有差別的在這塊,比如說3.6.5的版本是不會檢查這個許可權問題的)
static struct device_attribute sysfs_keypad_list[] = { __ATTR(virt_key, 0664, keypad_show_error, keypad_virt_key_store), };
第二種:
這樣設計的思路是因為搞驅動開發的相信大家都清楚,如果這個介面是我們曾經釋放出去的,開放了這樣的許可權
那麼我們後期開發的時候必須相容之前的介面設計,不能這樣隨意的更改許可權,因為如果你修改了,某個客戶之前有這樣子使用許可權的話,你改了許可權後,他可能就用不了了,
因此我們可以做如下處理,思路就是我們自己定義,不使用內核的設計
#undef __ATTR #define __ATTR(_name, _mode, _show, _store) { \ .attr = {.name = __stringify(_name), \ .mode = _mode}, \ .show = _show, \ .store = _store, \ } static struct device_attribute sysfs_keypad_list[] = { __ATTR(virt_key, 0666, keypad_show_error, keypad_virt_key_store), };
分析如上,如有描述不准確的地方還請告知,Thanks