メインコンテンツ

CWE Rule 558

Use of getlogin() in Multithreaded Application

R2023a 以降

説明

ルールの説明

The application uses the getlogin() function in a multithreaded context, potentially causing it to return incorrect values.

Polyspace 実装

ルール チェッカーは、"安全でない標準関数" をチェックします。

すべて展開する

問題

この問題は、安全でなく、セキュリティ関連のプログラミングに使用してはならない標準関数を使用した場合に発生します。関数は、多くの理由によって安全でなくなります。一部の関数は、再呼び出し不可能であるため安全ではありません。他の関数は、ターゲットやプラットフォームによって動作が変わるため、一部の実装が安全ではなくなります。

リスク

一部の安全でない関数は、再呼び出し可能ではありません。これは、呼び出し中に関数の内容がロックされないということです。そのため、攻撃者は途中で値を変更できます。

特に getlogin は、実装次第で安全でなくなります。getlogin の実装には、ログイン名の最初の 8 文字だけが返される場合があります。攻撃者は、最初の 8 文字が同じ別のログインを使用して侵入し、プログラムを操作できます。

修正方法

安全でない関数は、セキュリティ関連では使用しないようにします。安全でない関数を回避できない場合は、その関数のより安全なバージョンを代わりに使用します。getlogin に対しては、getlogin_r を使用します。

例 — getlogin の使用
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

int login_name_check(char *user)
{
    int r = -2;
    char *name = getlogin();  //Noncompliant
    if (name != NULL)
    {
        if (strcmp(name, user) == 0)
        {
            r = 0;
        }
        else
            r = -1;
    }

    return r;
}

この例では getlogin を使用して、現在のユーザーのユーザー名を指定のユーザー名と比較しています。しかし、並列処理により文字列が変更されることがあるため、getlogin は現在のユーザー名以外を返す場合があります。

修正 — getlogin_r を使用

1 つの修正方法として、getlogin_rgetlogin の代わりに使用します。getlogin_r は再呼び出し可能なので、その結果は信頼できます。

#define _POSIX_C_SOURCE 199506L // use of getlogin_r
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>


volatile int rd = 1;

enum {  NAME_MAX_SIZE=64  };

int login_name_check(char *user)
{
    int r;
    char name[NAME_MAX_SIZE];
    
    if (getlogin_r(name, sizeof(name)) == 0) 
    {
        if ((strlen(user) < sizeof(name)) && 
                     (strncmp(name, user, strlen(user)) == 0))
        {
            r = 0;
        }
        else
            r = -1;
    }
    else
        r = -2;
    return r;
}

チェック情報

カテゴリ: その他

バージョン履歴

R2023a で導入