# 機能設計書 47-veriexec（実行ファイル検証）

## 概要

本ドキュメントは、FreeBSDの実行ファイル署名検証機構であるveriexec（Verified Exec）について記述する。veriexecはMACフレームワーク上のポリシーモジュールとして実装され、実行ファイルのハッシュ署名を検証してシステムの完全性を保護する。

### 本機能の処理概要

veriexecはファイルのフィンガープリント（暗号ハッシュ）をカーネル内のデータベースに登録し、ファイルの実行時や読み込み時にハッシュを検証することで、改ざんされたバイナリの実行を防止する。

**業務上の目的・背景**：高セキュリティ環境において、許可されたバイナリのみが実行されることを保証する必要がある。マルウェアやルートキットによるシステムバイナリの置き換えを検知し、システムの完全性を維持する。

**機能の利用シーン**：セキュリティクリティカルなサーバでの実行バイナリ検証、ファームウェア完全性検証、IDS（侵入検知システム）の一部としてのファイル完全性モニタリング、規制要件に基づくシステムバイナリの完全性保証に使用される。

**主要な処理内容**：
1. マニフェストファイルの読み込みと登録（veriexecコマンド）
2. 実行時のフィンガープリント検証（mac_veriexec.c）
3. 複数ハッシュアルゴリズムのサポート（SHA1, SHA256, SHA384, SHA512）
4. 検証状態の管理（enforcement, active, loaded等）
5. vnode単位でのラベル管理（MACフレームワーク統合）

**関連システム・外部連携**：MACフレームワーク（mac_policy.h）上のポリシーモジュールとして動作。VFS層と統合し、vnode操作時に検証フックを挿入。nullfsとの統合（mac_veriexec_internal.h参照）。

**権限による制御**：マニフェストのロードにはroot権限が必要。検証ポリシーの変更もroot権限が必要。enforcement状態ではいかなるユーザも未検証バイナリの実行が拒否される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （CLIベースのためGUI画面なし） | - | veriexecコマンドによるマニフェスト管理 |

## 機能種別

ファイル完全性検証 / アクセス制御 / 暗号ハッシュ検証

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| manifest_file | string | Yes（ロード時） | マニフェストファイルパス | 読み取り可能なファイル |
| hash_algorithm | string | Yes | ハッシュアルゴリズム（sha1/sha256/sha384/sha512） | サポートされたアルゴリズム名 |
| file_path | string | Yes | 検証対象ファイルパス | 有効なファイルパス |
| fingerprint | string | Yes | ファイルのハッシュ値 | 有効な16進数文字列 |

### 入力データソース

- マニフェストファイル（veriexecコマンド経由）
- カーネル内のフィンガープリントデータベース
- VFS層からのvnode操作イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| verification_result | int | 検証成功（0）/ 検証失敗（エラーコード） |
| veriexec_state | int | 現在の検証状態（loaded/active/enforce/locked） |
| file_status | int | ファイルの検証ステータス |

### 出力先

- カーネル内アクセス制御判断（MACフレームワーク経由）
- sysctl（mac.veriexec.state）

## 処理フロー

### 処理シーケンス

