メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: SIG31-C

信号ハンドラー内の共有オブジェクトにアクセスしない

説明

ルール定義

信号ハンドラー内の共有オブジェクトにアクセスしないようにします。1

Polyspace 実装

ルール チェッカーは、"信号ハンドラー内でのデータ アクセスの共有" をチェックします。

すべて展開する

問題

信号ハンドラー内でのデータ アクセスの共有は、信号ハンドラー内の共有オブジェクトへのアクセスまたは変更を行った場合に発生します。

リスク

共有オブジェクトへのアクセスまたは変更を行う信号ハンドラー関数を定義する場合、ハンドラーは信号を受け取ると共有オブジェクトへのアクセスまたは変更を行います。他の関数が既にその共有オブジェクトにアクセス中の場合、その関数が競合状態を発生させ、データが不整合状態になる可能性があります。

修正方法

信号ハンドラー内の共有オブジェクトへのアクセスまたは変更を行うには、オブジェクトがロック制御不要のアトミックであることをチェックするか、オブジェクトが整数の場合は volatile sig_atomic_t として宣言します。

例 - 信号ハンドラー内での int 型変数へのアクセス
#include <signal.h>
#include <stdlib.h>
#include <string.h>

/* declare global variable. */
int e_flag;

void sig_handler(int signum)
{
	/* Signal handler accesses variable that is not
	of type volatile sig_atomic_t. */
    e_flag = signum;  //Noncompliant
}

int func(void)
{
    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        /* Handle error */
        abort();
    }
    /* Program code */
    if (raise(SIGINT) != 0)
    {
        /* Handle error */
        abort();
    }
    /* More code */
    return 0;
}
        
      

この例では、sig_handlerint 型の変数である e_flag にアクセスしています。別の関数からの同時アクセスによって、e_flag が不整合状態になる可能性があります。

修正 — volatile sig_atomic_t 型の変数を宣言

信号ハンドラーから共有変数にアクセスする前に、変数を int 型ではなく volatile sig_atomic_t 型で宣言します。この型の変数には非同期で安全にアクセスできます。

#include <signal.h>
#include <stdlib.h>
#include <string.h>

/* Declare variable of type volatile sig_atomic_t. */
volatile sig_atomic_t e_flag;
void sig_handler(int signum)
{
	/* Use variable of proper type inside signal handler. */
    e_flag = signum;
    
}

int func(void)
{
    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        /* Handle error */
        abort();
    }
    /* Program code */
    if (raise(SIGINT) != 0)
    {
        /* Handle error */
        abort();
    }
    /* More code */
    return 0;
} 

チェック情報

グループ: 49.その他 (MSC)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.