カーネル
OSの中心で、CPUやメモリ、デバイスを管理するプログラム。
仕組みを見る
アプリとハードウェアの間に入り、CPU時間、メモリ、デバイスへのアクセスを管理します。Linuxという言葉は、狭い意味ではこのカーネルを指します。
各ページの強調語をまとめて読む
用語の表記、短い定義、仕組みの説明をまとめています。
OSの中心で、CPUやメモリ、デバイスを管理するプログラム。
アプリとハードウェアの間に入り、CPU時間、メモリ、デバイスへのアクセスを管理します。Linuxという言葉は、狭い意味ではこのカーネルを指します。
コンピューターに実行させる命令とデータを記録したもの。
実行ファイルとして保存されている段階では、CPUで処理されていません。起動すると、その実行を管理するプロセスが作られます。
実行中のプログラムに、仮想アドレス空間やファイルディスクリプタ表などの実行環境を持たせた管理単位。
一つ以上のスレッドを含みます。別のプロセスとは通常、仮想アドレス空間やファイルディスクリプタ表などが分かれています。
プロセス内で命令を順に実行する流れ。
各スレッドはCPUレジスタ、命令位置、stackを個別に持ちます。同じプロセスのスレッドは、code、data、heap、open filesなどを共有します。
プログラムが実行中に必要な大きさを確保し、不要になれば解放するメモリ領域。
Cではmallocやfree、C++ではnewやdeleteなどを通して使います。同じプロセスのスレッドはheapを共有します。Linux上のメモリアロケータは、必要に応じてbrkやmmapで仮想アドレス空間を広げます。
カーネルや別のプロセスが、プロセスへイベントの発生を非同期に知らせる仕組み。
終了要求、端末からの割り込み、不正なメモリアクセス、子プロセスの終了などを知らせます。プロセスはシグナルごとに既定の動作を使うか、処理する関数を登録できます。
呼び出したプロセスをもとに、子プロセスを作るためのUnix系OSのAPI。
親子は別の仮想アドレス空間を持ちます。Linuxではcopy-on-writeを使い、書き込みが起きるまで多くの物理pageを共有します。forkの後にexecveを呼び、別のプログラムを実行する使い方が一般的です。
子タスクを作り、親と共有する実行環境を細かく指定できるLinuxのシステムコール。
仮想アドレス空間、ファイルディスクリプタ表、シグナル処理、namespaceなどを共有するか選べます。スレッドやコンテナの土台となるプロセスを作るときに使われます。clone3は引数を構造体で渡す新しいインターフェースです。
LinuxカーネルがCPUへ割り当てる実行単位。
Linuxではプロセスと各スレッドをtask_structで管理します。CPUスケジューラは、このタスクを単位に扱います。
CPUが空けば実行できる状態。
LinuxのTASK_RUNNINGは、CPUで実行中のタスクと、runqueueで順番を待つタスクを含みます。I/Oやイベントを待つタスクは、待つ条件が満たされて実行可能な状態へ戻るまで、選択対象から外れます。
プロセスが、開いたファイルや通信接続を指定するために使う整数。
Linuxカーネルはプロセスごとにファイルディスクリプタ表を持ちます。read、write、closeなどのシステムコールは、この番号で操作する対象を指定します。
readやwriteなどのI/O操作を、現在は待たずに進められる状態。
読み込みなら受信データがある、書き込みなら送信領域に空きがある、といった状態です。select、poll、epollは、監視対象のreadinessをアプリへ知らせます。
多数のファイルディスクリプタから、現在I/Oを進められる対象を受け取るLinuxのAPI。
epoll_ctlで監視対象を登録し、epoll_waitでready listにあるイベントを受け取ります。level-triggeredとedge-triggeredの二つの通知方法があります。
I/O操作の依頼と完了結果を、共有メモリ上の二つのqueueで受け渡すLinuxのAPI。
アプリはSubmission Queueへ操作を登録し、カーネルはCompletion Queueへ結果を登録します。複数の操作をまとめて依頼できます。
現在実行中のタスクと、次に実行する候補をCPUごとに管理する構造。
各CPUのrunqueueは、スケジューリングクラスごとのデータ構造を持ちます。複数CPUでは、負荷を分散するためにタスクを別のrunqueueへ移すこともあります。
LinuxがCPUを割り当てる対象として認識する、個別の実行単位。
物理コアは少なくとも一つのlogical CPUとして見えます。SMTに対応するCPUでは、一つの物理コアが複数のlogical CPUとして見える場合があります。Linuxはlogical CPUごとにrunqueueを持ちます。
一つの物理CPUコアへ複数の実行状態を持たせ、Linuxから複数のlogical CPUとして見せる機能。
Simultaneous Multithreadingの略です。実行資源の一部を共有するため、logical CPUの数と同じ倍率で処理性能が増えるわけではありません。IntelのHyper-Threading TechnologyはSMTの実装例です。
Linuxで、同じプロセスに属するスレッドをまとめて扱う単位。
各スレッドは個別のtask_structを持ち、同じthread group ID(TGID)を共有します。通常、ユーザー空間から見えるプロセスIDはthread group leaderのIDです。
スレッドを実行できるCPUの集合を指定する仕組み。
スケジューラは指定された集合の中から実行先を選びます。sched_setaffinityやcgroupのcpusetなどで範囲を制御できます。
実行可能なタスクをCPUへ割り当てるカーネルの仕組み。
次に実行するタスクの選択、実行中タスクの中断、CPU間の配置を扱います。通常、リアルタイム、deadlineなどの方針は、スケジューリングクラスごとに実装されています。
実行中のタスクを中断し、別のタスクへCPUを渡すこと。
優先度の高いタスクが実行可能になった場合や、各スケジューリングクラスの条件を満たした場合などに起こります。
CPUで実行するタスクを入れ替える処理。
現在のタスクのCPUレジスタなどを保存し、次のタスクの状態を読み込みます。切り替え自体にもCPU時間が必要です。
各タスクがどれだけCPUを使ったか比べるための時計。
優先度を考慮して進み方を調整します。CFSやEEVDFが公平さを判断する材料です。
選択対象になったタスクから、仮想デッドラインが最も早いものを選ぶアルゴリズム。
Linux 6.6からfairクラスのタスク選択に使われています。仮想デッドラインは公平さを計算するための値です。実時間の制約にはSCHED_DEADLINEなどを使います。
PID、マウント、ネットワーク、ホスト名などの参照範囲を、プロセス群ごとに分ける仕組み。
プロセスID、ネットワーク、マウント位置、ホスト名などを分けられます。コンテナの『見える範囲』を作ります。
プロセス群ごとに、CPU時間、メモリ、I/Oの使用量や優先度を管理する仕組み。
CPU、メモリ、I/Oなどの利用を計測し、重みや上限を設定します。
同じカーネルを共有しながら、プロセスを分離して動かす環境。
Linux上のコンテナは、namespace、cgroup、capability、ファイルシステムなど複数の機能を組み合わせて作ります。
一台の物理コンピュータ上で動く、別のコンピュータのような環境。
ゲストOSは自分のカーネルを持ちます。LinuxではKVMとQEMUなどを組み合わせて動かします。
仮想マシンへCPUやメモリを割り当てる仕組み。
KVMはLinuxカーネルの仮想化機能です。デバイスモデルなどはQEMUのようなユーザー空間プログラムが担います。
仮想マシンの中で、さらにハイパーバイザと仮想マシンを動かす構成。
物理ホストをL0、その上のゲストハイパーバイザをL1、さらに内側のゲストをL2と呼びます。CPU機能やlive migrationの対応範囲は構成によって異なります。
Linuxをハイパーバイザとして使うための、カーネル内の仮想化サブシステム。
ユーザー空間へ/dev/kvm APIを提供し、仮想マシンと仮想CPUの状態、ゲストメモリの対応、仮想マシン内の命令実行、割り込みやタイマーの一部を管理します。
仮想マシンのメモリ、起動環境、デバイスを用意するユーザー空間のプログラム。
KVMと組み合わせる場合は、仮想CPUの実行をKVMへ頼みます。KVMを使わず、TCGでCPU命令を変換して別のCPUアーキテクチャを動かすこともできます。
ゲストOSを修正せずに動かせるよう、CPUやデバイスの環境を用意する方式。
KVMはCPUの仮想化支援機能を使い、ゲストOSの特権命令を処理します。I/Oにはデバイスエミュレーションとvirtioのどちらも組み合わせられます。
QEMUなどが、既存の物理デバイスと互換の動作を再現する方式。
ゲストOSは、既存のデバイス用ドライバを使えます。ホスト側はレジスタ操作、割り込み、データ転送などを処理します。
ゲストOSが仮想環境向けのインターフェースを使う方式。
ゲスト側の専用ドライバとホスト側の装置モデルが、仮想環境向けの形式でやり取りします。virtioはI/Oデバイス向けの標準仕様です。
仮想マシン向けに標準化されたI/Oデバイスの仕様。
ゲスト側のドライバとホスト側のデバイス実装が、対応機能を確認してからvirtqueueで要求と完了を渡します。ネットワーク、ブロックデバイス、コンソールなどの種類があります。
virtioドライバとデバイス実装が、I/O要求と完了を受け渡すキュー。
ゲスト側のドライバは、データを置いたメモリ領域の情報をキューへ登録します。ホスト側の実装は要求を処理し、使用済みの領域としてゲストへ返します。
QEMUで、I/Oのevent loopをmain loopとは別に動かすスレッド。
対応するデバイスの処理をIOThreadへ割り当てると、QEMUのmain loopへI/O処理が集中するのを避けられます。複数のIOThreadへ処理を分ける構成では、別々のホストCPUでI/Oを進められます。
virtioのデータ処理をホストカーネルで行う仕組み。
QEMUが制御情報を設定した後、ネットワークやストレージのデータ処理をカーネル側で進め、QEMUプロセスへ戻る回数を減らします。
デバイスがCPUを介さず、RAMへ直接データを転送する機能。
Direct Memory Accessの略です。NIC、ストレージ、GPUなどが大量のデータを転送するときに使います。デバイスが読み書きできるRAMの範囲はIOMMUで制限できます。
デバイスのDMAアドレスを変換し、アクセスできるRAMの範囲を制限するハードウェア。
Input-Output Memory Management Unitの略です。CPUのMMUがプログラムの仮想アドレスを変換するのに対し、IOMMUはデバイスがDMAで使うI/O仮想アドレスを変換します。Intel VT-dやAMD-Viなどがあります。
ホストのPCIデバイスまたはPCI Functionを、仮想マシンへ直接割り当てる構成。
ゲストOSのドライバが割り当てられたFunctionのレジスタ、割り込み、DMAを使います。LinuxではVFIOとIOMMUを組み合わせる構成が一般的です。
IOMMUで保護したデバイスを、ユーザー空間から安全に扱うためのLinuxカーネルの枠組み。
Virtual Function I/Oの略です。仮想マシンへ物理PCIデバイスを割り当てる用途などで使います。IOMMU groupが、ほかのデバイスから分離して扱える単位になります。
一つのPCI Expressデバイスを、複数の独立した機能として見せるハードウェアの機能。
Single Root I/O Virtualizationの略です。管理用のPhysical Function(PF)と、仮想マシンなどへ割り当てるVirtual Function(VF)を作ります。デバイス側の対応が必要です。
動作中の仮想マシンの状態を別のホストへ転送し、実行先を切り替える処理。
RAM、仮想CPU、仮想デバイスなどの状態を転送します。必要な停止時間と、移動できるデバイスの範囲は構成によって変わります。
コンパイル済みのプログラムとOSやlibraryが、binary levelでやり取りするための約束。
関数の呼び出し規約、registerとstackの使い方、data layout、システムコール番号などを定めます。システムコールは個々の依頼で、ABIはその番号や引数を渡す方法まで含む約束です。Linuxは既存のユーザー空間ABIを壊さない方針を強く守ります。
ユーザー空間のプロセスが、Linuxカーネルへ処理を頼むための入口。
ファイルを読む、通信する、プロセスを作る、仮想アドレス空間を変更するといった操作に使います。多くのアプリはlibcなどのラッパー関数を通して呼び出します。
アプリやライブラリが動き、プロセスごとの仮想アドレス空間を使う範囲。
通常はCPUのuser modeで実行され、特権命令やカーネルのメモリへ直接アクセスできません。カーネルへ処理を頼むときはシステムコールを使います。
Linuxカーネルのコードとデータが置かれ、OSの中核処理が動く範囲。
プロセス管理、メモリ管理、ファイルシステム、network stack、デバイスドライバなどが動きます。カーネルの処理はCPUのkernel modeで実行されます。
実行できる命令とアクセスできる範囲を、CPUが制限する仕組み。
アプリは通常user mode、カーネルはkernel modeで動きます。システムコール、割り込み、例外などを入口としてkernel modeへ移り、処理後にuser modeへ戻ります。
カーネル本体を書き換えず、用途に合わせたプログラムをカーネル内で実行する仕組み。
ユーザー空間のツールがbpfシステムコールでプログラムを読み込みます。カーネルは実行前に命令とメモリアクセスを検査し、許可したプログラムを対応するイベントが起きたときに実行します。Linuxカーネルの文書ではBPFと表記されることもあります。
BPFプログラムをカーネルへ読み込む前に、命令やメモリアクセスを検査する仕組み。
プログラムの処理経路、レジスタの型、アクセス先などを追跡します。安全に実行できると確認できないプログラムは、カーネルへ読み込まれません。
BPFプログラムとユーザー空間のプログラムが、データを保持・共有するための構造。
hash、array、ring bufferなど用途の異なる種類があります。統計値や設定、イベントデータなどの受け渡しに使います。
特定の処理が起きたとき、追加のプログラムや確認処理を呼び出すために用意された位置。
BPFプログラムの取り付け先や、LSMがアクセス制御を呼び出す位置などを指します。利用できる情報と処理はhookの種類ごとに異なります。
次のリリースへ新機能を取り込む、約2週間の期間。
終了後はリリース候補を毎週出し、主に修正と安定化を進めます。
正式リリース前に、広く試して不具合を直す候補。
通常は週に一度更新されます。回数はカーネルの状態に応じて増減します。
連続する一つ以上のpageを、まとまりとして扱うための型。
Linux 5.16で導入されました。page cacheなどで複数のpageをまとめて処理でき、1 pageだけを表す場合もあります。
プロセスのアドレス空間で、命令がメモリを参照するときに使うアドレス。
物理RAMの位置とは分離されており、ページテーブルを使って変換されます。別のプロセスが同じ仮想アドレスを使っても、異なる物理領域へ対応づけられます。
一つのプロセスが使用できる仮想アドレスの範囲。
code、data、heap、共有ライブラリ、memory-mapped files、stackなどの領域が配置されます。実際に物理RAMへ対応づけられている範囲だけで構成されるわけではありません。
実行中のコードやデータを保持し、CPUから読み書きされる有限の記憶領域。
Linuxは物理RAMをpage frameへ分け、カーネルと各プロセスへ割り当てます。電源を切ると内容は失われます。
CPUが仮想アドレスを物理アドレスへ変換するための回路。
Memory Management Unitの略です。Linuxが用意したページテーブルを参照して変換し、許可されていないアクセスではページフォールトを発生させます。
プロセスの仮想アドレス空間で、コードやデータの配置を実行ごとに変える仕組み。
Address Space Layout Randomizationの略です。配置を予測しにくくし、既知のアドレスを使う攻撃を難しくします。
メモリの大きさを数える基本単位。Linuxでは1 byteは8 bit。
mallocへ渡す大きさや、配列の要素が占める大きさなどをbyte単位で表します。通常のLinuxでは、各仮想アドレスが1 byteの位置を指します。
メモリ上の位置を示すアドレスを保持する値。
mallocやmmapは、利用できる仮想アドレス範囲の先頭をポインタとして返します。プログラムはポインタを通して、その範囲を読み書きします。
必要なbyte数を指定し、利用できるメモリ領域を得るCライブラリ関数。
glibcのmallocは、プロセス内の空き領域を再利用します。不足すればbrkやmmapを使って仮想アドレス空間を広げます。戻り値は領域の先頭を示すポインタです。
プロセスのheapの終端を動かし、利用できる仮想アドレス範囲を広げたり縮めたりするシステムコール。
glibcのmallocがLinuxから領域を得る方法の一つです。アプリケーションが直接使うより、mallocなどのメモリアロケータを通して使われるのが一般的です。
プロセスの仮想アドレス空間へ、新しい範囲を追加するシステムコール。
ファイルの内容を対応づけるfile-backed mappingと、特定のファイルを持たないanonymous mappingを作れます。読み取り、書き込み、実行などの権限も指定します。
最近使ったアドレス変換結果をCPU内へ保持するcache。
ページテーブルを毎回たどる処理を減らします。必要な変換がTLBにない場合、CPUはpage table walkを行います。
仮想アドレス空間と物理RAMを、一定の大きさに区切って管理する単位。
仮想アドレス空間側の区画をvirtual page、物理RAM側の区画をpage frameと呼び分けます。x86-64では4 KiBが広く使われますが、大きさはアーキテクチャや設定によって異なります。
仮想アドレスと物理RAMの対応を記録する表。
CPUのMMUはページテーブルを使ってアドレスを変換します。Linuxカーネルは対応関係を作成し、変更し、不要になれば破棄します。
現在のページテーブルだけではメモリアクセスを完了できないときにCPUが起こす例外。
Linuxは、必要なpageの割り当て、ファイルからの読み込み、アクセス権の確認などを行います。正当なアクセスならページテーブルを更新して命令を再開します。
特定のファイルを保存元として持たないメモリ。
ヒープや多くのスタックが該当します。reclaim時に内容を保持する必要があれば、swapへ退避できます。
ファイルの内容をRAMへ保持し、読み書きを速くする仕組み。
変更されていないpageは捨ててもファイルから再読込できます。変更済みのpageは、必要に応じてストレージへ書き戻します。
RAM上のanonymous memoryを一時的に退避できる、ストレージ上の領域。
退避した内容が再び必要になるとRAMへ読み戻します。swap partitionやswap fileを使用できます。
空きRAMを増やすため、使用中のpageを回収候補から選んで解放する処理。
page cacheの破棄や書き戻し、anonymous memoryのswapなどを行います。どのpageを選ぶかが性能に影響します。
reclaimで必要な空きRAMを作れないとき、プロセスを終了させてシステムを動かし続ける仕組み。
Linuxはメモリ使用状況などから終了対象を選びます。cgroup単位でOOMを処理する場合もあります。
pageを参照時期の世代に分け、reclaimの候補を選ぶ仕組み。
Linux 6.1で導入されました。参照が新しいpageと古いpageを複数の世代で追跡します。
カーネル内の小さなオブジェクトを割り当てる仕組み。
page allocatorから得た領域を、task_structやinodeなどの型に合う小さな区画へ分けて再利用します。
空いている物理pageを、2の累乗個からなる連続領域として管理する仕組み。
必要に応じて領域を半分に分けます。隣り合う同じ大きさの領域が両方とも空くと、再び一つの大きな領域へ結合します。
カーネル内の操作へ、アクセス制御を呼び出すhookを用意する共通の枠組み。
ファイル、socket、プロセスなどを操作する箇所で、有効なsecurity moduleを呼び出します。SELinux、AppArmor、Landlockなどが、このhookを使います。
カーネルがプロセスの身元と権限を確認するために保持する情報。
UID、GID、補助グループ、capabilityの集合、keyring、LSMが使うセキュリティ属性などを含みます。Linuxカーネルではstruct credを中心に管理します。
所有者が設定できる権限をもとに、対象へのアクセスを確認する仕組み。
Discretionary Access Controlの略です。Unixのファイルでは、所有者のUIDとGID、user・group・otherのmode、ACLなどをプロセスのcredentialと照合します。
従来rootへまとめて与えられていた権限を、操作の種類ごとに分けた単位。
network設定、時刻変更、process trace、kernel moduleの読み込みなどを別々に許可できます。各threadはeffective、permitted、inheritable、bounding、ambientなどのsetを持ちます。
プロセスが呼び出せるシステムコールと引数をfilterで制限する仕組み。
システムコール番号、CPU architecture、引数の値を検査し、許可、errno、プロセス終了、通知などの結果を返します。カーネル内で到達できる処理を減らすために使います。
一般ユーザーのプロセスも、自分と子孫のアクセス権を狭められるLSM。
ファイル階層、network port、signal、UNIX domain socketなどをrulesetで制限します。ほかのアクセス制御へ重ねて適用でき、制限後に権限を広げる操作はできません。
execve後も、現在より強い権限を得ないとカーネルへ約束する属性。
set-user-ID、set-group-ID、file capabilityによる権限の追加を止めます。一般ユーザーがseccomp filterやLandlock rulesetを自分へ適用するときに使います。
カーネル処理の最大遅延を小さくし、ばらつきを抑えるリアルタイム対応。
6.12で公式カーネルの対応範囲が大きく広がりました。達成できる最大遅延は、CPU、ドライバ、カーネル設定を含む実機測定で評価します。
実行中のプロセスを、後で再開できる形で保存すること。
メモリ、CPUレジスタ、開いているファイル、プロセスの親子関係などを記録します。復元側ではプロセスID、ファイルディスクリプタ、親子関係なども作り直します。
Linuxプロセスやコンテナをユーザー空間から保存・復元するソフトウェア。
Checkpoint/Restore In Userspaceの略です。namespace、cgroup、ptrace、procfs、各種カーネルAPIを組み合わせて動きます。
cgroupに属するプロセス群をまとめて一時停止し、後で再開する機能。
checkpoint時に対象の実行状態が変化しないよう止める用途などで使われます。cgroup v2ではcgroup.freezeを通して制御します。
process IDが1で、孤児になったプロセスの終了状態を回収するプロセス。
Linuxの起動時に作られるPID namespaceと、コンテナなどが新しく作るPID namespaceには、それぞれPID 1があります。通常のプロセスとはシグナルの扱いが異なります。
システムを監視したり、ほかのプロセスへ機能を提供したりするプロセス。
従来のdaemonは端末から離れるためにforkを重ね、主プロセスのPIDをファイルへ記録することがありました。systemdが管理する構成では、初期化や監視をサービスマネージャーへ任せ、プロセス自身はforkで離脱しない形が推奨されます。
実行は終わっているが、親が終了状態をまだ受け取っていないプロセス。
カーネルは終了コードや使用時間などを保持します。親がwait、waitpid、waitid、wait4などを呼ぶと終了状態が読み取られ、プロセス表から取り除かれます。親がSIGCHLDをSIG_IGNに設定するか、SA_NOCLDWAITを使う場合は、終了した子をカーネルが自動で回収します。
起動中に一時的なrootファイルシステムとして使い、ストレージを読み出す準備をする小さなユーザー空間。
ストレージや暗号化に必要なドライバとツールを含められます。中にあるinitが、起動後に使うrootファイルシステムを見つけてmountし、rootを切り替えます。
PID 1として起動処理とサービス管理を担う、ユーザー空間のソフトウェア群。
unitの依存関係を解決し、サービスごとのcgroup、socket activation、timer、mount、サービスの実行環境などを管理します。Linuxカーネルの一部ではありません。
利用者やほかのプログラムへ提供される処理や機能を、この教材でまとめて指す言葉。
サービスはLinuxカーネルの実行単位ではありません。実際の処理は一つ以上のプロセスが担います。systemdはservice unitを使い、そのプロセスの起動、停止、監視を管理します。
unitをstart、stop、reloadする要求を、systemdが実行順序とともに管理する一時的な単位。
要求された操作と依存するunitの操作をtransactionへまとめ、job queueへ入れます。操作が完了するとjobも完了します。起動されたプロセスそのものではありません。
systemdが起動、停止、監視、依存関係の管理を行う対象。
service、socket、target、timer、mount、slice、scopeなどの種類があります。依存関係と起動順序は別々の設定で表します。
サービスより先に待ち受けsocketを用意し、接続を契機にサービスを起動する方法。
systemdがsocketを作り、起動したサービスへファイルディスクリプタを渡します。サービスの起動中に届いた接続は、カーネルのlisten queueで待てます。
孤児になった子孫プロセスを、PID 1より手前で引き取るよう指定されたプロセス。
Linux 3.4で追加されました。PR_SET_CHILD_SUBREAPERを設定したプロセスは、子孫の親が終了したとき、新しい親の候補になります。サービスマネージャやコンテナの監視プロセスなどが利用できます。
公開された脆弱性に、世界で共通の識別番号を付ける仕組み。
CVE-2016-5195のように「CVE-西暦-連番」で表します。番号はCNA (CVE Numbering Authority)と呼ばれる組織が割り当てます。2024年からはLinuxカーネルコミュニティ自身がCNAとなり、安定版へ入った修正を基準に自らCVEを割り当てています。
利用者を直接攻撃せず、依存するソフトウェアの開発・配布の経路へ不正なコードを混ぜる攻撃。
オープンソースでは、ライブラリ開発への参加、ビルド環境、配布物の改ざんなどが経路になります。2024年に報告されたxz utilsの事例では、公開されたリリースに、ビルド時へ不正なコードを挿入する仕組みが含まれていました。