```
1. マニフェストファイルの解析（veriexec コマンド）
   └─ manifest_parser.yによるマニフェスト構文解析
2. フィンガープリントのカーネル登録
   └─ ioctl経由でカーネルメタデータテーブルに登録
3. 実行ファイルのvnode操作時
   └─ mac_veriexec.c: MACフック関数が呼ばれる
4. フィンガープリント計算
   └─ ファイル内容からハッシュ値を計算
5. フィンガープリント照合
   └─ 登録済みハッシュと計算結果を比較
6. アクセス制御判断
   └─ マッチすれば許可、不一致または未登録なら状態に応じて拒否
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル実行要求] --> B[MAC veriexecフック]
    B --> C{フィンガープリント登録済み?}
    C -->|No| D{enforcement状態?}
    D -->|Yes| E[実行拒否 EAUTH]
    D -->|No| F[実行許可（警告）]
    C -->|Yes| G[ハッシュ計算]
    G --> H{ハッシュ一致?}
    H -->|Yes| I[実行許可]
    H -->|No| J{enforcement状態?}
    J -->|Yes| K[実行拒否 EAUTH]
    J -->|No| L[実行許可（警告）]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | 検証状態遷移 | loaded → active → enforce → locked の順で状態遷移。locked状態ではマニフェスト変更不可 | 状態変更時 |
| BR-47-02 | 複数ハッシュサポート | SHA1, SHA256, SHA384, SHA512をサポート。セキュリティ上SHA256以上を推奨 | マニフェスト作成時 |
| BR-47-03 | nullfs統合 | nullfsマウント経由のファイルも元のvnodeのフィンガープリントで検証 | nullfs使用時 |

### 計算ロジック

- フィンガープリント計算：対象ファイル全体をハッシュアルゴリズムに入力し、ダイジェスト値を算出
- メタデータルックアップ：デバイス番号+inode番号をキーとしたハッシュテーブル検索

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。カーネル内のフィンガープリントメタデータテーブルを操作する。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| load | veriexec metadata | INSERT | フィンガープリント登録 |
| verify | veriexec metadata | SELECT | フィンガープリント照合 |
| state change | veriexec state | UPDATE | 検証状態の変更 |

### テーブル別操作詳細

#### veriexec_metadata（メタデータテーブル）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| INSERT | dev, ino, fingerprint, hash_type | マニフェストファイルの内容 | デバイス+inode番号でインデックス |
| SELECT | dev, ino | vnode操作時にデバイス+inodeで検索 | ハッシュテーブルルックアップ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EAUTH | 認証失敗 | フィンガープリント不一致（enforcement時） | 正しいバイナリに置き換え |
| EPERM | 権限不足 | 非rootでのマニフェストロード | root権限で実行 |
| EINVAL | 不正マニフェスト | マニフェスト構文エラー | マニフェストを修正 |
| ENOENT | ファイル未検出 | マニフェスト内のファイルが存在しない | ファイルパスを確認 |

### リトライ仕様

フィンガープリント検証失敗はファイル内容の問題であり、リトライでは解決しない。正しいバイナリの再インストールが必要。

## トランザクション仕様

マニフェストのロードは原子的に行われる。部分的なロードは行われず、マニフェスト全体が正常にパースされた場合のみカーネルに登録される。

## パフォーマンス要件

- フィンガープリント計算はファイルサイズに比例するI/Oを伴う
- 計算済みフィンガープリントのキャッシュによる再計算の回避
- メタデータルックアップはハッシュテーブルによるO(1)

## セキュリティ考慮事項

- locked状態では管理者でもマニフェストを変更できないため、ブート時に設定する必要がある
- SHA1は衝突攻撃が実証されているためSHA256以上の使用を推奨
- マニフェストファイル自体の完全性保護も重要
- nullfs経由の検証回避の防止

## 備考

- veriexecはNetBSD由来の概念をFreeBSD向けにMACフレームワーク上で再実装したもの
- Juniper Networks社の貢献により開発・保守されている（ソースヘッダのCopyright参照）
- mac_veriexec_internal.h内でnullfs統合のためのマクロが定義されている

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

veriexecのメタデータとラベル管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mac_veriexec.h | `sys/security/mac_veriexec/mac_veriexec.h` | veriexecの公開API定義 |
| 1-2 | mac_veriexec_internal.h | `sys/security/mac_veriexec/mac_veriexec_internal.h` | 内部データ構造。SLOTマクロの定義、nullfs統合 |

**読解のコツ**: SLOT(l)マクロ（mac_veriexec.c 65-66行目）はMACラベルスロットの取得・設定を行う。mac_label_get/mac_label_setでvnode単位のveriexec状態を管理する。

#### Step 2: MACポリシーモジュール実装を理解する

veriexecのMACフレームワーク統合を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mac_veriexec.c | `sys/security/mac_veriexec/mac_veriexec.c` | MACポリシーモジュール実装。SLOTマクロ（65-68行目）、デバッグマクロ（70-78行目）、sysctl_mac_veriexec_state関数（80行目） |

**主要処理フロー**:
1. **65-68行目**: SLOT/SLOT_SETマクロ定義。MACラベルスロット経由のveriexec状態管理
2. **70-78行目**: デバッグマクロ定義（MAC_VERIEXEC_DEBUG有効時）
3. **80行目**: sysctl_mac_veriexec_state()関数宣言。検証状態の取得

#### Step 3: フィンガープリント処理を理解する

各ハッシュアルゴリズムの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | veriexec_fingerprint.c | `sys/security/mac_veriexec/veriexec_fingerprint.c` | フィンガープリント計算共通処理 |
| 3-2 | mac_veriexec_sha256.c | `sys/security/mac_veriexec/mac_veriexec_sha256.c` | SHA256ハッシュ実装 |
| 3-3 | mac_veriexec_sha512.c | `sys/security/mac_veriexec/mac_veriexec_sha512.c` | SHA512ハッシュ実装 |

#### Step 4: ユーザ空間コマンドを理解する

veriexecコマンドのマニフェスト管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | veriexec.c | `sbin/veriexec/veriexec.c` | veriexecコマンドmain処理 |
| 4-2 | manifest_parser.y | `sbin/veriexec/manifest_parser.y` | マニフェストファイルの構文定義（yacc） |
| 4-3 | manifest_lexer.l | `sbin/veriexec/manifest_lexer.l` | マニフェストの字句解析（lex） |

### プログラム呼び出し階層図

```
veriexec（ユーザ空間コマンド）
    │
    ├─ veriexec.c: main()
    │      ├─ manifest_parser.y: マニフェスト解析
    │      │      └─ manifest_lexer.l: 字句解析
    │      └─ ioctl → カーネルメタデータ登録
    │
