0

Clangのscan-buildは、私のプロジェクトでnullポインターのかなりの数の逆参照を報告しますが、(6年間使用して)異常な動作は実際には見られません。

Dereference of null pointer (loaded from variable chan)

char *tmp;
CList *chan = NULL; 
/* This is weird because chan is set via do_lookup so why could it be NULL? */
chan = do_lookup(who, me, UNLINK);
if (chan)
tmp = do_lookup2(you,me,0);

prot(get_sec_var(chan->zsets));

                 ^^^^

null derefがクラッシュを引き起こす可能性があることは知っていますが、一部の人々がそれを明らかにしているので、これは本当に大きなセキュリティ上の懸念ですか?この場合はどうすればよいですか?

4

6 に答える 6

5

ポインタを逆参照するのは未定義動作です。NULLあらゆる動作を示す可能性があり、クラッシュするかどうかはわかりませんが、修正する 必要があります。

未定義動作についての真実は、それがマーフィーの法則に従うということです

「うまくいかないことはすべてうまくいかない」

于 2012-10-02T07:04:23.307 に答える
4

chanある時点でNULLをチェックすることは意味がありません。

if (chan)
  tmp = do_lookup2(you,me,0);     /* not evaluated if `chan` is NULL */
  prot(get_sec_var(chan->zsets)); /* will be evaluated in any case */

...まだ次の行でそれをチェックしていません。

ifブランチ内でこれら両方のステートメントを実行する必要はありませんか?

于 2012-10-02T07:06:24.943 に答える
4

chanNULLであることを確認した後、とにかく次の行で無条件に逆参照するため、Clangは警告を発します。これはおそらく正しくありません。どちらdo_lookupもNULLを返すことができない場合、チェックは役に立たないため、削除する必要があります。または、それが可能である場合、最後の行が未定義の動作を引き起こす可能性があり、修正する必要があります。Alsは100%正しいです。NULLポインターの逆参照は未定義の動作であり、常に潜在的なリスクです。

おそらく、コードをブロックで囲み、次の行だけでなく、すべてのコードがNULLのチェックによって管理されるようにする必要があります。

于 2012-10-02T07:07:37.087 に答える
1

これらをできるだけ早く修正する必要があります。またはおそらくもっと早く。標準では、NULLポインターは「有効なメモリー位置がない」ことを指すポインターであるとされているため、それを逆参照することは未定義の動作です。これは、動作したり、クラッシュしたり、プログラムの他の部分で奇妙なことをしたり、デーモンが鼻から飛び出したりする可能性があることを意味します。

それらを修正します。今。

方法は次のとおりです。逆参照ステートメントをif-の中に入れます。そうでない場合(あなたが行うように:NULLをチェックしてからとにかく逆参照する)は意味がありません。

if (pointer != NULL) {
    something = pointer->field;
}

^^これは良い習慣です。

于 2012-10-02T07:09:24.080 に答える
0

NULLポインターの逆参照が原因でプログラムがクラッシュした場合、これはサービス拒否(DoS)として分類できます。

このプログラムを他のプログラムと一緒に使用する場合(たとえば、プログラムを呼び出す場合)、セキュリティの側面は、このプログラムがクラッシュしたときに他のプログラムが何をするかに依存し始めます。全体的な影響は、同じDoSまたはそれより悪いもの(悪用、機密情報の漏洩など)になる可能性があります。

NULLポインターの逆参照が原因でプログラムがクラッシュせず、代わりに、プログラム自体、および場合によっては同じアドレス空間内のOSや他のプログラムが破損しているときに実行を続けると、さまざまなセキュリティ問題が発生する可能性があります。

潜在的なハッキングの結果に対処する余裕がない限り、壊れたコードを(またはオンラインで)行かせないでください。

于 2012-10-02T08:29:50.503 に答える
0

このコードで問題が発生したことがない場合は、次の理由が考えられます。

do_lookup(who, me, UNLINK);

常に有効なポインタを返します。

しかし、この関数が変更された場合はどうなりますか?またはそのパラメータは異なりますか?

間接参照する前に、必ずNULLポインターをチェックする必要があります

if (chan)
   prot(get_sec_var(chan->zsets));

do_lookupどちらも、またはそのパラメーターが将来変更されないことを絶対に確信している場合(そして、プログラムの安全な実行に賭けることができます)、同様の機能のすべての発生を変更するコストは、あなたの利益と比較して過度に高くなりますそうすることで、次のようになります。

コードを壊したままにしておくこともできます。

多くのプログラマーが過去にそれを行いましたが、将来的にはさらに多くのプログラマーがそれを行うでしょう。そうでなければ、何が存在を説明するでしょうWindows MEか?

于 2012-10-02T07:27:02.780 に答える