プログラミング
LinuxがStrncpyを廃止
Linux Kills Strncpy (smist08.wordpress.com)
要約
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