年が終わり、私は長い間オープンプロジェクトの検証に関するメモを書いていません。 PostgreSQLデータベース管理システムプロジェクトをチェックアウトするよう繰り返し求められました。 これは私がやったことです。 残念ながら、壮大で興味深い記事は機能しません。 いくつかの典型的なエラーに気づきました。 そのため、今回は非常に小さな記事になりました。
PostgreSQLは無料のオブジェクトリレーショナルデータベース管理システム(DBMS)です。 PostgreSQLはSQL言語に基づいており、SQL:2003標準(ISO / IEC 9075)の多くの機能をサポートしています。 プロジェクトの詳細については、 Wikipedia Webサイトおよびプロジェクト Webサイト自体を参照してください。
1. memcmp()関数を使用する際のタイプミス
Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { .... if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr, sizeof(zero_clientaddr) == 0)) .... }
PVS-Studioが発行する警告: V526対応するバッファーが等しい場合、「memcmp」関数は0を返します。 状態の間違いを調べることを検討してください。 postgres pgstatfuncs.c 712
また、この行で警告V575が発行されます。 ところで、プログラムの同じ行に2つ以上の診断メッセージが表示される場合、これは非常に慎重にチェックする機会です。 非常に多くの場合、1つの間違いにより、コードが「異なる観点から」疑わしくなります。
コードをよく見ると、1つの閉じ括弧がその場所にないことがわかります。 その結果、関数の3番目の実際の引数は、式「sizeof(zero_clientaddr)== 0」です。
隣接する関数で同じエラーが見られることがあります。 どうやらコードをコピーしたためにエラーが増加したようです。
その他の問題領域:
- pgstatfuncs.c 976
- pgstatfuncs.c 1023
2. 8進数の数字
void RestoreArchive(Archive *AHX) { .... AHX->minRemoteVersion = 070100; AHX->maxRemoteVersion = 999999; .... }
PVS-Studioが発行する警告: V536使用される定数値は8進数形式で表されることに注意してください。 10月:070100、12月:28736。pg_dump pg_backup_archiver.c 301
近くにあるコードを見ると、プログラマは8進数システムで書かれた番号を使用する予定はなかったと結論付けることができます。 たとえば、次のような行があります。
fout->minRemoteVersion = 70000;
ほとんどの場合、美しさのためにゼロが追加されました。 しかし、このゼロのため、数字「070100」は8進数で表記され、28736です。
3.クラシック。 SOCKETタイプのエラー
Windowsオペレーティングシステムでは、SOCKETタイプは符号なしタイプです。 多くの人はこれを知らないか、忘れていません。 その結果、さまざまなプロジェクトで同じエラーが発生する可能性があります。 このエラーは、PostgreSQLプロジェクトに合格していません。
typedef UINT_PTR SOCKET; typedef SOCKET pgsocket; static int ident_inet(hbaPort *port) { .... pgsocket sock_fd; .... sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype, ident_serv->ai_protocol); if (sock_fd < 0) { .... }
PVS-Studioが発行する警告: V547式 'sock_fd <0'は常にfalseです。 符号なしの型の値が<0になることはありませんpostgres auth.c 1668
チェック(sock_fd <0)は意味がありません。 符号なし変数はゼロより小さくすることはできません。 ソケットを開くことができない状況を処理するコードは、制御を受け取りません。
これと同じエラーがさらにいくつかあります。
- auth.c 1748
- auth.c 2567
- pqcomm.c 395
- pqcomm.c 633
- postmaster.c 2168
4.個人データの消去エラー
プライベートデータを含むメモリの上書きに関連する多くの典型的なエラーが見つかりました。 このエラーは、おそらくSOCKETタイプの問題よりも頻繁に発生します。
char * px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen) { .... unsigned char final[MD5_SIZE]; .... /* Don't leave anything around in vm they could use. */ memset(final, 0, sizeof final); .... }
PVS-Studioが発行する警告: V597コンパイラーは、「最終」バッファーのフラッシュに使用される「memset」関数呼び出しを削除できました。 RtlSecureZeroMemory()関数を使用して、プライベートデータを消去する必要があります。 pgcrypto crypt-md5.c 157
コメントは、メモリの特定の領域を上書きする必要性を強調しています。 ただし、これは起こりません。 コンパイラーは、memset()関数の呼び出しをスローします。 これが発生する理由と対処方法は、診断ルールの説明に記載されています。
データが消去されない場所はたくさんあります。
- fortuna.c 294
- fortuna.c 344
- fortuna.c 381
- internal.c 671
- pgp-encrypt.c 131
- pgp-encrypt.c 493
- pgp-encrypt.c 555
- pgp-decrypt.c 283
- pgp-decrypt.c 398
- pgp-decrypt.c 399
- pgp-decrypt.c 496
- pgp-decrypt.c 706
- pgp-decrypt.c 795
- pgp-pgsql.c 90
- pgp-pgsql.c 132
- px-crypt.c 161
- pgp-pubkey.c 153
- pgp-pubkey.c 294
- pgp-pubkey.c 295
そのような場所はそれぞれ潜在的な脆弱性です! 最も予期しない方法で消去されていないデータをディスクに書き込んだり、ネットワーク経由で送信したりできます。 このテーマに関する記事: メモリの上書き-なぜですか?
5.未定義の動作
static char * inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { .... m = ~0 << (8 - b); .... }
PVS-Studioが発行する警告: V610未定義の動作。 シフト演算子 '<<を確認してください。 左のオペランド「〜0」は負です。 postgres inet_cidr_ntop.c 206
負の数はシフトできません。 これにより、未定義の動作が発生します。 続きを読む:「 フォードを知らないで、水に入らないでください-パート3。 」
その他の危険なシフト:
- network.c 1435
- signal.c 118
- signal.c 125
- varbit.c 1508
- varbit.c 1588
6.タイプミス
static void AddNewRelationTuple(....) { .... new_rel_reltup->relfrozenxid = InvalidTransactionId; new_rel_reltup->relfrozenxid = InvalidMultiXactId; .... }
PVS-Studioが発行する警告: V519 'new_rel_reltup-> relfrozenxid'変数には、連続して2回値が割り当てられます。 おそらくこれは間違いです。 行を確認してください:912、913。postgres heap.c 913
1つの変数には2つの異なる値が割り当てられます。 タイプミスのようです。 おそらく2行目で、値を変数「new_rel_reltup-> relminmxid」に割り当てる必要があります
おわりに
PostgreSQLプロジェクトの開発者の1人がPVS-Studioアナライザーに興味がある場合、しばらくの間登録キーを提供する準備ができています。 サポートしてください。
そして、私はあなたに幸せな新年を願っています!