もう 1 つの可能性は、呼び出しがシグナルによって中断されないようにするために何らかの処理を行ったアプリケーション (またはアプリケーションの一部) でのみ、この関数が使用されていることです。シグナルで重要なことを何もしないのであれば、それらに応答する必要はありません。ブロックしているすべてのシステム コールを EINTR 再試行でラップするのではなく、シグナルをすべてマスクする方が理にかなっている可能性があります。もちろん、あなたを殺すものを除いて、終了して処理する場合は SIGKILL と頻繁に SIGPIPE が発生し、SIGSEGV や同様の致命的なエラーが発生し、いずれにしても正しいユーザー空間アプリに配信されることはありません。
とにかく、彼が話しているのがセキュリティのことだけなら、おそらく再試行する必要はありませんclose
。close が EIO で失敗した場合、再試行できず、永続的な失敗になります。close
したがって、成功する彼のプログラムの正しさは必要ありません。close
EINTR で再試行することも、彼のプログラムの正確さのために必要ではないかもしれません。
通常、プログラムが成功するために最善を尽くす必要があり、それは EINTR で再試行することを意味します。しかし、これはセキュリティとは別の問題です。なんらかの理由で機能が失敗してもセキュリティ上の欠陥にならないようにプログラムが設計されている場合、特に、恒久的な理由ではなくたまたまEINTR に失敗したという事実は欠陥ではありません。DJB はかなり独断的であることが知られているので、彼が再試行する必要がない理由を証明したとしても、私はまったく驚かないでしょう。現在失敗している可能性がある特定の状況でハンドルをフラッシュします (kill
重要な瞬間にユーザーによって無害な信号が明示的に送信されるなど)。
編集: EINTR を再試行すること自体が、特定の条件下でセキュリティ上の欠陥になる可能性があることに気付きました。これにより、コードのそのセクションに新しい動作が導入されます。以前は 1 回試行しclose
てから戻るのに対し、シグナル フラッドに応答して無期限にループすることができます。これが qmail に何らかの問題を引き起こすかどうかはわかりません (結局のところ、qmailclose
自体はそれがいつ戻るかを保証しません)。しかし、1 回の試行であきらめた方がコードの分析が容易になるのであれば、それは賢明な選択かもしれません。か否か。
再試行することで、信号が偽の障害を引き起こす DoS の欠陥を防ぐことができると考えるかもしれません。しかし、再試行すると、別の (より困難な) DoS の欠陥が許されます。この脆弱性では、シグナル フラッドが無期限の停止を引き起こします。DJB が qmail と djbdns を書いたときに興味を持っていた絶対的なセキュリティの質問である「このアプリは DoSed できますか?」というバイナリに関しては、違いはありません。何かが 1 回発生する可能性がある場合、通常、それは何度も発生する可能性があることを意味します。