JPCERT コーディネーションセンター

MSC24-C. 非推奨関数や時代遅れの関数を使用しない

非推奨(deprecated)関数や時代遅れ(obsolescent)の関数は、より安全な同等の関数があるときには使用しないこと。非推奨関数は C 標準によって定義されている。時代遅れの関数とは、このレコメンデーションで定義しているものを指す。

非推奨関数

gets() 関数は、C99 の正誤表 3 で非推奨とされ、C11 で削除された。

時代遅れの関数

以下の表の第 1 列の関数を「時代遅れの関数」と定義する。アプリケーションで行っている時代遅れの関数の呼出しを修正するためには、このガイドラインに適合したインラインコーディング、またはこのガイドラインに適合した代替ライブラリ、または代替の「時代遅れでない関数」を使用できる。

時代遅れの
関数

推奨される
代替

理由

asctime()

asctime_s()

再入不可能

atof()

strtod()

エラー検出がない

atoi()

strtol()

エラー検出がない

atol()

strtol()

エラー検出がない

atoll()

strtoll()

エラー検出がない

ctime()

ctime_s()

再入不可能

fopen()

fopen_s()

ファイルへの排他的アクセスなし

freopen()

freopen_s()

ファイルへの排他的アクセスなし

rewind()

fseek()

エラー検出なし

setbuf()

setvbuf()

エラー検出なし

atof()atoi()atol() および atoll() は時代遅れの関数である。これらの関数は strtod()strtof()strtol()strtold()strtoll()strotul() および strtoull() 関数でエミュレートでき、より堅牢なエラー処理機能を備えている。「INT05-C. 可能性のあるすべての入力を処理できない入力関数を使って文字データを変換しない」を参照のこと。

fopen() および freopen() 関数は時代遅れの関数である。ファイル保護を設定し排他的アクセスでファイルをオープンする fopen_s() および freopen_s() 関数によってそれらの関数をエミュレートでき、ファイルを不正なアクセスから保護できるからである[ISO/IEC WG14 N1173]。

setbuf() 関数は値を返さず、setvbuf() でエミュレートできるため、時代遅れの関数である。「FIO12-C. setbuf() ではなく setvbuf() を使用する」を参照のこと。

rewind() 関数は値を返さず、fseek() でエミュレートできるため、時代遅れの関数である。「FIO07-C. rewind() ではなく fseek() を使用する」を参照のこと。

asctime() および ctime() 関数は、再入不可能な静的バッファを使用しており、asctime_s() および ctime_s() でエミュレートできるため、時代遅れの関数である。

未チェックの時代遅れの関数

以下の関数を、未チェックの時代遅れの関数と定義する。

 

bsearch

 

fprintf

fscanf

fwprintf

fwscanf

getenv

gmtime

localtime

mbsrtowcs

mbstowcs

memcpy

memmove

printf

qsort

setbuf

snprintf

sprintf

sscanf

strcat

strcpy

strerror

strncat

strncpy

strtok

swprintf

swscanf

vfprintf

vfscanf

vfwprintf

vfwscanf

vprintf

vscanf

vsnprintf

vsprintf

vsscanf

vswprintf

vswscanf

vwprintf

vwscanf

wcrtomb

wcscat

wcscpy

wcsncat

wcsncpy

wcsrtombs

wcstok

wcstombs

wctomb

wmemcpy

wmemmove

wprintf

wscanf

 

 

アプリケーションで行っている未チェックの時代遅れの関数の使用を修正するためには、このガイドラインに適合するインラインコーディング、または、このガイドラインに適合する代替ライブラリ、または C11 Annex K で規定されている代替の「時代遅れでない関数」を使用できる。

abort_handler_s

 

bsearch_s

 

fprintf_s

freopen_s

fscanf_s

fwprintf_s

fwscanf_s

getenv_s

gets_s

gmtime_s

ignore_handler_s

localtime_s

mbsrtowcs_s

mbstowcs_s

memcpy_s

memmove_s

printf_s

qsort_s

scanf_s

set_constraint_handler_s

snprintf_s

snwprintf_s

sprintf_s

sscanf_s

strcat_s

strcpy_s

strerror_s

strerrorlen_s

strncat_s

strncpy_s

strnlen_s

strtok_s

swprintf_s

swscanf_s

