Linuxカーネルからstrncpyが消えた日|6年362コミットが示す"安全なC"の現実解

HOMEリナックスマスター.JP 公式ブログLinux情報・技術・セキュリティ > Linuxカーネルからstrncpyが消えた日|6年362コミットが示す"安全なC"の現実解
宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
「strncpy は安全な文字列コピー関数だと習った気がするのに、Linuxカーネルからわざわざ全部消したと聞いて、何が起きているのか分からない」。Cでサーバー周りのコードを書く現役エンジニアなら、2026年6月のこのニュースに引っかかった人は多いはずです。

Linuxカーネルから strncpy() が完全に削除されました。しかも一晩の作業ではなく、6年・362コミットをかけた長い掃除の末の達成です。Linux 7.2 のマージウィンドウで、Kernel Self Protection Project(KSPP)を率いる Kees Cook 氏が、最後に残っていた箇所を自ら片付けて完了しました。

20年以上 Linux サーバーの現場にいますが、「教科書的に安全」とされてきた関数が、これほどの労力をかけて駆逐されるのは珍しい出来事です。この記事では、攻撃手法の話ではなく、なぜ strncpy が危ないのか、そして自分のCコードで何を使えばいいのかという、文字列関数の現実解を整理します。

この記事のポイント
・Linuxカーネルから strncpy() が完全に削除された。6年・362コミット(一部報道は360超と表記)をかけた長期プロジェクトで、Linux 7.2 のマージウィンドウで完了。
・主導したのは KSPP(Kernel Self Protection Project)を率いる Kees Cook 氏。最後の残り箇所は本人が処理した。
・strncpy の問題は「NUL終端が保証されない」こと。コピー元が指定サイズ以上だと終端文字が付かず、その後の文字列操作が暴走する温床になる。
・一括置換できなかったのは、各呼び出し箇所の「意図」を読まないと正しい代替を選べないため。だから6年かかった。
・代替は strscpy()(NUL終端する安全な版)が基本。用途に応じて strscpy_pad() / strtomem_pad() / memcpy_and_pad() を使い分ける。

Linuxカーネルからstrncpyが消えた日|6年362コミットが示す
「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

strncpy() の何が問題だったのか

「安全そうな名前」の落とし穴

strncpy は名前に「n」が付いているため、コピーするバイト数を指定でき、バッファオーバーフローを防げる安全な関数だと誤解されがちです。実際には、これは 固定長フィールドを埋めるための関数であって、いわゆる「安全な文字列コピー」とは設計思想が違います。

最大の落とし穴は NUL終端(文字列の終わりを示す \0)が保証されないことです。挙動を整理すると、こうなります。

コピー元の長さstrncpyの挙動
指定サイズより短い残りを \0 で埋める(ゼロ埋め)
指定サイズと同じか長いNUL終端が付かない

つまり、コピー元がちょうど収まる、あるいは溢れる長さだったとき、終端文字のない「壊れた文字列」が出来上がります。これを後続のコードが普通の文字列として扱うと、メモリの隣の領域まで読み続けてしまい、情報漏えいやクラッシュにつながります。

性能面でも損をしている

もう一つ見落とされがちなのが性能の話です。strncpy はコピー元が短いと、残りのバッファを すべて \0 で埋め尽くす仕様です。長いバッファに短い文字列をコピーするだけのつもりが、内部では大量のゼロ埋めが走っている、ということが起こります。

直感に反する挙動とこの冗長なゼロ埋めの2点が、strncpy が「バグの温床であり、性能も悪い」と評価され続けてきた理由です。だからカーネル開発者たちは、これを使い続けるのではなく そもそも使わない方向へ舵を切りました。

なぜ削除に6年・362コミットもかかったのか

機械的な一括置換ができなかった

「危険な関数なら、sed で一括置換すればいいのでは」と思うかもしれません。実際、私も最初はそう感じました。ところが、それができなかったのが今回の作業が長引いた核心です。

strncpy には前述のとおり「短ければゼロ埋め、長ければ終端なし」という二面性があります。ある呼び出し箇所では「終端付きの文字列が欲しい」、別の箇所では「固定長フィールドをゼロ埋めしたい」と、意図がまったく違う。この意図を1箇所ずつ読み解かないと、正しい代替関数を選べません。

だからこそ、巨大なカーネルのコードベース全体にわたって、数百箇所を1つずつ判断していく必要がありました。6年・362コミット、そして多数の貢献者の手が入ったのは、この「機械化できない判断の積み重ね」だったわけです。

KSPPという地道な取り組みの成果

この削除を主導したのは、Google のエンジニアで Kernel Self Protection Project(KSPP、カーネル自己防衛プロジェクト)を率いる Kees Cook 氏です。KSPP は、攻撃そのものを追いかけるのではなく、バグのクラスごと根絶するという発想でカーネルを地道に堅牢化してきたチームです。

