C言語の再履修シリーズ。
DCL39-C. 信頼境界を越えて構造体を渡すとき情報漏えいしない
https://www.jpcert.or.jp/sc-rules/c-dcl39-c.html
何を言っているのかなかなかわからなかったが、たぶんこういうことだろう。
- 構造体や共用体では、メンバ間にパディングが入ることがある
- ビットフィールドでも、ビットのパディングが入ることがある
- パディングの値は不定
- 不定ゆえに、メンバの書き換えを行う場合にどういう値が入るかも不定
- そのため、意図していない有用なデータが書き込まれるかもしれない
問題は、最後の部分だ。
いきなり文章が飛躍しているが、タイトルの通り気にするのは「信頼境界」で、例で上がっている「カーネルとユーザスペース間」のような、カーネルからユーザスペースに値を渡すときに、情報を漏らしてはいけないのにカーネル側から漏れてしまうことを懸念している。
memset()の例では、4byteアラインメント(レジスタも4byte)だとして、構造体メンバの真ん中に1byteのメンバがいる。
ここの書き換えを行うときに「どうせ1byteしか見ないからいいや」とコンパイラが判断して、1byteのメンバ分のレジスタしか書き換えず、残りの3byteはそのままで、しかも書込みは4byteで行ったりすると、レジスタの残り3byteはそのときの値を残したままなので、ユーザスペースに渡すデータに書き込まれてしまう、と。
えー、そんなことまで考慮しないといけないのぉ。。。
対策案としてあげてあるコードは、構造体メンバをシリアライズしてユーザスペースに渡して、向こう側で構造体に戻す、というものだ。
つまりまあ、機器間で通信データを作ってやりとりするようなものですな。
ここまでやるんですなぁ。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。