# 機能設計書 44-MAC（Mandatory Access Control）

## 概要

本ドキュメントは、FreeBSDのMAC（Mandatory Access Control）フレームワークおよび各ポリシーモジュールの機能設計について記述する。MACフレームワークはカーネル内の拡張可能なアクセス制御基盤であり、TrustedBSDプロジェクトの成果として開発された。

### 本機能の処理概要

MACフレームワークはカーネル全体に分散するセキュリティ判断ポイントにおいて、プラグイン可能なポリシーモジュールを通じて強制アクセス制御を実現する。

**業務上の目的・背景**：従来のUNIX DAC（Discretionary Access Control）では不十分な高セキュリティ環境において、強制アクセス制御により情報フローの制御やプロセス間の隔離を実現する。軍事・政府系システムや、マルチテナント環境でのセキュリティ強化に利用される。

**機能の利用シーン**：Biba完全性モデルによるシステム整合性保護、MLS（Multi-Level Security）による機密レベル別情報アクセス制御、プロセスパーティショニングによるプロセス可視性制限、ポートACLによるネットワークポートのバインド制御、seeotheruidsによるプロセス一覧の可視性制限、bsdextendedによるファイルアクセス制御の拡張に使用される。

**主要な処理内容**：
1. ポリシーモジュールの登録・アンロード（mac_policy_register/mac_policy_unregister）
2. オブジェクトラベルの初期化・設定・破棄
3. カーネル各所でのセキュリティチェックの実行（mac_check_*系関数）
4. セキュリティイベントの通知（mac_create_*, mac_relabel_*等）
5. ユーザ空間からのラベル照会・設定（mac_get_*/mac_set_*システムコール）
6. 複数ポリシーの合成（エラー合成演算子による結果統合）

**関連システム・外部連携**：ファイルシステム（VFS層）、プロセス管理、ネットワークスタック、IPC機構、デバイスドライバ等、カーネルのほぼ全域にフックポイントが設置されている。

**権限による制御**：MACラベルの設定変更にはroot権限またはポリシーモジュールが定義する特定の権限が必要。各ポリシーモジュールは独自のアクセス制御ロジックを実装する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | セキュリティ強化設定画面 | 主機能 | プロセス隠蔽・PIDランダム化等のsysctlセキュリティパラメータ設定 |

## 機能種別

アクセス制御 / セキュリティポリシー適用 / ラベル管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| policy_module | string | Yes（登録時） | ポリシーモジュール名 | 有効なモジュール名 |
| label | mac_label | No | セキュリティラベル | ポリシーモジュール定義に準拠 |
| subject | struct ucred | Yes（チェック時） | 操作主体の資格情報 | 有効なucred構造体 |
| object | 各種 | Yes（チェック時） | 操作対象（vnode, socket, pipe等） | 有効なオブジェクト参照 |

### 入力データソース

- カーネル内部のセキュリティフックポイント
- mac_get_*/mac_set_*システムコール
- ポリシーモジュール固有のsysctlパラメータ
- loader.conf / rc.confによるモジュールロード設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| access_decision | int | アクセス許可（0）/ 拒否（エラーコード） |
| label_data | mac_label | オブジェクトに付与されたラベル情報 |
| policy_status | text | ポリシーモジュールの状態情報 |

### 出力先

- カーネル内部（アクセス判断結果のリターン値）
- ユーザ空間（システムコール経由のラベル情報）
- sysctl経由のポリシーパラメータ

## 処理フロー

### 処理シーケンス

```
1. ポリシーモジュールのロード（boot時またはkldload）
   └─ mac_policy_register()でフレームワークにモジュールを登録
2. オブジェクト作成時のラベル初期化
   └─ mac_create_*()でポリシーモジュールにラベル初期化を委譲
3. アクセスチェック（カーネル各所）
   └─ mac_check_*()で全登録ポリシーモジュールに問い合わせ
4. エラー合成
   └─ 複数ポリシーの結果を合成演算子で統合
5. アクセス許可/拒否の決定
   └─ いずれかのポリシーが拒否すれば全体として拒否
```

### フローチャート