最後に残った数件は Kees Cook 氏が自ら片付け、Linux 7.2 のマージウィンドウで strncpy の利用箇所がゼロになりました。派手さはありませんが、こうした「バグの温床を構造的に潰す」取り組みこそが、長期的なセキュリティを支えています。


Linuxカーネルからstrncpyが消えた日|6年362コミットが示す

現実解:今のCコードで何を使うべきか

基本は strscpy()

カーネル開発における置き換えの基本は strscpy() です。これは「必ず NUL終端する」「コピー先サイズを超えない」という、本来 strncpy に期待されていた振る舞いを正しく実装したものです。

// avoid this: terminator may be missing
strncpy(dst, src, sizeof(dst));

// use this: always NUL-terminated, never overruns dst
strscpy(dst, src, sizeof(dst));


strscpy は終端を保証するうえに、コピーした長さ(またはエラー)を返してくれるので、終端漏れによる事故が構造的に起きません。

用途別の使い分け

すべてを strscpy に置き換えれば終わり、ではないのが今回の難しさでした。元の strncpy が「固定長フィールドのゼロ埋め」目的で使われていた箇所では、別の関数が適切です。

関数用途
strscpy()NUL終端の文字列が欲しいとき(基本形)
strscpy_pad()NUL終端+残りをゼロ埋めしたいとき
strtomem_pad()非NUL終端の固定長フィールドへ詰めるとき
memcpy_and_pad()固定長へコピーし残りをパディングするとき

ポイントは、「この箇所は終端が欲しいのか、固定長フィールドを埋めたいのか」を毎回考えることです。これはカーネルに限らず、自分でユーザー空間のCコードを書くときにもそのまま通じる判断軸です。

Cの文字列まわりは、こうした細かな挙動の差が事故に直結します。背景から腰を据えて学び直したい方には、定番の解説書を1冊手元に置くことをおすすめします。

PR

プログラミング言語C 第2版 ANSI規格準拠(K&R)

C言語と文字列・ポインタの土台を、原典で押さえ直せる定番中の定番。strncpy のような関数の「設計意図」を理解する出発点になります。

自分のCコードでstrncpyを使っている場合の対処

strncpyを使っている既存コードをどう直すか

ユーザー空間のCコードで strncpy を使っている場合、いきなり全削除する必要はありません。ただし、NUL終端を自分で保証しているかは必ず確認すべきです。よくあるのが、終端を付け忘れたまま放置されているパターンです。

# grep existing usages in your codebase
grep -rn "strncpy" ./src

// quick safety net if you must keep strncpy
strncpy(dst, src, sizeof(dst) - 1);
dst[sizeof(dst) - 1] = '\0';


上のように、最後の1バイトを必ず \0 にしておけば、終端漏れによる暴走は防げます。とはいえ、これは応急処置です。新規コードでは、終端を保証してくれる安全な関数(環境によっては strlcpy なども候補)を選ぶ方が筋がいいです。

「nが付いているから安全」という思い込みを捨てる

今回の件で現場として持ち帰るべき教訓は、関数名の印象で安全性を判断しないことに尽きます。strncpy だけでなく、strncat や snprintf にも、それぞれ固有の落とし穴があります。注意すべきは「名前」ではなく「終端とサイズの扱い」です。

本番で動くコードのレビューでは、文字列関数を見かけたら「終端は保証されているか」「サイズはバッファを超えないか」をその場で確認する。この習慣があるだけで、メモリ系のバグはかなり減らせます。


Linuxカーネルからstrncpyが消えた日|6年362コミットが示す

まとめ:strncpy削除が示す「安全なC」の現実解

今回の strncpy 完全削除を一覧で整理します。

項目内容
何が起きたLinuxカーネルから strncpy() を完全削除(Linux 7.2)
規模6年・362コミット、多数の貢献者
主導KSPP を率いる Kees Cook 氏
問題点NUL終端が保証されない+冗長なゼロ埋めで性能も悪い
現実解基本は strscpy()。用途で strscpy_pad / strtomem_pad / memcpy_and_pad を使い分け

「安全なC」とは、特定の魔法の関数を1つ覚えることではありません。各関数の挙動を正しく理解し、用途に合った道具を選ぶこと。6年・362コミットという数字は、その地道さがいかに重いかを示しています。自分のコードでも、文字列関数を見かけたら一度立ち止まる。それが現実解です。

Cのセキュアコーディングを体系的に身につけたい方には、原理から押さえられる定番書も役立ちます。

PR

Linuxプログラミングインタフェース

システムコールからメモリ・文字列の扱いまで、Linux上のCプログラミングを体系的に追える大著。なぜその関数が安全なのかを根っこから理解したい方に。

「安全なC」、根っこから理解できていますか?

文字列関数の終端とサイズの扱い、メモリの境界、システムコールの挙動。読むだけでなく、実機のLinux上で繰り返し手を動かすことで初めて身につきます。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。


Linux無料マニュアル(図解60P) 名前とメールで30秒登録