CXX.ERRNO.NOT_CHECKED
ライブラリ関数を呼び出した後に、errno の条件チェックが欠落している
CXX.ERRNO.NOT_CHECKED チェッカーは、値を設定するライブラリ関数を呼び出した後に errno の値がチェックされないケースにフラグを立てます。
脆弱性とリスク
ライブラリ関数の以前の呼び出しから、errno の値が設定される可能性があります。errno 値を設定するライブラリ関数を呼び出した後に errno の値をチェックしないと、コードは間違って実行される可能性があります。
軽減と防止
値を設定するライブラリ関数を呼び出した後は、errno の値を常にチェックします。
脆弱コード例 1
コピー
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
void func(const char *c_str) {
unsigned long number;
char *endptr;
errno=0;
number = strtoul(c_str, &endptr, 0);
}
この準拠していない例では、コードは strtoul() を呼び出した後に、errno の値をチェックすることに失敗します。エラーが発生した場合、strtoul() は有効な値 (ULONG_MAX) を返すため、strtoul() が正常に実行されたかどうかを判断する唯一の手段は errno になります。
修正コード例 1
コピー
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
void func(const char *c_str) {
unsigned long number;
char *endptr;
errno = 0;
number = strtoul(c_str, &endptr, 0);
if (errno == ERANGE) {
/* Handle error */
} else {
/* Computation succeeded */
}
}
この修正された例では、コードは strtoul() を呼び出した後に errno の値をチェックします。
脆弱コード例 2
コピー
#include <errno.h>
#include <stdio.h>
void func(const char *filename) {
FILE *fileptr;
errno = 0;
fileptr = fopen(filename, "rb");
if (errno != 0) {
/* Handle error */
}
}
この準拠していない例では、エラーが発生しても fopen() は errno の値を設定しない場合があるため、コードはエラーを診断することに失敗する可能性があります。
修正コード例 2
コピー
#include <stdio.h>
void func(const char *filename) {
FILE *fileptr = fopen(filename, "rb");
if (fileptr == NULL) {
/* An error occurred in fopen() */
}
}
C 標準では、fopen() を説明するときに errno については何も言及していません。この修正された例では、コードは fopen() を呼び出した結果を使用して失敗を判断しており、errno の値をチェックしません。