カーネル空間（MACフレームワーク上）:
    │
    ├─ mac_veriexec.c: MACポリシーモジュール
    │      ├─ vnode実行時フック
    │      │      ├─ veriexec_metadata.c: メタデータ検索
    │      │      └─ veriexec_fingerprint.c: ハッシュ計算
    │      │             ├─ mac_veriexec_sha256.c
    │      │             ├─ mac_veriexec_sha384.c
    │      │             ├─ mac_veriexec_sha512.c
    │      │             └─ mac_veriexec_sha1.c
    │      └─ sysctl: mac.veriexec.state
    │
    └─ nullfs統合: nullfsマウント経由の検証
```

### データフロー図

```
[入力]                    [処理]                         [出力]

マニフェストファイル ──▶ veriexec コマンド ───────▶ カーネルメタデータ
                        manifest_parser.y           テーブル
                        ioctl登録

ファイル実行要求 ────▶ MAC veriexec フック ──────▶ 実行許可/拒否
                      veriexec_fingerprint.c
                      ハッシュ計算・照合
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mac_veriexec.c | `sys/security/mac_veriexec/mac_veriexec.c` | ソース | MACポリシーモジュール |
| mac_veriexec.h | `sys/security/mac_veriexec/mac_veriexec.h` | ヘッダ | 公開API定義 |
| mac_veriexec_internal.h | `sys/security/mac_veriexec/mac_veriexec_internal.h` | ヘッダ | 内部データ構造 |
| veriexec_fingerprint.c | `sys/security/mac_veriexec/veriexec_fingerprint.c` | ソース | フィンガープリント計算 |
| veriexec_metadata.c | `sys/security/mac_veriexec/veriexec_metadata.c` | ソース | メタデータ管理 |
| mac_veriexec_sha1.c | `sys/security/mac_veriexec/mac_veriexec_sha1.c` | ソース | SHA1ハッシュ |
| mac_veriexec_sha256.c | `sys/security/mac_veriexec/mac_veriexec_sha256.c` | ソース | SHA256ハッシュ |
| mac_veriexec_sha384.c | `sys/security/mac_veriexec/mac_veriexec_sha384.c` | ソース | SHA384ハッシュ |
| mac_veriexec_sha512.c | `sys/security/mac_veriexec/mac_veriexec_sha512.c` | ソース | SHA512ハッシュ |
| veriexec.c | `sbin/veriexec/veriexec.c` | ソース | veriexecコマンド |
| veriexec.h | `sbin/veriexec/veriexec.h` | ヘッダ | コマンドヘッダ |
| manifest_parser.y | `sbin/veriexec/manifest_parser.y` | ソース | マニフェストパーサー |
| manifest_lexer.l | `sbin/veriexec/manifest_lexer.l` | ソース | マニフェスト字句解析 |
| veriexec.8 | `sbin/veriexec/veriexec.8` | マニュアル | veriexecコマンドのmanページ |
