メインコンテンツ

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

CERT C: Rule INT36-C

Converting a pointer to integer or integer to pointer

説明

ルール定義

ポインターを整数に、または整数をポインターに変換します。1

Polyspace 実装

ルール チェッカーは、"ポインターと整数の間の変換" をチェックします。

すべて展開する

問題

次のいずれかの条件に該当する場合、"ポインターと整数の間の変換" が報告されます。

  • ポインター型がより小さいサイズの整数型に変換される。intptr_t 型または uintprt_t 型のポインターを整数型 enumptrdiff_t または pid_t に変換する場合、環境内でポインターと整数型のサイズが異なっていると、Polyspace が欠陥を報告します。i386 環境では、ポインターと整数型の両方のサイズが 32 ビットとなっています。この環境では、Polyspace は、ポインターから同じサイズの整数への変換にフラグを設定しません。ただし、ポインターが 64 ビットで、符号なし整数が 32 ビットとなっている x86_64 環境では、Polyspace® がポインターからサイズの異なる整数への変換にフラグを設定します。

  • 整数型が、生のポインター型に変換される。Polyspace は、サイズを問わず、整数型から生のポインターへの変換にフラグを設定します。たとえば、ポインターから生成された整数が、後でポインターにキャストされる場合、Polyspace は整数からポインターへの変換にフラグを設定します。この場合、整数とポインターは同じサイズですが、それでもこの変換にはフラグが設定されます。

リスク

ポインターと整数とのマッピングは、環境のアドレス指定構造と必ずしも一致するとは限りません。

ポインターから整数への変換により、以下が生じる可能性があります。

  • 整数値の切り捨てまたは範囲外の整数値。

  • 不適切な整数型。

整数からポインターへの変換により、以下が生じる可能性があります。

  • ポインターまたはオブジェクトのミスアライメント。

  • 不適切なポインター アドレス。

修正方法

可能であれば、ポインターから整数への変換または整数からポインターへの変換を避けます。void ポインターを整数に変換する場合は、値が変化しないように、以下の型を使用します。

  • C99 — intptr_t または uintptr_t

  • C90 — size_t または ssize_t

例 - 整数からポインターへの変換
unsigned int* badintptrcast(void)
{
    int* ptr;
    unsigned long long int_same_as_ptr ;
    unsigned int int_smaller_than_ptr;

    unsigned int* ptr0 = (unsigned int*)0xdeadbeef; //Noncompliant
    

    /*int to ptr of same size*/
    ptr = (int*)int_same_as_ptr;  //Noncompliant
    
    /*int to ptr of different size*/
    ptr = (int*)int_smaller_than_ptr;  //Noncompliant

    return (unsigned int*)(ptr0 - (unsigned int*)ptr);  //Noncompliant
}

この例では、Polyspace は安全ではない可能性のある変換にフラグを設定します。次に例を示します。

  • 0xdeadbeef から unsigned int* への変換により、ポインターにアライメントの問題が発生します。Polyspace はこの変換にフラグを設定します。

  • int_same_as_ptr および int_smaller_than_ptr から int* ポインターへの変換により、無効なポインター アドレスになる可能性があります。Polyspace はこれらの変換にフラグを設定します。

  • return ステートメントは ptrdiff_t をポインターにキャストします。このポインターは無効なアドレスを指さない可能性があります。Polyspace はこの変換にフラグを設定します。

修正 — intptr_t を使用

考えられる 1 つの修正方法として、intptr_t 型を使用してアドレスを格納します。2 つのポインターを減算した結果を格納する場合は、ptrdiff_t 型を使用します。

#include<stdint.h>
#include<stddef.h>
ptrdiff_t badintptrcast(void)
{
    intptr_t ptr;
    unsigned long long int_same_as_ptr ;
    unsigned int int_smaller_than_ptr;

    intptr_t ptr0 = (intptr_t)0xdeadbeef; //Compliant

    /*int to ptr of same size*/
    ptr = (intptr_t)int_same_as_ptr;  //Compliant
    
    /*int to ptr of different size*/
    ptr = (intptr_t)int_smaller_than_ptr;  //Compliant

    int offset = 0;
    return (ptrdiff_t)(ptr0 - offset);//Compliant
    
}

チェック情報

グループ: Rule 04.整数 (INT)

バージョン履歴

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.