2011-12-10 19 views
1

私はシンプルな質問があります:構造体の内容をユーザー空間からカーネル空間にコピーする必要がある場合(例:ioctl呼び出し(またはviceversa)):copy_to_userと構造体を持つcopy_from_user

typedef struct my_struct{ 
int a; 
char b; 
} my_struct; 

ユーザ空間:

my_struct s; 
s.a = 11; 
s.b = 'X'; 

ioctl(fd, MY_CMD, &s); 

Kernelspace:

int my_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 
      unsigned long arg) 
{ 
... 
    my_struct ks; 
    copy_from_user(&ks, (void __user *)arg, sizeof(ks)); 
... 
} 

私はSTの大きさを考えますユーザー空間(変数s)とカーネル空間(変数ks)のルーキールは同じではない可能性があります(__attribute__((packed))を指定せずに)。だからcopy_from_userのバイト数をsizeofマクロで指定するのは正しいですか?カーネルソースには、パックされていると宣言されていない構造がいくつかありますが、サイズがユーザー空間とカーネル空間で同じになることはどうして保証されていますか?

ありがとうございました!

答えて

1

なぜ構造体のレイアウトは、カーネル空間とユーザー空間とで異なるのですか?コンパイラがデータを異なる方法でレイアウトする理由はありません。 userspaceが64ビットカーネル上で動作する32ビットプログラムである場合は例外です。チュートリアルについては、これに対処する方法についてはhttp://www.x86-64.org/pipermail/discuss/2002-June/002614.htmlを参照してください。

+1

たとえば、アプリケーションをコンパイルしてカーネルを構築し、構造体をパックすることを選択したアプリケーションをコンパイルします。しかし、リンクをありがとう!非常に面白いです... – MirkoBanchi

+2

事実、構造体とそのレイアウトは、カーネルによって定義されたカーネルABIの一部です。 これは実際にはioctl()インタフェースの破壊の良い例です。 –

+0

構造体が特定の方法でメモリにレイアウトされていると仮定するのは一般的に安全ではありませんか? – Cuadue

1

ユーザ空間構造はカーネルヘッダから来るべきであるので、構造体の定義はユーザ空間とカーネル空間で同じにする必要があります。本当の例はありますか?

もちろん、ABIの2つの側面で異なる梱包オプションを使用してプレイする場合は、何でも問題になります。ここの問題はサイズではありません。

質問がある場合:パッキングオプションはバイナリインターフェイスに影響しますか?回答はyesです。 質問があれば、パッキングの不一致を解決するにはどうすればいいですか詳細情報を提供してください

+0

最初の例は、 'my_struct vec [2]'と '-fpack-struct'スイッチでビルドされた2つの構造のベクトルを定義するuserspaceアプリケーションです。カーネルモジュール( 'my_ioctl'が定義されている)がビルドされている場合、コンパイラは構造体をパックしません(これはおそらく)' sizeof(my_struct) 'を第3引数として呼び出された' copy_to_user'と、 'vec'は最初の引数として、ユーザ空間変数' vec'に2番目の項目も書き出します。私は正しい? – MirkoBanchi

+0

@MirkoBanchi:yes – shodanex

+0

おそらく質問かもしれません:ユーザスペースアプリケーションを構築すると、コンパイラは '-fpack-struct'フラグを付けずにカーネルをコンパイルするのとは異なる方法で構造体をパックすることもできるでしょうか?そして: 'my_struct'が' ioctl'システムコールで使用できることをコンパイラがどのように知っていますか?ありがとうshodanex! – MirkoBanchi

関連する問題