2016-03-25 19 views
0

私は、(小さなライブラリのような)引数として、機密データ(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モデルを使用するだろうが、それは良い選択であるかどうかは分かりません。

+1

あなたは、フル機能の範囲チェックが埋め込まれ、ステージコーチをしたい場合、ユーザは、例えば、ポインタを変更した場合、あなたは決定的に何C.を使うべきではありません:ユーザが直接変更する(または唯一のハックの方法で)ことができませんか? – Olaf

+0

慣例ですあなたのlibで使用するための構造体の最後に絶対的に巨大な配列を定義し、ユーザーが実際の割り当てを管理してポインタと '本当の'サイズを渡せるようにします。柔軟性を維持し、実際のスペースを無駄にすることはありません。もちろん、構造体を直接コピーしてはいけません! –

+1

セキュリティ?それはCです - あなたはすでにセキュリティがありません:) –

答えて

0

あなたのライブラリのユーザはどこから関数に渡すstruct2インスタンスを取得しますか?あなた自身がそれを作成し、あなたの関数に引数を渡すと思っています。それは引数を渡すのに奇妙な方法でしょう。あなたのライブラリの別の関数から返される可能性が最も高いです。その場合、struct2を不透明なデータ型

/* in the header file */ 
typedef struct2_s struct2; 

/* in the implementation file, where allocation is handled as well 
* so you know str_length is set to the proper value. 
*/ 
struct struct2_s { 
    char *str; 
    size_t str_length; 
}; 
+0

実際に私は構造体アドレスを渡すことを考えていましたが、あなたの解決策は私にそのオプションを再考させました。しかしその方法では、ライブラリは、私が望むのは、関数によって処理されるようにchar配列を渡すことだけです。 – lorenzownd

0

struct struct1 { 
    anyType thisVar; 
    someType anotherVar 
    size_t str_length; 
    char str[10240000];/
} 

は、ユーザは、彼らが望むものは何でも「本当の」サイズにそれををmallocしてみましょう。..最後に大きな配列を入れてください。彼らが 'str_length'を間違って設定した場合、あなたが何をするにしても、それについて多くのことができるわけではありません:(

+0

しかし、その場合、ユーザは間違った* str_length *値を渡すことによってバッファをあふれさせることができます。私はあなたが正しいと思います、簡単な解決策はありません:( – lorenzownd

関連する問題