HN 日本語サマリー

← 一覧へ戻る
プログラミング

LinuxがStrncpyを廃止

Linux Kills Strncpy (smist08.wordpress.com)

16 pointsby ingve5 コメント

要約

C言語の標準文字列関数である`strncpy`は、その設計上の欠陥から長年にわたりバッファオーバーランなどのセキュリティ問題を引き起こしてきました。Linuxカーネルは、これらの問題を解決するため、6年の歳月と360以上のパッチを費やして`strncpy`の使用を完全に排除しました。これにより、より安全で効率的な`strscpy`などの新しい関数に置き換えられ、Linuxカーネルのセキュリティが大幅に向上しました。

全文翻訳

Stephen Smithのブログ 機械学習に関する考察… Linuxがstrncpyを廃止 コメントを残す » はじめに C言語の文字列ライブラリはコンパクトで高速かつ効率的です。しかし、正しく注意して使用しないと、バッファオーバーランエラーを引き起こし、プログラムがクラッシュしたり、さらに悪いことに任意のコードが実行されたりする可能性があります。ハッカーは、C言語の文字列関数の使用におけるエラーを、悪用すべきセキュリティの弱点の宝庫と見なしてきました。LinuxカーネルはC言語で書かれており、これらの文字列関数を使用しているため、カーネルの文字列使用における問題の修正と文字列ライブラリのAPIの改善に多くの時間を費やしてきました。 多くの問題の根本的な原因は、`strcpy(dest, src);` 関数です。これは、NULL終端文字に到達するまでsrcからdestにバイトをコピーします。問題は、src文字列が宛先バッファよりも大きい場合、またはsrc文字列がまったくNULL終端されていない場合です。この場合、destバッファが上書きされ、その後ろのメモリがすべて消去されます。バッファがスタック上にある場合、これによりハッカーは関数のリターンアドレスを上書きし、ハッカーが選択したアドレスを設定できるようになります。 この問題に対する元の修正策は `strncpy(dest, src, n);` でした。ここでnは宛先バッファのサイズであり、nに達するとコピーが停止します。これにより、メモリが上書きされることはありません。問題は、結果としてdest内の文字列がNULL終端されないことです。これにより、次のような形式のコードが多用されるようになりました。 ```c strncpy(dest, src, sizeof(dest)); dest[sizeof(dest)-1] = '\0'; ``` これによって生じる問題は、プログラマーが2番目の文を追加するのを忘れたり、`-1`を忘れるなど、サイズを間違えたりすることです。`strncpy`にはもう1つの特徴があり、常にnバイトをコピーします。srcがdestよりも短い場合、残りをNULLバイトでパディングします。ほとんどのプログラマーはこれが何をするのかさえ知らず、一般的にこれはめったに必要とされない不要な作業です。 strncpyの削除は大変な作業だった Linuxカーネルから`strncpy`のすべてのインスタンスを削除するには、6年の歳月と360を超えるパッチが必要でした。これはかなりの作業でした。その主な理由は、各インスタンスを検討し、その代わりに正しい関数を使用する必要があったからです。これは単なるコピー/ペーストの問題ではありませんでした。新しい関数には、より良いエラーリターンがあり、リターンコードに基づいて何が起こったかをテストできます。Linuxカーネルの多くの古いメモリおよび文字列ライブラリには、さまざまなサポートされているプロセッサ用のアセンブリ言語バージョンがあります。新しい文字列関数についてはあまり見かけないので、おそらく、いくつかの巧妙なアセンブリ言語でさらに高速なコードを生成する余地があるかもしれません。 strncpyに代わるものは何か? 新しい関数は、文字列が文字列であることを保証し、文字列のオーバーフロー保護を`strncpy`のバッファパディング機能から分離します。これにより、何が行われているかがより明確になり、不要なコード実行が排除されることで効率が向上します。最も一般的な代替は`strscpy(dest, src, n);` です。これは、destバッファが文字列であることを保証します。つまり、必要に応じて最後のバイトを`'\0'`に設定します。バッファパディングは行わず、src文字列が切り詰められた場合は `E2BIG` を返します。`strscpy_pad()` はバッファパディングを追加します。関連する関数の全リストは以下のとおりです。`mem*` 関数は常に固定サイズ用であり、NULL文字を他の文字と同様に扱います。 使用例 推奨される関数 理由がより明確 通常のNULL終端された宛先文字列にコピーする `strscpy()` 宛先サイズがゼロでない場合にコピーを制限し、終端を保証する。 NULL終端された文字列にコピーし、残りをゼロ埋めする `strscpy_pad()` `strncpy()`から偶然に継承するのではなく、意図的にパディングを維持する。 固定幅の非文字列メモリフィールドにテキストをコピーする `strtomem_pad()` 宛先がC文字列ではなくメモリであることを明確にする。 制限された値をコピーし、未使用のスペースを明示的にパディングする `memcpy_and_pad()` バイトコピーのセマンティクスと文字列のセマンティクスを分離する。 既知のバイト数をコピーする `memcpy()` 文字列の終端やパディングの動作が不要であることを示す。 まとめ Cプログラミング言語とその文字列ライブラリは1972年から存在しています。その間、今日使用されているほぼすべてのオペレーティングシステムは、コンパイラ、システムソフトウェア、アプリケーションソフトウェア、ゲームとともにC言語で書かれています。1972年当時、目標は可能な限り高速で効率的であることでした。コンピュータがネットワークに接続されていなかったため、ハッカーは懸念事項ではありませんでした。C文字列ライブラリには、これほど広範囲に使用されるだけの多くの利点がありました。その後数年間で、APIの亀裂が現れ、それらを適切に修正することは驚くほど困難でした。ある場所をパッチすると、別の場所に問題が現れます。これらの変更により、Linuxカーネルは、その評価されている効率性を維持しながら、さらに安全になることを願っています。これは、優れたAPI設計の重要性を示しており、その問題にもかかわらず、C文字列ライブラリは長い間存続してきました。これらの調整は、ライブラリの意図を維持しながら、最も明白な欠点を修正しているようです。 これを共有する: Xで共有 (新しいウィンドウで開く) X Facebookで共有 (新しいウィンドウで開く) Facebook LinkedInで共有 (新しいウィンドウで開く) LinkedIn Redditで共有 (新しいウィンドウで開く) Reddit いいね ロード中… 関連 smist08によって2026年6月25日午前11時03分に書かれました プログラミング、ソフトウェアアーキテクチャに投稿 タグ: c, linux, linux kernel, strcpy, string library, strncpy, strscpy « ARMはどこにでもなろうとしている コメントを残す 返信をキャンセル Δ このサイトはAkismetを使用してスパムを削減しています。コメントデータがどのように処理されるかをご覧ください。 ページ 概要 すべての記事 影響 Raspberry Piの記事 Raspberry Piアセンブリ言語プログラミング Sage 300の記事 ビデオ 検索 サイト内検索 アーカイブ ブログロール John Thomas Sage City SCUMB Stephen SmithのAmazon著者ページ Sun Coast Amateur Radio Club Society The Write Cup アーカイブ 2026年6月 2026年5月 2026年4月 2026年3月 2026年2月 2026年1月 2025年12月 2025年11月 2025年10月 2025年4月 2025年3月 2025年2月 2024年12月 2024年11月 2024年10月 2024年8月 2024年7月 2024年6月 2024年5月 2024年4月 2024年3月 2024年2月 2024年1月 2023年12月 2023年6月 2023年4月 2023年3月 2023年2月 2023年1月 2022年12月 2022年11月 2022年10月 2022年9月 2022年8月 2022年7月 2022年6月 2022年5月 2022年4月 2022年2月 2022年1月 2021年12月 2021年11月 2021年10月 2021年9月 2021年8月 2021年4月 2021年3月 2021年2月 2021年1月 2020年12月 2020年11月 2020年10月 2020年9月 2020年8月 2020年7月 2020年6月 2020年5月 2020年4月 2020年3月 2020年2月 2019年12月 2019年11月 2019年9月 2019年8月 2019年4月 2019年3月 2019年2月 2019年1月 2018年12月 2018年10月 2018年9月 2018年8月 2018年2月 2018年1月 2017年12月 2017年11月 2017年10月 2017年9月 2017年8月 2017年7月 2017年6月 2017年5月 2017年3月 2017年2月 2016年10月 2016年9月 2016年8月 2016年6月 2016年5月 2016年4月 2016年3月 2016年2月 2015年12月 2015年11月 2015年10月 2015年9月 2015年8月 2015年7月 2015年4月 2015年3月 2015年2月 2015年1月 2014年12月 2014年11月 2014年10月 2014年9月 2014年8月 2014年7月 2014年6月 2014年5月 2014年4月 2014年3月 2014年2月 2014年1月 2013年12月 2013年11月 2013年10月 2013年9月 2013年8月 2013年7月 2013年6月 2013年5月 2013年4月 2013年3月 2013年2月 2013年1月 2012年12月 2012年11月 2012年10月 2012年9月 2012年8月 2012年7月 2012年6月 2012年5月 2012年4月 2012年3月 2012年2月 2012年1月 2011年12月 2011年11月 2011年10月 2011年9月 2011年8月 2011年7月 2011年6月 2011年5月 2011年4月 2011年3月 2011年2月 2011年1月 2010年12月 2010年11月 2010年10月 2010年9月 2010年8月 2010年7月 2010年6月 2010年5月 2010年4月 2010年3月 2010年2月 2010年1月 2009年12月 2009年11月 2009年10月 2009年9月 2009年8月 2009年7月 2009年6月 2009年5月 2009年4月 2009年3月 2009年2月 2009年1月 カテゴリ 3Dプリンティング アマチュア無線 人工知能 アセンブリ言語 ビジネス クラウド CRM エレクトロニクス fpga ga