```mermaid
flowchart TD
    A[カーネル操作要求] --> B[MACフックポイント]
    B --> C[mac_check_*呼び出し]
    C --> D[ポリシーモジュール1に問い合わせ]
    C --> E[ポリシーモジュール2に問い合わせ]
    C --> F[ポリシーモジュールNに問い合わせ]
    D --> G{エラー合成}
    E --> G
    F --> G
    G -->|全ポリシー許可| H[操作許可]
    G -->|いずれか拒否| I[操作拒否]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | 強制アクセス制御 | DACで許可された操作でもMACポリシーにより拒否可能 | 常時 |
| BR-44-02 | 複数ポリシー合成 | 複数ポリシーのいずれかが拒否すれば全体として拒否（最も制限的な結果を採用） | 複数ポリシー同時利用時 |
| BR-44-03 | ラベル継承 | 新規オブジェクトは作成元のラベルを継承（ポリシー依存） | オブジェクト作成時 |
| BR-44-04 | 特権バイパス | 一部ポリシーではroot権限でもアクセス制御をバイパスできない | ポリシー設計による |

### 計算ロジック

- エラー合成演算子：複数ポリシーの結果を合成する際、最も制限的なエラーコードを返す
- Bibaモデル：完全性レベルの比較による読み出し/書き込みの許可判断
- MLSモデル：機密レベルとコンパートメントの包含関係による判断

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

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

本機能はデータベースを使用しない。カーネル内のポリシーモジュールリストとオブジェクトラベルを操作する。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| register | mac_policy_list | INSERT | ポリシーモジュール登録 |
| unregister | mac_policy_list | DELETE | ポリシーモジュール解除 |
| check | mac_label | SELECT | ラベル照合・アクセス判断 |
| set_label | mac_label | UPDATE | ラベル設定変更 |

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

#### mac_policy_list（ポリシーモジュールリスト）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| INSERT | mpc_ops, mpc_name, mpc_loadtime_flags | モジュールロード時 | rmlockで保護 |
| DELETE | モジュール名指定 | モジュールアンロード時 | 動的アンロード可能かはフラグ依存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EACCES | アクセス拒否 | MACポリシーによるアクセス拒否 | ラベルまたはポリシー設定を見直す |
| ENOMEM | メモリ不足 | ラベル割り当て失敗 | システムリソースを確保 |
| EINVAL | 無効なラベル | 不正なラベル文字列の指定 | 正しいラベル形式を指定 |
| EPERM | 権限不足 | ラベル変更権限の不足 | 適切な権限で操作 |

### リトライ仕様

MACの判断は即座に行われ、リトライ機構は不要。ポリシーモジュールの登録失敗時はエラーを返す。

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

ポリシーモジュールの登録・解除はrmlockで保護された原子的操作。ラベルの設定変更は個別のオブジェクトに対して行われ、トランザクション的な一括変更はサポートしない。

## パフォーマンス要件

- MACフックの呼び出しはカーネル内のクリティカルパス上にあるため低オーバーヘッドが要求される
- rmlockによる読み取り側のスケーラビリティ確保
- ポリシーモジュール未登録時のオーバーヘッドは最小（早期リターン）

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

- MACフレームワーク自体のバグはシステム全体のセキュリティに直結する
- ポリシーモジュールの品質がシステムセキュリティの鍵
- Bibaモデルの完全性レベル設定の不備はシステム保護の穴となる
- MLSモデルの機密レベル設定の不備は情報漏洩リスクとなる
- root権限でもMACによりアクセスが拒否される場合がある点に注意

## 備考

- TrustedBSDプロジェクトの成果としてFreeBSDに統合
- MACフレームワークはmacOSのセキュリティフレームワークの基盤にもなった
- 主要ポリシーモジュール：mac_biba（Biba完全性）、mac_mls（多レベルセキュリティ）、mac_bsdextended（ファイルACL拡張）、mac_partition（プロセス分離）、mac_seeotheruids（UID可視性制御）、mac_portacl（ポートACL）、mac_ifoff（インタフェース制御）、mac_lomac（Low-Watermark MAC）

---

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

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

### 推奨読解順序

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

MACフレームワークの核心的データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mac_policy.h | `sys/security/mac/mac_policy.h` | mac_policy_ops構造体でポリシーモジュールが実装すべきエントリポイント群を理解する。mac_policy_conf構造体でモジュール登録情報を把握する |
| 1-2 | mac_framework.h | `sys/security/mac/mac_framework.h` | カーネルから呼び出されるMACフック関数のプロトタイプを理解する |

**読解のコツ**: mac_policy_opsの各関数ポインタはカーネルのセキュリティフックポイントに対応する。名前規則はmpo_{check|create|destroy|relabel}_{object_type}_{operation}。

#### Step 2: フレームワーク中核を理解する

MACフレームワークの実装中核部を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mac_framework.c | `sys/security/mac/mac_framework.c` | フレームワークの3つのプログラミングインタフェース（45-67行目のコメント）を理解する。ポリシー登録、バージョニング、エラー合成演算子の実装 |

**主要処理フロー**:
1. **45-67行目**: MACフレームワークの3つのインタフェースの説明コメント
   - カーネルMACインタフェース（mac_framework.h）
   - MACポリシーモジュールインタフェース（mac_policy.h）
   - ユーザMAC API（mac.h）

#### Step 3: 各セキュリティドメインのフック実装を理解する

MACフレームワークがカーネルの各サブシステムとどう統合されているかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mac_vfs.c | `sys/security/mac/mac_vfs.c` | VFS層（ファイルシステム）のMACフック実装 |
| 3-2 | mac_process.c | `sys/security/mac/mac_process.c` | プロセス関連のMACフック実装 |
| 3-3 | mac_socket.c | `sys/security/mac/mac_socket.c` | ソケット関連のMACフック実装 |
| 3-4 | mac_net.c | `sys/security/mac/mac_net.c` | ネットワーク関連のMACフック実装 |

#### Step 4: 代表的なポリシーモジュールを理解する

具体的なポリシーモジュールの実装パターンを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mac_biba.c | `sys/security/mac_biba/mac_biba.c` | Biba完全性モデルの実装。ラベルの比較ロジックとアクセス判断の実装パターン |
| 4-2 | mac_seeotheruids.c | `sys/security/mac_seeotheruids/mac_seeotheruids.c` | シンプルなポリシーモジュールの実装例。他ユーザのプロセス可視性を制限 |
| 4-3 | mac_portacl.c | `sys/security/mac_portacl/mac_portacl.c` | ポートバインドの制御を行うポリシー実装 |

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

```
カーネル操作（VFS, プロセス, ネットワーク等）
    │
    ├─ mac_framework.h: mac_check_*()
    │      │
    │      ├─ mac_framework.c: ポリシーリスト走査
    │      │      ├─ ポリシーモジュール1: mpo_check_*()
    │      │      ├─ ポリシーモジュール2: mpo_check_*()
    │      │      └─ エラー合成演算子
    │      │
    │      └─ 結果返却（許可/拒否）
    │
