雨の中の外壁高圧洗浄
今日は雨、時々、雨音がひどくなる
この日に外壁の高圧洗浄が行われている
黒い水が・・・汚れが凄まじい
建築して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;
}
};
ソースコードにはいくつかの脆弱性があります。以下はその主なものです:
メモリリークの可能性:
CreateNote メソッドで new を使ってメモリを割り当てていますが、これを解放するのは DeleteNote メソッドだけです。DeleteNote メソッドを呼び出さないとメモリリークが発生します。また、CreateNote を複数回呼び出すと、以前に割り当てたメモリが解放されずにリークする可能性があります。
バッファオーバーフローの可能性:
RegisterName と RegisterMsg メソッドで、ユーザ入力を固定長のバッファに読み込んでいます。scanf のフォーマット指定子で長さを制限していますが、不正な入力(長すぎる入力やバイナリデータ)によってバッファオーバーフローが発生する可能性があります。
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ポインタ参照のリスクを軽減できます。
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?