世界を動かす技術を、日本語で。

Linux、6年の作業と360のパッチを経てstrncpy APIを廃止

2026年6月21日原文(phoronix.com)

概要

  • Linux 7.2strncpy API がカーネルから完全削除
  • strncpy() は長年バグの温床として問題視
  • 6年・362コミット で全ユーザー除去
  • 新APIとして strscpy() などを推奨
  • パフォーマンス・安全性向上が主な目的

Linux 7.2でstrncpy APIがカーネルから完全削除

  • Linux 7.2 にて、カーネル内の strncpy() API がついに完全削除
  • strncpy()関数 は、指定バイト数コピー用だが、 NUL終端処理の直感に反する挙動冗長なゼロ埋め によるパフォーマンス問題で長年非推奨
  • strncpy() は「バグの温床」として多くの問題を引き起こしてきた歴史
  • 6年・362件のコミット を経て、全ての strncpy利用箇所 を削除
  • 金曜日のマージ で、API本体と各CPUアーキテクチャ毎の実装も削除完了

代替APIとその用途

  • strscpy() :NUL終端を保証する文字列コピー

  • strscpy_pad() :NUL終端+ゼロパディング付き文字列コピー

  • strtomem_pad() :NUL終端不要な固定長フィールド用コピー

  • memcpy_and_pad() :明示的なパディングを伴うバウンデッドコピー

  • memcpy() :長さが既知のメモリコピーに使用

    • これらのAPIにより 安全性・パフォーマンス の両立を実現

今後の展望

  • strncpy()削除 により、今後のカーネル開発で バグ発生率低減 を期待
  • 新API の明確な役割分担による コード品質向上
  • 詳細やコミット履歴はLinux Kernel Gitリポジトリ参照

Hackerたちの意見

ゼロ終端の文字列は、コンピュータの最大のミスだと思う。パスカルスタイルの文字列の方がずっと安全だったよね。

ポインタの割り当て方としては面白い方法だったね。昔、大きなプロジェクトで開発者たちがこれを理解してなくて、オフバイワンやメモリの上書きが何百件も発生したことがあったよ。でも、ソフトウェアを責めるのはちょっと逃げだと思う。開発者たちは急いでて、ルールを尊重してなかったんだよね。今のソフトウェアエンジニアを見てると、プログラミング言語を壊れないように弱体化させるのも悪くないかも。でも、AIがすべてを弱体化させるだろうね。

長さカウンタのサイズを選んで、後でバイト、コードポイント、グリフの長さを区別しなきゃいけない上に、ポインタ算術を使ってパスカル文字列を分割することもできない。文字列の終わりを関数に渡すには、パスカルスタイルの文字列の末尾を別の小さいサイズの文字列にコピーするか、整数と実際のデータへのポインタを持つ構造体にしなきゃいけない。前者は場合によっては大量のコピーが必要だし、後者は無効なポインタを持つ構造体の問題を引き起こすかもしれない。それにキャッシュに関する潜在的な問題もあるしね。

ゼロ終端の文字列は、センチネル値の終端の特別なケースだね。センチネル値の終端は、パンチカードや固定長レコードを切り分ける必要があるときにすごく理にかなってる。1960年代や1970年代に彼らがしていた決定が、半世紀後のコンピュータに影響を与えるなんて誰も思ってなかったよ。彼らは、自分たちのミスはいつかもっと賢い人たちによって覆い隠されるだろうと思ってたんだ。でも、私たちはみんな慣性を過小評価するミスを犯してるよね。

改行で終わる行と同じくらい最悪だね。 ;)

ゼロ終端の文字列は、たくさんの役立つソフトウェアの基盤だったよね。コンピュータの最大の間違いだと言うのはちょっと言い過ぎだと思う。30年以上Pascalに関するプログラミングはしてないけど、その頃は文字列システムがそんなに使いにくくなければいいなと思ってたのをぼんやり覚えてるよ。

255文字で十分だよね、みんなにとって。

ある程度同意するけど、サイズのデータ型については争いがあっただろうね、可変長じゃない限り。可変長だと他の問題もあっただろうし。しばらくの間、16ビットは贅沢すぎると思われてたかもしれない。今は32ビットが小さすぎるって感じるだろうね。「強く型付けされた」言語としては、Cは重要なところでかなり緩いんだよね。

ClangとGCCは、Pascal文字列をCで使うことを許可してるよ(\pを使って)。でも、Pascal文字列は今ではあまり役に立たない。最大長が短すぎるからね。

ゼロ終端文字列はコンピュータの最大の間違いだと思う いや、彼らはトレードオフをしなきゃいけなかったし、センチネルベースのシーケンスは必要なものなんだ。文字列以外でもね。間違いだったのは、ISAがHLLのニーズを見て、必要な命令を追加しなかったことだよ(詳しくは下に書いた)。NULLも、開発された時代の文脈で見れば大きな間違いじゃないんだ。

Visual Basic(その後COM)が取った中間的なアプローチがBSTR型だね。ゼロ終端のchar配列へのポインタだけど、最初のポインタ先のバイトの前に長さフィールドがあるんだ。これならCの文字列とも互換性がある(埋め込まれたヌル文字がないと仮定して)。でもBSTR型の関数は長さの値を活用できるんだよね。

スペースパディッド文字列を使ったWin32アプリに関わったことがあるんだけど、つまり、宛先の文字列はスペースでパディングされてたけど、最後のバイトにはまだヌルがあったんだ。長さやコピーなどの文字列関数には特別なバージョンを使わなきゃいけなかった。なんでそうなってたのかはよくわからないけど、ソースベースが古すぎて、パスカルの構造体の挙動に由来してるかもしれない。

Hacker Newsで議論の続きを見る