デバイス オブジェクトに対するセキュリティ記述子の摘要
ほとんどのドライバーは、不適切なアクセスから自身を保護するために、I/O マネージャーがデバイス オブジェクトに適用するアクセス制御を使用します。 ほとんどのドライバーにとって最も簡単な手法は、ドライバーのインストール時に明示的なセキュリティ記述子を適用することです。 INF ファイルでは、このようなセキュリティ記述子は、AddReg セクションの "Security" エントリによって記述されます。 セキュリティ記述子の記述に使用される完全な言語の詳細については、Microsoft Windows SDK ドキュメントの「セキュリティ記述子定義言語」を参照してください。
セキュリティ記述子定義言語 (SDDL) を使用したセキュリティ記述子の基本形式には、標準セキュリティ記述子の次の部分が含まれています。
所有者 SID。
グループ SID。
随意アクセス制御リスト (DACL)。
システム アクセス制御リスト (SACL)。
したがって、セキュリティ記述子の INF スクリプト内の記述は次のとおりです。
O:owner-sidG:group-sidD:dacl-flags(ace)(ace)S:sacl-flags(ace)(ace)
個々のアクセス制御エントリは、セキュリティ識別子または SID で指定された特定のグループまたはユーザーに対して許可または拒否されるアクセス権を記述します。 たとえば、INF ファイルには次のような行が含まれている場合があります。
"D:P(A;CI;GR;;;BU)(A;CI;GR;;;PU)(A;CI;GA;;;BA)(A;CI;GA;;;SY)(A;CI;GA;;;NS)(A;CI;GA;;;LS)(A;CI;CCDCLCSWRPSDRC;;;S-1-5-32-556)"
上記の例は Microsoft Windows XP Service Pack 1 (SP1) システムの NETTCPIP.INF ファイルのものです。
この例では、所有者またはグループが指定されていないため、既定では定義済みの値または既定値になります。 D は、これが DACL であることを示します。 P は、これが保護された ACL であり、含んでいるオブジェクトのセキュリティ記述子から権限を継承しないことを示します。 保護された ACL は、親のより緩いセキュリティが継承されないようにします。 かっこで囲まれた式が 1 つのアクセス制御エントリ (ACE) を示します。 SDDL を使用するアクセス制御エントリは、セミコロンで区切られた複数の個別コンポーネントで構成されます。 これらのセクションを順番に示します。
ACE の型インジケーター。 DACL には 4 つの固有の型があり、SACL には 4 種類の型があります。
子オブジェクトのこの ACE の継承、または SACL の監査およびアラーム ポリシーを記述するために使用される flags フィールド。
rights フィールドは、ACE によって付与または拒否される権限を示します。 このフィールドでは、この ACE に適用できる汎用権限、標準権限、および特定の権限を示す特定の数値を指定したり、一般的なアクセス権の説明文字列を使用したりすることができます。
DACL がオブジェクト固有の ACE 構造体である場合のオブジェクト GUID。
DACL がオブジェクト固有の ACE 構造体の場合の継承オブジェクト GUID
この ACE の適用先のセキュリティ エンティティを示す SID。
したがって、サンプルのセキュリティ記述子を解釈すると、ACE の先頭にある "A" は、これが "アクセスを許可された" エントリであることを示します。 "アクセスを拒否された" エントリもあります。これは使用頻度の低いエントリで、先頭の "D" 文字で示されます。 flags フィールドでは、この ACE がサブオブジェクトによって継承されることを示すコンテナー継承 (CI) を指定します。
rights フィールドの値は、汎用権限と標準権限を含む特定の権限をエンコードします。 たとえば、"GR" は "汎用読み取り" アクセス権を示し、"GA" は "すべての汎用" アクセス権を示します。どちらも汎用権限です。 多くの特別な権限がこれらの汎用権限に従います。 上記のサンプルでは、"CC" は、ファイルとディレクトリの権限に固有の子の作成アクセス権を示しています。 上記のサンプルには、"CC" 文字列の後に、子の削除アクセス権を表す "DC"、子の一覧表示アクセス権を表す "LC"、自己権限アクセス権を表す "SW"、プロパティの読み取りアクセス権を表す "RP"、標準削除アクセス権を表す "SD"、読み取り制御アクセス権を表す "RC" など、その他の標準権限も含まれています。
上記のサンプルの SID エントリ文字列には、パワー ユーザーを表す "PU"、組み込みユーザーを表す "BU"、組み込み管理者を表す "BA"、ローカル サービス アカウントを表す "LS"、ローカル システムを表す "SY"、ネットワーク サービス アカウントを表す "NS" が含まれます。 そのため、上記の例では、ユーザーにはオブジェクトに対する汎用読み取りアクセス権が付与されます。 一方、組み込みの管理者、ローカル サービス アカウント、ローカル システム、ネットワーク サービスには、すべての汎用アクセス権 (読み取り、書き込み、実行) が付与されます。 すべての可能な権限と標準 SID 文字列の完全なセットは、Windows SDK で文書化されています。
これらの ACL は、特定のドライバーによって作成されたすべてのデバイス オブジェクトに適用されます。 ドライバーは、名前付きデバイス オブジェクトを作成する際に、新しい関数 IoCreateDeviceSecure を使用して、特定のオブジェクトのセキュリティ設定を制御することもできます。 IoCreateDeviceSecure 関数は、Windows XP Service Pack 1 および Windows Server 2003 以降で使用できます。 IoCreateDeviceSecure を使用すると、デバイス オブジェクトに適用されるセキュリティ記述子は、デバイス オブジェクトに適した完全なセキュリティ記述子定義言語のサブセットを使用して記述されます。
特定のセキュリティ記述子をデバイス オブジェクトに適用する目的は、アプリケーションがデバイス自体にアクセスしようとするたびに、デバイスに対して適切なセキュリティ チェックが実行されるようにすることです。 名前の構造体を含むデバイス オブジェクトの場合 (ファイル システムの名前空間など)、このデバイス名前空間へのアクセスの管理の詳細は、I/O マネージャーではなくドライバーに属します。
このような場合の興味深い問題は、ドライバー デバイス オブジェクトへのアクセスのチェックを担当する I/O マネージャーと、ドライバーに適したセキュリティ ポリシーを実装するデバイス ドライバーの間の境界でセキュリティを処理する方法です。 従来、開いているオブジェクトがデバイス自体の名前である場合、I/O マネージャーは、そのセキュリティ記述子を使用して、デバイス オブジェクトに対してフル アクセス チェックを直接実行します。 一方、開いているオブジェクトがドライバー自体内のパスを示している場合、I/O マネージャーは、デバイス オブジェクトへの走査アクセス権が確実に付与されるようにするためにのみチェックします。 通常、この走査権限が付与されるのは、ほとんどのスレッドに SeChangeNotifyPrivilege が付与されているからです。これは、ディレクトリへの走査権限の付与に対応します。 名前の構造体をサポートしていないデバイスは、通常、I/O マネージャーにフル セキュリティ チェックの実行を要求します。 これを行うには、デバイス特性フィールドに FILE_DEVICE_SECURE_OPEN ビットを設定します。 このようなデバイス オブジェクトの組み合わせを含むドライバーは、名前の構造体をサポートしていないデバイスに対してこの特性を設定する必要があります。 たとえば、ファイル システムでは、(名前付け構造をサポートしない) 名前付きデバイス オブジェクトにこのオプションを設定しますが、名前付け構造をサポートする名前のないデバイス オブジェクト (ボリュームなど) ではこのオプションを設定しません。 このビットを正しく設定できないのはドライバーによくあるバグであり、これによってデバイスへの不適切なアクセスが許可される可能性があります。 アタッチメント インターフェイス (IoAttachDeviceToDeviceStackSafe など) を使用するドライバーの場合、ドライバーがアタッチするデバイスでこのフィールドが設定されていれば、FILE_DEVICE_SECURE_OPEN ビットが設定されます。 そのため、フィルター ドライバーは、セキュリティ チェックのこの特定の側面について心配する必要はありません。