ポリシーモジュール例:
    ├─ mac_biba/mac_biba.c - Biba完全性モデル
    ├─ mac_mls/mac_mls.c - 多レベルセキュリティ
    ├─ mac_bsdextended/mac_bsdextended.c - ファイルACL拡張
    ├─ mac_partition/mac_partition.c - プロセス分離
    ├─ mac_seeotheruids/mac_seeotheruids.c - UID可視性制御
    ├─ mac_portacl/mac_portacl.c - ポートACL
    ├─ mac_ifoff/mac_ifoff.c - インタフェース制御
    └─ mac_lomac/mac_lomac.c - Low-Watermark MAC
```

### データフロー図

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

カーネル操作要求 ──▶ MACフックポイント ──────▶ アクセス許可/拒否
(VFS/Process/Net)    mac_check_*()
                     ポリシーモジュール走査
                     エラー合成

mac_set_*() ────▶ フレームワーク ──────────▶ オブジェクトラベル更新
(システムコール)    ポリシーモジュール通知

loader.conf ────▶ mac_policy_register() ─▶ ポリシーモジュール登録
(モジュールロード)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mac_framework.c | `sys/security/mac/mac_framework.c` | ソース | MACフレームワーク中核 |
| mac_framework.h | `sys/security/mac/mac_framework.h` | ヘッダ | カーネルMAC API定義 |
| mac_policy.h | `sys/security/mac/mac_policy.h` | ヘッダ | ポリシーモジュールインタフェース |
| mac_vfs.c | `sys/security/mac/mac_vfs.c` | ソース | VFS層MACフック |
| mac_process.c | `sys/security/mac/mac_process.c` | ソース | プロセス関連MACフック |
| mac_socket.c | `sys/security/mac/mac_socket.c` | ソース | ソケット関連MACフック |
| mac_net.c | `sys/security/mac/mac_net.c` | ソース | ネットワーク関連MACフック |
| mac_biba.c | `sys/security/mac_biba/mac_biba.c` | ソース | Biba完全性ポリシー |
| mac_mls.c | `sys/security/mac_mls/mac_mls.c` | ソース | 多レベルセキュリティポリシー |
| mac_bsdextended.c | `sys/security/mac_bsdextended/mac_bsdextended.c` | ソース | ファイルACL拡張ポリシー |
| mac_partition.c | `sys/security/mac_partition/mac_partition.c` | ソース | プロセス分離ポリシー |
| mac_seeotheruids.c | `sys/security/mac_seeotheruids/mac_seeotheruids.c` | ソース | UID可視性制御ポリシー |
| mac_portacl.c | `sys/security/mac_portacl/mac_portacl.c` | ソース | ポートACLポリシー |
| mac_ifoff.c | `sys/security/mac_ifoff/mac_ifoff.c` | ソース | インタフェース制御ポリシー |
| mac_lomac.c | `sys/security/mac_lomac/mac_lomac.c` | ソース | Low-Watermark MACポリシー |
| mac_none.c | `sys/security/mac_none/mac_none.c` | ソース | 無操作ポリシー（テンプレート） |
| mac_stub.c | `sys/security/mac_stub/mac_stub.c` | ソース | スタブポリシー（テンプレート） |
| mac_ddb.c | `sys/security/mac_ddb/mac_ddb.c` | ソース | DDBデバッガ用ポリシー |
| mac_do.c | `sys/security/mac_do/mac_do.c` | ソース | 権限委譲ポリシー |
| mac_ipacl.c | `sys/security/mac_ipacl/mac_ipacl.c` | ソース | IP ACLポリシー |
| mac_ntpd.c | `sys/security/mac_ntpd/mac_ntpd.c` | ソース | ntpd用ポリシー |
| mac_pimd.c | `sys/security/mac_pimd/mac_pimd.c` | ソース | pimd用ポリシー |
| mac_priority.c | `sys/security/mac_priority/mac_priority.c` | ソース | 優先度制御ポリシー |
