UPDATE構文のセキュリティモデル

今日は、SQLのUPDATE構文実行時に強制アクセス制御を実行するためのコードを実装した。

UPDATE構文の実行時には、以下のパーミッションがチェックされる。


  • UPDATEを行うテーブルに対する table:update 権限

  • UPDATEを行うカラムに対する column:update 権限

  • UPDATEを行うタプルに対する tuple:update 権限

  • UPDATE条件句でカラムが指定されていた場合、カラムに対する column:select 権限と、そのカラムが属するテーブルに対する table:select 権限

  • UPDATE条件句で関数を使用する場合、関数に対する procedure:execute 権限

  • さらにこの関数がドメイン遷移を引き起こす場合、procedure:entrypoint 権限

  • UPDATEはセキュリティコンテキスト行を更新しようとする場合、tuple:{relabelfrom relabelto}権限


UPDATE構文は最も単純なDDL命令の一つなので、これで網羅できてしまう。モデル的にはこれでOKだと思う。

但し、例外があり、pg_database, pg_class, pg_attribute, pg_proc, pg_largeobject の各テーブルを更新する場合には特別な操作が必要になる。なぜなら、これらのテーブルはシステムカタログと呼ばれる特殊なテーブルで、例えば pg_class はテーブルのメタデータを保持しており、pg_proc は関数のメタデータを保持している。

このため、SE-PgSQLはこれらのテーブルへのアクセスをメタ情報の参照として扱い、一般のテーブルとは異なった権限を必要とするように設計してある。

例えば、pg_classテーブルへの SELECT 操作は、pg_classテーブルへの table:select 権限のほかに、pg_classテーブルの各タプルによって表現されているテーブルへのメタ情報の参照、即ち table:getattr 権限を必要とする。

同様に、pg_classテーブルへの UPDATE 操作は table:setattr で、DELETE 操作は table:drop と等価となる。通常、これらのシステムカタログは CREATE TABLE 文によって自動的に生成されるため、ユーザは意識しないが、UPDATE文などのDDL構文によってもアクセスが可能であるため、このような扱いが必要になる。



あと、PostgreSQLでちょっと面倒なのがテーブルの継承の扱いだけれども、、、これは後の宿題にしておくか。