52

を使用してメモリを割り当てる場合malloc()、読み取り専用としてマークする方法があります。それで、誰かがそれに書き込もうとすると、memcpy()は失敗しますか?

これは、ユーザーがミスしている誤ったAPI設計に関連しています- GetValue()大容量メモリ構造の一部であるメソッドによって返されるconstポインタを使用します。メモリの大きなチャンクのコピーを避けたいので、特定の形式の構造化メモリ内にライブポインタを返します。ここで問題となるのは、このメモリに直接書き込み、割り当てを行い、開発したメモリバイナリ形式を適切に渡すSetValue()呼び出しを回避することで、機能するようにするためのハックを見つけるユーザーがいることです。作業が行われることもありますが、ユーザーによってオーバーライドされた制御フラグの誤った解釈により、メモリアクセス違反が発生することもあります。

ユーザーの教育は1つのタスクですが、今のところ、コードを失敗させたいとしましょう。

この事件を簡単に防ぐことができるかどうか疑問に思っています。

類推のために、誰かがsqliteステートメントからblob列を取得し、それに書き戻すと仮定します。sqliteの場合は意味がありませんが、私たちの場合はこれがやや起こります。

4

4 に答える 4

65

ほとんどのハードウェアアーキテクチャでは、メモリページ全体の保護属性のみを変更できます。ページのフラグメントを読み取り専用としてマークすることはできません。

関連するAPIは次のとおりです。

メモリページに、読み取り専用にしたくないものが含まれていないことを確認する必要があります。これを行うには、で過剰割り当てするか、、、などのmalloc()別の割り当てAPIを使用する必要があります。mmap()posix_memalign()VirtualAlloc()

于 2013-02-18T07:43:06.470 に答える
37

プラットフォームによって異なります。Linuxでは、mprotect()( http://linux.die.net/man/2/mprotect )を使用できます。

Windowsでは、VirtualProtect()(http://msdn.microsoft.com/en-us/library/windows/desktop/aa366898 (v=vs.85).aspx)を試すことができます。私はそれを使ったことがありません。

編集:これはNPEの答えの複製ではありません。NPEには元々異なる答えがありました。後で編集され、mprotect()とVirtualProtect()が追加されました。

于 2013-02-18T07:44:26.280 に答える
5

大容量メモリ構造の一部であるGetValue()メソッドによって返されるconstポインタを使用して、ユーザーが見落としている誤ったAPI設計。メモリの大きなチャンクのコピーを避けたいので、特定の形式の構造化メモリ内にライブポインタを返します

これは明らかに欠陥のあるAPI設計ではありません。APIはコントラクトです。クラスが特定の方法で動作することを約束し、クラスのクライアントがAPIを適切な方法で使用することを約束します。のような汚いトリックconst_castは不適切です(すべてではありませんが、一部のケースでは未定義の動作があります)。

使用するconst_castセキュリティの問題が発生する場合は、APIの設計に問題があります。その場合、メモリのチャンクをコピーするか、APIを再設計する必要があります。これはJavaの標準であり、 ( Javaで予約語であるにもかかわらず)同等のものはありません。constconst

于 2013-02-19T13:08:12.707 に答える
2

ポインタをわかりにくくします。つまり、ポインタとオフセットをクライアントに返します。これで、ポインタを直接使用できなくなります。ポインターが公式APIを介してコードに渡されるときは常に、オフセットを減算し、通常どおりポインターを使用します。

于 2019-07-09T23:02:40.747 に答える