vfprintf_s

vfscanf_s

vfwprintf_s

vfwscanf_s

vprintf_s

vscanf_s

vsnprintf_s

vsnwprintf_s

vsprintf_s

vsscanf_s

vswprintf_s

vswscanf_s

vwprintf_s

vwscanf_s

wcrtomb_s

wcrtoms_s

wcscat_s

wcscpy_s

wcsncat_s

wcsncpy_s

wcsnlen_s

wcsrtombs_s

wcstok_s

wcstombs_s

wctomb_s

wmemcpy_s

wmemmove_s

wprintf_s

wscanf_s

 

 

 

 

 

または、ISO/IEC TR 24731-2、Extensions to the C Library—Part II: Dynamic Allocation Functions [ISO/IEC TR 24731-2] に規定されている代替の「時代遅れでない関数」を使うこともできる。

asprintf

aswprintf

fmemopen

fscanf

fwscanf

getdelim

getline

getwdelim

getwline

open_memstream

open_wmemstream

strdup

strndup

 

違反コード

次の違反コード例では、時代遅れの関数 strcat()strcpy() が使用されている。

#include <string.h>
#include <stdio.h>

enum { BUFSIZE = 32 };
void complain(const char *msg) {

  static const char prefix[] = "Error: ";
  static const char suffix[] = "\n";
  char buf[BUFSIZE];

  strcpy(buf, prefix);
  strcat(buf, msg);
  strcat(buf, suffix);
  fputs(buf, stderr);
}
適合コード

次の適合コードでは、strcat()strcpy()strcat_s()strcpy_s() に置き換えられている。

#define __STDC_WANT_LIB_EXT1__
#include <string.h>
#include <stdio.h>

enum { BUFFERSIZE = 256 };

void complain(const char *msg) {
  static const char prefix[] = "Error: ";
  static const char suffix[] = "\n";
  char buf[BUFFERSIZE];

  strcpy_s(buf, BUFFERSIZE, prefix);
  strcat_s(buf, BUFFERSIZE, msg);
  strcat_s(buf, BUFFERSIZE, suffix);
  fputs(buf, stderr);
}
リスク評価

非推奨関数や時代遅れの関数は、しばしばソフトウェアの脆弱性の原因となる。

ルール

深刻度

可能性

修正コスト

優先度

レベル

MSC24-C

P12

L1

自動検出
ツール バージョン チェッカー 説明

ECLAIR

1.2

CC2.MSC34

実装済み

関連するガイドライン
CERT C Coding Standard

ERR07-C. よりよいエラー検査を行える関数を使用する
INT05-C. 可能性のあるすべての入力を処理できない入力関数を使って文字データを変換しない
INT06-C. 文字列トークンを整数に変換するには strtol() 系の関数を使う
STR06-C. strtok() が分割対象文字列を変更しないと想定しない
STR07-C. 境界チェックインタフェースを使用し、文字列操作を行う既存のコードの脅威を緩和する

ISO/IEC TR 24772 Use of Libraries [TRJ]
MISRA C:2012 Rule 21.3 (required)
MITRE CWE CWE-20, Insufficient input validation
CWE-73, External control of file name or path
CWE-192, Integer coercion error
CWE-197, Numeric truncation error
CWE-367, Time-of-check, time-of-use race condition
CWE-464, Addition of data structure sentinel
CWE-676, Use of potentially dangerous function
参考資料
[Apple 2006] Apple Secure Coding Guide, "Avoiding Race Conditions and Insecure File Operations"
[Burch 2006] Specifications for Managed Strings, Second Edition
[Drepper 2006] Section 2.2.1 "Identification When Opening"
[IEEE Std 1003.1:2013] XSH, System Interfaces, open
ISO/IEC 23360-1:2006  
[ISO/IEC WG14 N1173] Rationale for TR 24731 Extensions to the C Library Part I: Bounds-checking interfaces
[Klein 2002] "Bullet Proof Integer Input Using strtol()"
[Linux 2008] strtok(3)
[Seacord 2013] Chapter 2, "Strings"
Chapter 8, "File I/O"
[Seacord 2005b] "Managed String Library for C, C/C++"
翻訳元

これは以下のページを翻訳したものです。

MSC24-C. Do not use deprecated or obsolescent functions (revision 55)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter