メインコンテンツ

ISO/IEC TS 17961 [syscall]

システムの呼び出し

説明

ルール定義

システムの呼び出し。1

Polyspace 実装

このチェッカーは、システム関数の安全でない呼び出しをチェックします。

すべて展開する

問題

システム関数の安全でない呼び出しは、処理系定義のコマンド プロセッサを呼び出す関数を使用する場合に発生します。これらの関数には以下が含まれます。

  • C 標準関数 system()

  • POSIX 関数 popen()

  • Windows® 関数 _popen() および _wpopen()

リスク

コマンド プロセッサを呼び出す関数の引数がサニタイズされていない場合、悪用可能な脆弱性の原因になる可能性があります。攻撃者は任意のコマンドを実行したり、システム上の任意の場所にあるデータを読み取ったり変更したりできます。

修正方法

コマンド プロセッサを呼び出す system ファミリ関数を使用しないようにします。代わりに、POSIX の execve() や WinAPI の CreateProcess() など、より安全な関数を使用します。

例 - system() の呼び出し
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>

enum { 
SIZE512=512,
SIZE3=3};

void func(char *arg)
{
	char buf[SIZE512];
	int retval=sprintf(buf, "/usr/bin/any_cmd %s", arg);
	
	if (retval<=0 || retval>SIZE512){
		/* Handle error */
		abort();
	}
	/* Use of system() to pass any_cmd with 
	unsanitized argument to command processor */
	
	if (system(buf) == -1) {
	/* Handle error */
  }
} 

この例では、実行するコマンド プロセッサのホスト環境に system() が引数を渡しています。このコードはコマンド インジェクションによる攻撃に対して脆弱です。

修正 — 引数をサニタイズして execve() を使用

次のコードでは、any_cmd の引数がサニタイズされた後に execve() に渡されて実行されます。exec ファミリ関数は、コマンド インジェクション攻撃に対して脆弱ではありません。

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

enum { 
SIZE512=512,
SIZE3=3};


void func(char *arg)
{
  char *const args[SIZE3] = {"any_cmd", arg, NULL};
  char  *const env[] = {NULL}; 
  
  /* Sanitize argument */
  
  /* Use execve() to execute any_cmd. */

  if (execve("/usr/bin/time", args, env) == -1) { 
    /* Handle error */
  }
} 

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.