Commit Fest:May

かねてより提案していた SE-PostgreSQL のパッチに関して、Commit Fest:May の開始に伴い、開発チームリーダの1人である Tom Lane から物凄い勢いでレビューが返ってきた。
http://wiki.postgresql.org/wiki/CommitFest:May
http://archives.postgresql.org/message-id/3275.1210019965@sss.pgh.pa.us

それに合わせて、かなり大掛かりにコードをいじっている。
主なものでも
・PGACEのフックを static inline に変更
・initdb時に pg_security の代用ファイルを使わないように修正(On Memoryにキャッシュ)
・TRUNCATE→無条件DELETEへの書き換えをやめる(トリガ関数非互換)
・EXECUTEパラメータリストへのチェックを追加
・oidシステム列も書き込み可能にした
・WHERE句への条件追加をやめ、テーブルのスキャン中にフックを呼ぶようにした
セキュリティポリシーを修正

それに加えて、パッチを投稿するためには、少なくとも regression test をパスしないといけないらしい。
最初に投稿した際のバージョンだと、大小様々に30個程度が FAIL になっていたようだ(死)が、上記のような改善を加えることで、現バージョンでは3個にまで減らすことができた。
このうち2個は機能追加に伴う真っ当なもので、あと1個は security_label 型の演算子の実装が必要であるためのもの。

[kaigai@masu sepgsql]$ make check
    :
〜(略)〜
    :
========================
 3 of 115 tests failed.
========================
security_label型に配列としての利用を許すオペレータが必要
*** ./expected/type_sanity.out  Mon Apr 21 13:14:24 2008
--- ./results/type_sanity.out   Thu May 15 22:35:00 2008
***************
*** 65,74 ****
       WHERE p2.typname = ('_' || p1.typname)::name AND
             p2.typelem = p1.oid and p1.typarray = p2.oid);
   oid | typname
! -----+---------
   210 | smgr
   705 | unknown
! (2 rows)

  -- Make sure typarray points to a varlena array type of our own base
  SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype,
--- 65,75 ----
       WHERE p2.typname = ('_' || p1.typname)::name AND
             p2.typelem = p1.oid and p1.typarray = p2.oid);
   oid  |    typname
! ------+----------------
    210 | smgr
    705 | unknown
!  3403 | security_label
! (3 rows)

  -- Make sure typarray points to a varlena array type of our own base
  SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype,

PostgreSQL本体のチェックより先に、SE-PostgreSQLがエラーを検出している

*** ./expected/create_function_1.out    Thu May 15 22:34:44 2008
--- ./results/create_function_1.out Thu May 15 22:35:01 2008
***************
*** 72,78 ****
  ERROR:  only one AS item needed for language "sql"
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
      AS 'nosuchfile';
! ERROR:  could not access file "nosuchfile": No such file or directory
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
      AS '(略)/regress.so', 'nosuchsymbol';
  ERROR:  could not find function "nosuchsymbol" in file "(略)regress.so"
--- 72,78 ----
  ERROR:  only one AS item needed for language "sql"
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
      AS 'nosuchfile';
! ERROR:  SELinux: could not obtain security context of nosuchfile
  CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
      AS '(略)/regress.so', 'nosuchsymbol';
  ERROR:  could not find function "nosuchsymbol" in file "(略)regress.so"

新しいシステムカタログpg_securityが追加されたので

*** ./expected/sanity_check.out Sun Nov 25 12:55:19 2007
--- ./results/sanity_check.out  Thu May 15 22:35:06 2008
***************
*** 111,116 ****
--- 111,117 ----
   pg_pltemplate           | t
   pg_proc                 | t
   pg_rewrite              | t
+  pg_security             | t
   pg_shdepend             | t
   pg_shdescription        | t
   pg_statistic            | t
***************
*** 149,155 ****
   timetz_tbl              | f
   tinterval_tbl           | f
   varchar_tbl             | f
! (138 rows)

  --
  -- another sanity check: every system catalog that has OIDs should have
--- 150,156 ----
   timetz_tbl              | f
   tinterval_tbl           | f
   varchar_tbl             | f
! (139 rows)

  --
  -- another sanity check: every system catalog that has OIDs should have

しかしこの regression test、作業ディレクトリの下に代替のルートディレクトリを作ってそこに PostgreSQL をインストールするという作りになっているので、正しいセキュリティコンテキストが付かずに難儀する。
仕方ないので、sepgsql_regression_test_mode という boolean を追加して、regression test に必要なパーミッションを与えるようにした。
user_home_tの共有ライブラリをロードできたりするので、通常運用では絶対に on にしてはならないが、まぁ、これはこれでアリだろう。