私は、(小さなライブラリのような)引数として、機密データ(char
配列内)を含むstruct *
ポインタを受け入れる関数を持っています。次のようにモデルは、次のとおり構造体のcharポインタオーバーフローを防ぐ
struct struct1 {
char str[1024]; /* maybe even 4096 or 10KB+ */
size_t str_length;
}
struct struct2 {
char *str;
size_t str_length;
}
テスト関数である:
/* Read str_length bytes from the char array. */
void foo(struct struct1/struct2 *s) {
int i;
for (i = 0; i < s->str_length; i++) {
printf("%c\n", s->str[i]);
}
}
私の懸念はstr_lengthパラメータは任意の値であるので、一方が意図的に設定することができ、ということですバッファオーバーフローを引き起こします(実際には、自分自身のプログラムにセキュリティ上の欠陥を意図的に作成するほど愚かではありますが、そのようなケースを考慮する必要があります)。 struct1モデルを用いて、しかし、私は単純に使用してバッファオーバーフローの可能性をチェックすることもできます
if (s->str_length > sizeof(s->str)) {
/* ERROR */
}
問題は長配列は、コンパイル時に実際に不明であるということです。だから私はchar *
ポインタ(構造体スタイル、のでオーバーフローチェック)を使用するか、最大長(私が避けたいもの)を制限する非常に大きな配列(構造1)を定義するかどうかわからないほとんどの場合、不必要なスペースを割り当てます(これは、希少なメモリを持つ組み込みシステムで問題になる可能性があります)。私は妥協する必要があることを知っている、私は個人的にのstruct2モデルを使用するだろうが、それは良い選択であるかどうかは分かりません。
あなたは、フル機能の範囲チェックが埋め込まれ、ステージコーチをしたい場合、ユーザは、例えば、ポインタを変更した場合、あなたは決定的に何C.を使うべきではありません:ユーザが直接変更する(または唯一のハックの方法で)ことができませんか? – Olaf
慣例ですあなたのlibで使用するための構造体の最後に絶対的に巨大な配列を定義し、ユーザーが実際の割り当てを管理してポインタと '本当の'サイズを渡せるようにします。柔軟性を維持し、実際のスペースを無駄にすることはありません。もちろん、構造体を直接コピーしてはいけません! –
セキュリティ?それはCです - あなたはすでにセキュリティがありません:) –