見出し画像

雨の中の外壁高圧洗浄

今日は雨、時々、雨音がひどくなる
この日に外壁の高圧洗浄が行われている
黒い水が・・・汚れが凄まじい
建築して15年以上経過すると、排気ガスで汚れてしまう

猫たちは何事かとうろうろするのはよいが、室内が蒸し暑い
気温は低めでも、蒸していると、リバースが増えてしまう
設定気温を低くして冷房をオン
人も猫も快適になる、、、30分で冷房はオフ💦

クールダウンのミケ
シニアになり、食べる量が減り、スリムになる
私も見習おう
近所の公園のねむの木
暑い夏が近そう

ソースの脆弱性

#include <cstdio>

struct Note {
    char* name;
    char* msg;
};

class NoteManager {
    Note* m_note;

public:
    NoteManager() {
        m_note = NULL;
    }

    void CreateNote() {
        if (m_note = new Note()) {
            m_note->name = NULL;
            m_note->msg = NULL;
        }
    }

    void RegisterName() {
        if (m_note && !m_note->name) {
            m_note->name = new char[8];
        }

        if (m_note && m_note->name) {
            printf("Input name: ");
            scanf("%7s%*[^\n]%*c", m_note->name);
        }
    }

    void RegisterMsg() {
        if (m_note && !m_note->msg) {
            m_note->msg = new char[100];
        }

        if (m_note && m_note->msg) {
            printf("Input message: ");
            scanf("%99s%*[^\n]%*c", m_note->msg);
        }
    }

    void DisplayNote() {
        if (m_note && m_note->name) {
            printf("Name: %s\n", m_note->name);
        }

        if (m_note && m_note->msg) {
            printf("Message: %s\n", m_note->msg);
        }
    }

    void DeleteNote() {
        delete[] m_note->name;
        delete[] m_note->msg;
        delete m_note;
    }
};

ソースコードにはいくつかの脆弱性があります。以下はその主なものです:

  1. メモリリークの可能性:

    • CreateNote メソッドで new を使ってメモリを割り当てていますが、これを解放するのは DeleteNote メソッドだけです。DeleteNote メソッドを呼び出さないとメモリリークが発生します。また、CreateNote を複数回呼び出すと、以前に割り当てたメモリが解放されずにリークする可能性があります。

  2. バッファオーバーフローの可能性:

    • RegisterName と RegisterMsg メソッドで、ユーザ入力を固定長のバッファに読み込んでいます。scanf のフォーマット指定子で長さを制限していますが、不正な入力(長すぎる入力やバイナリデータ)によってバッファオーバーフローが発生する可能性があります。

  3. NULLポインタの参照:

    • DisplayNote や DeleteNote メソッドで、m_note がNULLの場合のチェックが不足しており、NULLポインタを参照する可能性があります。

これらの脆弱性に対する修正例を以下に示します:

#include <cstdio>
#include <cstring> // for std::strncpy

struct Note {
    char* name;
    char* msg;
};

class NoteManager {
    Note* m_note;

public:
    NoteManager() {
        m_note = nullptr;
    }

    ~NoteManager() {
        DeleteNote();
    }

    void CreateNote() {
        DeleteNote(); // 既存のNoteを削除してから新しいNoteを作成する
        m_note = new Note();
        if (m_note) {
            m_note->name = nullptr;
            m_note->msg = nullptr;
        }
    }

    void RegisterName() {
        if (m_note && !m_note->name) {
            m_note->name = new char[8];
        }

        if (m_note && m_note->name) {
            printf("Input name: ");
            if (scanf("%7s%*[^\n]%*c", m_note->name) != 1) {
                printf("Input error.\n");
            }
        }
    }

    void RegisterMsg() {
        if (m_note && !m_note->msg) {
            m_note->msg = new char[100];
        }

        if (m_note && m_note->msg) {
            printf("Input message: ");
            if (scanf("%99s%*[^\n]%*c", m_note->msg) != 1) {
                printf("Input error.\n");
            }
        }
    }

    void DisplayNote() const {
        if (m_note) {
            if (m_note->name) {
                printf("Name: %s\n", m_note->name);
            }
            if (m_note->msg) {
                printf("Message: %s\n", m_note->msg);
            }
        }
    }

    void DeleteNote() {
        if (m_note) {
            delete[] m_note->name;
            delete[] m_note->msg;
            delete m_note;
            m_note = nullptr;
        }
    }
};

修正点:

  • CreateNote メソッドで新しい Note を作成する前に既存の Note を削除することで、メモリリークを防止。

  • デストラクタ ~NoteManager を追加して、オブジェクトが破棄される際に確実にメモリを解放。

  • DisplayNote と DeleteNote メソッドで m_note が NULL かどうかをチェック。

  • scanf の戻り値をチェックして入力エラーを検出。

これにより、メモリリークやバッファオーバーフロー、NULLポインタ参照のリスクを軽減できます。

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?