[0/4] Proposal of SE-PostgreSQL patches

Started by Kohei KaiGaialmost 18 years ago65 messages
#1Kohei KaiGai
kaigai@ak.jp.nec.com

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

[1/4] sepostgresql-pgace-8.4devel-3.patch
provides PGACE (PostgreSQL Access Control Extension) framework
[2/4] sepostgresql-sepgsql-8.4devel-3.patch
provides SE-PostgreSQL feature, based on PGACE framework.
[3/4] sepostgresql-pg_dump-8.4devel-3.patch
enables pg_dump to dump database with security attribute.
[4/4] sepostgresql-policy-8.4devel-3.patch
provides the default security policy for SE-PostgreSQL.

We can provide a quick overview of SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

Any comment and suggestion are welcome.
Thanks,

ENVIRONMENT
-----------
Please confirm your environment.
The followings are requriements of SE-PostgreSQL.
* Fedora 8 or later system
* SELinux is enabled and working
* kernel-2.6.24 or later
* selinux-policy and selinux-policy-devel v3.0.8 or later
* libselinux, policycoreutils

INSTALLATION
------------
$ tar jxvf postgresql-snapshot.tar.bz2
$ cd postgresql-snapshot
$ patch -p1 < ../sepostgresql-pgace-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-sepgsql-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-pg_dump-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-policy-8.4devel-3.patch

$ ./configure --enable-selinux
$ make
$ make -C contrib/sepgsql-policy
$ su
# make install

# /usr/sbin/semodule -i contrib/sepgsql-policy/sepostgresql.pp
(NOTE: semodule is a utility to load/unload security policy modules.)

# /sbin/restorecon -R /usr/local/pgsql
(NOTE: restorecon is a utilicy to initialize security context of files.)

SETUP
-----
# mkdir -p /opt/sepgsql
# chown foo_user:var_group /opt/sepgsql
# chcon -t postgresql_db_t /opt/sepgsql
(NOTE: chcon is a utility to set up security context of files.)
# exit

$ /usr/sbin/run_init /usr/local/pgsql/bin/initdb -D /opt/sepgsql
(NOTE: run_init is a utility to start a program, as if it is branched from init script.)
$ /usr/local/pgsql/bin/pg_ctl -D /opt/sepgsql start

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#2Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Kohei KaiGai (#1)
1 attachment(s)
[3/4] Proposal of SE-PostgreSQL patches

[3/4] - sepostgresql-pg_dump-8.4devel-3.patch

This patch gives us a feature to dump database with security attribute.
It is turned on with '--enable-selinux' option at pg_dump/pg_dumpall,
when the server works as SE- version.
No need to say, users need to have enough capabilities to dump whole of
database. It it same when they tries to restore the database.

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

Attachments:

sepostgresql-pg_dump-8.4devel-3.patchtext/x-patch; name=sepostgresql-pg_dump-8.4devel-3.patchDownload
diff -rpNU3 pgace/src/bin/pg_dump/pg_dump.c sepgsql/src/bin/pg_dump/pg_dump.c
--- pgace/src/bin/pg_dump/pg_dump.c	2008-02-03 01:18:48.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dump.c	2008-02-03 01:26:35.000000000 +0900
@@ -118,6 +118,9 @@ static int	g_numNamespaces;
 /* flag to turn on/off dollar quoting */
 static int	disable_dollar_quoting = 0;
 
+/* flag to tuen on/off SE-PostgreSQL support */
+#define SELINUX_SYSATTR_NAME	"security_context"
+static int enable_selinux = 0;
 
 static void help(const char *progname);
 static void expand_schema_name_patterns(SimpleStringList *patterns,
@@ -267,6 +270,7 @@ main(int argc, char **argv)
 		{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
 		{"disable-triggers", no_argument, &disable_triggers, 1},
 		{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+		{"enable-selinux", no_argument, &enable_selinux, 1},
 
 		{NULL, 0, NULL, 0}
 	};
@@ -419,6 +423,8 @@ main(int argc, char **argv)
 					disable_triggers = 1;
 				else if (strcmp(optarg, "use-set-session-authorization") == 0)
 					use_setsessauth = 1;
+				else if (strcmp(optarg, "enable-selinux") == 0)
+					enable_selinux = 1;
 				else
 				{
 					fprintf(stderr,
@@ -549,6 +555,24 @@ main(int argc, char **argv)
 	std_strings = PQparameterStatus(g_conn, "standard_conforming_strings");
 	g_fout->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
 
+	if (enable_selinux) {
+		/* confirm whther server support SELinux features */
+		const char *tmp = PQparameterStatus(g_conn, "security_sysattr_name");
+
+		if (!tmp) {
+			write_msg(NULL, "could not get security_sysattr_name from libpq\n");
+			exit(1);
+		}
+		if (!!strcmp(SELINUX_SYSATTR_NAME, tmp) != 0) {
+			write_msg(NULL, "server does not have SELinux feature\n");
+			exit(1);
+		}
+		if (g_fout->remoteVersion < 80204) {
+			write_msg(NULL, "server version is too old (%u)\n", g_fout->remoteVersion);
+			exit(1);
+		}
+	}
+
 	/* Set the datestyle to ISO to ensure the dump's portability */
 	do_sql_command(g_conn, "SET DATESTYLE = ISO");
 
@@ -771,6 +795,7 @@ help(const char *progname)
 	printf(_("  --use-set-session-authorization\n"
 			 "                              use SESSION AUTHORIZATION commands instead of\n"
 	"                              ALTER OWNER commands to set ownership\n"));
+	printf(_("  --enable-selinux            enable to dump security context in SE-PostgreSQL\n"));
 
 	printf(_("\nConnection options:\n"));
 	printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
@@ -1160,7 +1185,8 @@ dumpTableData_insert(Archive *fout, void
 	if (fout->remoteVersion >= 70100)
 	{
 		appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
-						  "SELECT * FROM ONLY %s",
+						  "SELECT * %s FROM ONLY %s",
+						  (!enable_selinux ? "" : "," SELINUX_SYSATTR_NAME),
 						  fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
 										 classname));
 	}
@@ -1774,11 +1800,32 @@ dumpBlobComments(Archive *AH, void *arg)
 			Oid			blobOid;
 			char	   *comment;
 
+			blobOid = atooid(PQgetvalue(res, i, 0));
+
+			/* dump security context of binary large object */
+			if (enable_selinux) {
+				PGresult	*__res;
+				char		query[512];
+
+				snprintf(query, sizeof(query),
+						 "SELECT lo_get_security(%u)", blobOid);
+				__res = PQexec(g_conn, query);
+				check_sql_result(__res, g_conn, query, PGRES_TUPLES_OK);
+
+				if (PQntuples(__res) != 1) {
+					write_msg(NULL, "lo_get_security(%u) returns %d tuples\n",
+							  blobOid, PQntuples(__res));
+					exit_nicely();
+				}
+				archprintf(AH, "SELECT lo_set_security(%u, '%s');\n",
+						   blobOid, PQgetvalue(__res, 0, 0));
+				PQclear(__res);
+			}
+
 			/* ignore blobs without comments */
 			if (PQgetisnull(res, i, 1))
 				continue;
 
-			blobOid = atooid(PQgetvalue(res, i, 0));
 			comment = PQgetvalue(res, i, 1);
 
 			printfPQExpBuffer(commentcmd, "COMMENT ON LARGE OBJECT %u IS ",
@@ -2886,6 +2933,7 @@ getTables(int *numTables)
 	int			i_owning_col;
 	int			i_reltablespace;
 	int			i_reloptions;
+	int			i_selinux;
 
 	/* Make sure we are in proper schema */
 	selectSourceSchema("pg_catalog");
@@ -2926,6 +2974,7 @@ getTables(int *numTables)
 						  "d.refobjsubid as owning_col, "
 						  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
 						  "array_to_string(c.reloptions, ', ') as reloptions "
+						  "%s "
 						  "from pg_class c "
 						  "left join pg_depend d on "
 						  "(c.relkind = '%c' and "
@@ -2935,6 +2984,7 @@ getTables(int *numTables)
 						  "where relkind in ('%c', '%c', '%c', '%c') "
 						  "order by c.oid",
 						  username_subquery,
+						  (!enable_selinux ? "" : ",c." SELINUX_SYSATTR_NAME),
 						  RELKIND_SEQUENCE,
 						  RELKIND_RELATION, RELKIND_SEQUENCE,
 						  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
@@ -3101,6 +3151,7 @@ getTables(int *numTables)
 	i_owning_col = PQfnumber(res, "owning_col");
 	i_reltablespace = PQfnumber(res, "reltablespace");
 	i_reloptions = PQfnumber(res, "reloptions");
+	i_selinux = PQfnumber(res, SELINUX_SYSATTR_NAME);
 
 	for (i = 0; i < ntups; i++)
 	{
@@ -3131,6 +3182,9 @@ getTables(int *numTables)
 		}
 		tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
 		tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
+		tblinfo[i].relsecurity = NULL;
+		if (i_selinux >= 0)
+			tblinfo[i].relsecurity = strdup(PQgetvalue(res, i, i_selinux));
 
 		/* other fields were zeroed above */
 
@@ -4319,6 +4373,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
 	int			i_atthasdef;
 	int			i_attisdropped;
 	int			i_attislocal;
+	int			i_attselinux;
 	PGresult   *res;
 	int			ntups;
 	bool		hasdefaults;
@@ -4362,11 +4417,13 @@ getTableAttrs(TableInfo *tblinfo, int nu
 			appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, a.attstattarget, a.attstorage, t.typstorage, "
 				  "a.attnotnull, a.atthasdef, a.attisdropped, a.attislocal, "
 				   "pg_catalog.format_type(t.oid,a.atttypmod) as atttypname "
+							  "%s "		/* security context, if required */
 			 "from pg_catalog.pg_attribute a left join pg_catalog.pg_type t "
 							  "on a.atttypid = t.oid "
 							  "where a.attrelid = '%u'::pg_catalog.oid "
 							  "and a.attnum > 0::pg_catalog.int2 "
 							  "order by a.attrelid, a.attnum",
+							  (!enable_selinux ? "" : ",a." SELINUX_SYSATTR_NAME),
 							  tbinfo->dobj.catId.oid);
 		}
 		else if (g_fout->remoteVersion >= 70100)
@@ -4415,6 +4472,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
 		i_atthasdef = PQfnumber(res, "atthasdef");
 		i_attisdropped = PQfnumber(res, "attisdropped");
 		i_attislocal = PQfnumber(res, "attislocal");
+		i_attselinux = PQfnumber(res, SELINUX_SYSATTR_NAME);
 
 		tbinfo->numatts = ntups;
 		tbinfo->attnames = (char **) malloc(ntups * sizeof(char *));
@@ -4425,6 +4483,7 @@ getTableAttrs(TableInfo *tblinfo, int nu
 		tbinfo->typstorage = (char *) malloc(ntups * sizeof(char));
 		tbinfo->attisdropped = (bool *) malloc(ntups * sizeof(bool));
 		tbinfo->attislocal = (bool *) malloc(ntups * sizeof(bool));
+		tbinfo->attsecurity = (char **) malloc(ntups * sizeof(char *));
 		tbinfo->notnull = (bool *) malloc(ntups * sizeof(bool));
 		tbinfo->attrdefs = (AttrDefInfo **) malloc(ntups * sizeof(AttrDefInfo *));
 		tbinfo->inhAttrs = (bool *) malloc(ntups * sizeof(bool));
@@ -4456,6 +4515,11 @@ getTableAttrs(TableInfo *tblinfo, int nu
 			tbinfo->inhAttrs[j] = false;
 			tbinfo->inhAttrDef[j] = false;
 			tbinfo->inhNotNull[j] = false;
+
+			/* security attribute, if defined */
+			tbinfo->attsecurity[j] = NULL;
+			if (i_attselinux >= 0 && !PQgetisnull(res, j, i_attselinux))
+				tbinfo->attsecurity[j] = strdup(PQgetvalue(res, j, i_attselinux));
 		}
 
 		PQclear(res);
@@ -6428,6 +6492,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	char	   *proconfig;
 	char	   *procost;
 	char	   *prorows;
+	char	   *proselinux = NULL;
 	char	   *lanname;
 	char	   *rettypename;
 	int			nallargs;
@@ -6459,8 +6524,10 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 						  "provolatile, proisstrict, prosecdef, "
 						  "proconfig, procost, prorows, "
 						  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) as lanname "
+						  "%s "		/* security context, if required */
 						  "FROM pg_catalog.pg_proc "
 						  "WHERE oid = '%u'::pg_catalog.oid",
+						  (!enable_selinux ? "" : "," SELINUX_SYSATTR_NAME),
 						  finfo->dobj.catId.oid);
 	}
 	else if (g_fout->remoteVersion >= 80100)
@@ -6562,6 +6629,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
 	lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
 
+	if (enable_selinux) {
+		int i_selinux = PQfnumber(res, "security_context");
+
+		if (i_selinux >= 0 && !PQgetisnull(res, 0, i_selinux))
+			proselinux = PQgetvalue(res, 0, i_selinux);
+	}
+
 	/*
 	 * See backend/commands/define.c for details of how the 'AS' clause is
 	 * used.
@@ -6698,6 +6772,9 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 	if (prosecdef[0] == 't')
 		appendPQExpBuffer(q, " SECURITY DEFINER");
 
+	if (proselinux)
+		appendPQExpBuffer(q, " CONTEXT = '%s'", proselinux);
+
 	/*
 	 * COST and ROWS are emitted only if present and not default, so as not to
 	 * break backwards-compatibility of the dump without need.	Keep this code
@@ -8779,6 +8856,9 @@ dumpTableSchema(Archive *fout, TableInfo
 				if (tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
 					appendPQExpBuffer(q, " NOT NULL");
 
+				if (enable_selinux && tbinfo->attsecurity[j])
+					appendPQExpBuffer(q, " CONTEXT = '%s'", tbinfo->attsecurity[j]);
+
 				actual_atts++;
 			}
 		}
@@ -8826,6 +8906,9 @@ dumpTableSchema(Archive *fout, TableInfo
 		if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
 			appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
 
+		if (enable_selinux && tbinfo->relsecurity)
+			appendPQExpBuffer(q, " CONTEXT = '%s'", tbinfo->relsecurity);
+
 		appendPQExpBuffer(q, ";\n");
 
 		/* Loop dumping statistics and storage statements */
@@ -10243,6 +10326,12 @@ fmtCopyColumnList(const TableInfo *ti)
 
 	appendPQExpBuffer(q, "(");
 	needComma = false;
+
+	if (enable_selinux) {
+		appendPQExpBuffer(q, SELINUX_SYSATTR_NAME);
+		needComma = true;
+	}
+
 	for (i = 0; i < numatts; i++)
 	{
 		if (attisdropped[i])
diff -rpNU3 pgace/src/bin/pg_dump/pg_dump.h sepgsql/src/bin/pg_dump/pg_dump.h
--- pgace/src/bin/pg_dump/pg_dump.h	2008-01-08 01:39:49.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dump.h	2008-01-10 18:25:12.000000000 +0900
@@ -238,6 +238,7 @@ typedef struct _tableInfo
 	char		relkind;
 	char	   *reltablespace;	/* relation tablespace */
 	char	   *reloptions;		/* options specified by WITH (...) */
+	char	   *relsecurity;	/* security attribute of the relation */
 	bool		hasindex;		/* does it have any indexes? */
 	bool		hasrules;		/* does it have any rules? */
 	bool		hasoids;		/* does it have OIDs? */
@@ -262,6 +263,7 @@ typedef struct _tableInfo
 	char	   *typstorage;		/* type storage scheme */
 	bool	   *attisdropped;	/* true if attr is dropped; don't dump it */
 	bool	   *attislocal;		/* true if attr has local definition */
+	char	  **attsecurity;	/* security attribute of attribute (column) */
 
 	/*
 	 * Note: we need to store per-attribute notnull, default, and constraint
diff -rpNU3 pgace/src/bin/pg_dump/pg_dumpall.c sepgsql/src/bin/pg_dump/pg_dumpall.c
--- pgace/src/bin/pg_dump/pg_dumpall.c	2008-01-08 01:39:49.000000000 +0900
+++ sepgsql/src/bin/pg_dump/pg_dumpall.c	2008-01-10 18:25:12.000000000 +0900
@@ -67,6 +67,10 @@ static int	disable_triggers = 0;
 static int	use_setsessauth = 0;
 static int	server_version;
 
+/* flag to tuen on/off SE-PostgreSQL support */
+#define SELINUX_SYSATTR_NAME	"security_context"
+static int  enable_selinux = 0;
+
 static FILE *OPF;
 static char *filename = NULL;
 
@@ -119,6 +123,7 @@ main(int argc, char *argv[])
 		{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
 		{"disable-triggers", no_argument, &disable_triggers, 1},
 		{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
+		{"enable-selinux", no_argument, NULL, 1001},
 
 		{NULL, 0, NULL, 0}
 	};
@@ -290,6 +295,10 @@ main(int argc, char *argv[])
 					appendPQExpBuffer(pgdumpopts, " --disable-triggers");
 				else if (strcmp(optarg, "use-set-session-authorization") == 0)
 					 /* no-op, still allowed for compatibility */ ;
+				else if (strcmp(optarg, "enable-selinux") == 0) {
+					appendPQExpBuffer(pgdumpopts, " --enable-selinux");
+					enable_selinux = 1;
+				}
 				else
 				{
 					fprintf(stderr,
@@ -300,6 +309,11 @@ main(int argc, char *argv[])
 				}
 				break;
 
+			case 1001:
+				appendPQExpBuffer(pgdumpopts, " --enable-selinux");
+				enable_selinux = 1;
+				break;
+
 			case 0:
 				break;
 
@@ -391,6 +405,24 @@ main(int argc, char *argv[])
 		}
 	}
 
+	if (enable_selinux) {
+        /* confirm whther server support SELinux features */
+        const char *tmp = PQparameterStatus(conn, "security_sysattr_name");
+
+        if (!tmp) {
+			fprintf(stderr, "could not get security_sysattr_name from libpq\n");
+            exit(1);
+        }
+        if (!!strcmp(SELINUX_SYSATTR_NAME, tmp) != 0) {
+			fprintf(stderr, "server does not have SELinux feature\n");
+            exit(1);
+        }
+        if (server_version < 80204) {
+			fprintf(stderr, "server version is too old (%u)\n", server_version);
+            exit(1);
+        }
+	}
+
 	/*
 	 * Open the output file if required, otherwise use stdout
 	 */
@@ -505,6 +537,7 @@ help(void)
 	printf(_("  --use-set-session-authorization\n"
 			 "                           use SESSION AUTHORIZATION commands instead of\n"
 			 "                           OWNER TO commands\n"));
+	printf(_("  --enable-selinux         enable to dump security attribute\n"));
 
 	printf(_("\nConnection options:\n"));
 	printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
@@ -915,16 +948,18 @@ dumpCreateDB(PGconn *conn)
 	fprintf(OPF, "--\n-- Database creation\n--\n\n");
 
 	if (server_version >= 80100)
-		res = executeQuery(conn,
+		appendPQExpBuffer(buf,
 						   "SELECT datname, "
 						   "coalesce(rolname, (select rolname from pg_authid where oid=(select datdba from pg_database where datname='template0'))), "
 						   "pg_encoding_to_char(d.encoding), "
 						   "datistemplate, datacl, datconnlimit, "
 						   "(SELECT spcname FROM pg_tablespace t WHERE t.oid = d.dattablespace) AS dattablespace "
+						   "%s "
 			  "FROM pg_database d LEFT JOIN pg_authid u ON (datdba = u.oid) "
-						   "WHERE datallowconn ORDER BY 1");
+						   "WHERE datallowconn ORDER BY 1",
+						   (!enable_selinux ? "" : "d." SELINUX_SYSATTR_NAME));
 	else if (server_version >= 80000)
-		res = executeQuery(conn,
+		appendPQExpBuffer(buf,
 						   "SELECT datname, "
 						   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
 						   "pg_encoding_to_char(d.encoding), "
@@ -933,7 +968,7 @@ dumpCreateDB(PGconn *conn)
 		   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
 						   "WHERE datallowconn ORDER BY 1");
 	else if (server_version >= 70300)
-		res = executeQuery(conn,
+		appendPQExpBuffer(buf,
 						   "SELECT datname, "
 						   "coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), "
 						   "pg_encoding_to_char(d.encoding), "
@@ -942,7 +977,7 @@ dumpCreateDB(PGconn *conn)
 		   "FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) "
 						   "WHERE datallowconn ORDER BY 1");
 	else if (server_version >= 70100)
-		res = executeQuery(conn,
+		appendPQExpBuffer(buf,
 						   "SELECT datname, "
 						   "coalesce("
 					"(select usename from pg_shadow where usesysid=datdba), "
@@ -958,7 +993,7 @@ dumpCreateDB(PGconn *conn)
 		 * Note: 7.0 fails to cope with sub-select in COALESCE, so just deal
 		 * with getting a NULL by not printing any OWNER clause.
 		 */
-		res = executeQuery(conn,
+		appendPQExpBuffer(buf,
 						   "SELECT datname, "
 					"(select usename from pg_shadow where usesysid=datdba), "
 						   "pg_encoding_to_char(d.encoding), "
@@ -968,6 +1003,7 @@ dumpCreateDB(PGconn *conn)
 						   "FROM pg_database d "
 						   "ORDER BY 1");
 	}
+	res = executeQuery(conn, buf->data);
 
 	for (i = 0; i < PQntuples(res); i++)
 	{
@@ -978,6 +1014,7 @@ dumpCreateDB(PGconn *conn)
 		char	   *dbacl = PQgetvalue(res, i, 4);
 		char	   *dbconnlimit = PQgetvalue(res, i, 5);
 		char	   *dbtablespace = PQgetvalue(res, i, 6);
+		char	   *dbsecurity = PQgetvalue(res, i, 7);
 		char	   *fdbname;
 
 		fdbname = strdup(fmtId(dbname));
@@ -1021,6 +1058,9 @@ dumpCreateDB(PGconn *conn)
 				appendPQExpBuffer(buf, " CONNECTION LIMIT = %s",
 								  dbconnlimit);
 
+			if (enable_selinux && dbsecurity)
+				appendPQExpBuffer(buf, " CONTEXT = '%s'", dbsecurity);
+
 			appendPQExpBuffer(buf, ";\n");
 
 			if (strcmp(dbistemplate, "t") == 0)
#3Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Kohei KaiGai (#1)
1 attachment(s)
[4/4] Proposal of SE-PostgreSQL patches

[4/4] - sepostgresql-policy-8.4devel-3.patch

This patch gives us the default security policy for SE-PostgreSQL.
You can build it as a security policy module. It can be linked with
the existing distributor's policy, and reloaded.

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

Attachments:

sepostgresql-policy-8.4devel-3.patchtext/x-patch; name=sepostgresql-policy-8.4devel-3.patchDownload
diff -rpNU3 pgace/contrib/sepgsql-policy/Makefile sepgsql/contrib/sepgsql-policy/Makefile
--- pgace/contrib/sepgsql-policy/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/contrib/sepgsql-policy/Makefile	2008-03-12 20:00:04.000000000 +0900
@@ -0,0 +1,20 @@
+# SE-PostgreSQL Security Policy
+#------------------------------
+
+SHAREDIR := /usr/share/selinux
+
+AWK ?= gawk
+NAME ?= $(strip $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' /etc/selinux/config))
+
+SELINUX_POLICY := /usr/share/selinux
+
+all: sepostgresql.pp
+
+install: all
+	install -m 0644 sepostgresql.pp $(SELINUX_POLICY)/$(NAME)
+
+sepostgresql.pp: sepostgresql.te sepostgresql.if sepostgresql.fc
+	make -f $(SELINUX_POLICY)/devel/Makefile NAME=$(NAME)
+
+clean:
+	make -f $(SELINUX_POLICY)/devel/Makefile NAME=$(NAME) clean
diff -rpNU3 pgace/contrib/sepgsql-policy/sepostgresql.fc sepgsql/contrib/sepgsql-policy/sepostgresql.fc
--- pgace/contrib/sepgsql-policy/sepostgresql.fc	1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/contrib/sepgsql-policy/sepostgresql.fc	2008-03-13 10:21:48.000000000 +0900
@@ -0,0 +1,17 @@
+#
+# SE-PostgreSQL install path
+#
+/usr/bin/sepostgres		--	gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/bin/initdb.sepgsql		--	gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/bin/sepg_ctl		--	gen_context(system_u:object_r:initrc_exec_t,s0)
+
+/var/lib/sepgsql(/.*)?			gen_context(system_u:object_r:postgresql_db_t,s0)
+/var/lib/sepgsql/pgstartup\.log		gen_context(system_u:object_r:postgresql_log_t,s0)
+/var/log/sepostgresql\.log.*	--	gen_context(system_u:object_r:postgresql_log_t,s0)
+
+#
+# For source installation
+#
+/usr/local/pgsql/bin/postgres	--	gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/local/pgsql/bin/initdb	--	gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/local/pgsql/bin/pg_ctl	--	gen_context(system_u:object_r:initrc_exec_t,s0)
diff -rpNU3 pgace/contrib/sepgsql-policy/sepostgresql.if sepgsql/contrib/sepgsql-policy/sepostgresql.if
--- pgace/contrib/sepgsql-policy/sepostgresql.if	1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/contrib/sepgsql-policy/sepostgresql.if	2008-03-12 20:00:04.000000000 +0900
@@ -0,0 +1,88 @@
+########################################
+## <summary>
+##      Marks the specified domain as SE-PostgreSQL server process.
+## </summary>
+## <param name="domain">
+##      <summary>
+##      Domain to be marked
+##      </summary>
+## </param>
+#
+interface(`sepgsql_server_domain',`
+	gen_require(`
+		attribute sepgsql_server_type;
+	')
+	typeattribute $1 sepgsql_server_type;
+')
+
+########################################
+## <summary>
+##      Allow the specified domain unconfined accesses to any database objects
+##  managed by SE-PostgreSQL,
+## </summary>
+## <param name="domain">
+##      <summary>
+##      Domain allowed access.
+##      </summary>
+## </param>
+#
+interface(`sepgsql_unconfined_domain',`
+	gen_require(`
+		attribute sepgsql_unconfined_type;
+		attribute sepgsql_client_type;
+	')
+	typeattribute $1 sepgsql_unconfined_type;
+	typeattribute $1 sepgsql_client_type;
+')
+
+########################################
+## <summary>
+##      Allow the specified domain unprivileged accesses to any database objects
+##  managed by SE-PostgreSQL,
+## </summary>
+## <param name="domain">
+##      <summary>
+##      Domain allowed access.
+##      </summary>
+## </param>
+#
+interface(`sepgsql_client_domain',`
+	gen_require(`
+		attribute sepgsql_client_type;
+	')
+	typeattribute $1 sepgsql_client_type;
+')
+
+########################################
+## <summary>
+##      Allow the specified role to invoke trusted procedures
+## </summary>
+## <param name="role">
+##  <summary>
+##  The role associated with the domain.
+##  </summary>
+## </param>
+#
+interface(`sepgsql_trusted_procedure_role',`
+	gen_require(`
+		type sepgsql_trusted_domain_t;
+	')
+	role $1 types sepgsql_trusted_domain_t;
+')
+
+########################################
+## <summary>
+##     Marks as a SE-PostgreSQL loadable shared library module
+## </summary>
+## <param name="type">
+##     <summary>
+##     Type marked as a database object type.
+##     </summary>
+## </param>
+#
+interface(`sepgsql_loadable_module',`
+	gen_require(`
+		attribute sepgsql_module_type;
+	')
+	typeattribute $1 sepgsql_module_type;
+')
diff -rpNU3 pgace/contrib/sepgsql-policy/sepostgresql.te sepgsql/contrib/sepgsql-policy/sepostgresql.te
--- pgace/contrib/sepgsql-policy/sepostgresql.te	1970-01-01 09:00:00.000000000 +0900
+++ sepgsql/contrib/sepgsql-policy/sepostgresql.te	2008-03-12 20:00:04.000000000 +0900
@@ -0,0 +1,353 @@
+policy_module(sepostgresql, 3.01)
+
+gen_require(`
+        class db_database all_db_database_perms;
+        class db_table all_db_table_perms;
+        class db_procedure all_db_procedure_perms;
+        class db_column all_db_column_perms;
+        class db_tuple all_db_tuple_perms;
+        class db_blob all_db_blob_perms;
+
+	type postgresql_t, unlabeled_t;
+	attribute domain, file_type;
+
+	role system_r;
+')
+
+#################################
+#
+# SE-PostgreSQL Boolean declarations
+#
+
+## <desc>
+## <p>
+## Allow to enable unconfined domains
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_unconfined, true)
+
+## <desc>
+## <p>
+## Allow to generate auditallow logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditallow, false)
+
+## <desc>
+## <p>
+## Allow to generate auditdeny logs
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_auditdeny,  true)
+
+## <desc>
+## <p>
+## Allow to generate audit(allow|deny) logs for tuples
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_audittuple, false)
+
+## <desc>
+## <p>
+## Allow unprivileged users to execute DDL statement
+## </p>
+## </desc>
+gen_tunable(sepgsql_enable_users_ddl,  true)
+
+#################################
+#
+# SE-PostgreSQL Type/Attribute declarations
+#
+
+# database subjects
+attribute sepgsql_server_type;
+attribute sepgsql_client_type;
+attribute sepgsql_unconfined_type;
+
+# database objects attribute
+attribute sepgsql_database_type;
+attribute sepgsql_table_type;
+attribute sepgsql_procedure_type;
+attribute sepgsql_blob_type;
+attribute sepgsql_module_type;
+
+# database trusted domain
+type sepgsql_trusted_domain_t;
+
+# database object types
+type sepgsql_db_t,		sepgsql_database_type;
+
+type sepgsql_table_t,		sepgsql_table_type;
+type sepgsql_sysobj_t,		sepgsql_table_type;
+type sepgsql_secret_table_t,	sepgsql_table_type;
+type sepgsql_ro_table_t,	sepgsql_table_type;
+type sepgsql_fixed_table_t,	sepgsql_table_type;
+
+type sepgsql_proc_t,		sepgsql_procedure_type;
+type sepgsql_user_proc_t,	sepgsql_procedure_type;
+type sepgsql_trusted_proc_t,	sepgsql_procedure_type;
+
+type sepgsql_blob_t,		sepgsql_blob_type;
+type sepgsql_ro_blob_t,		sepgsql_blob_type;
+type sepgsql_secret_blob_t,	sepgsql_blob_type;
+
+typeattribute unlabeled_t	sepgsql_database_type;
+typeattribute unlabeled_t	sepgsql_table_type;
+typeattribute unlabeled_t	sepgsql_procedure_type;
+typeattribute unlabeled_t	sepgsql_blob_type;
+
+########################################
+#
+# SE-PostgreSQL Server Local policy
+#                    (sepgsql_server_type)
+allow sepgsql_server_type self : netlink_selinux_socket create_socket_perms;
+selinux_get_fs_mount(sepgsql_server_type)
+selinux_get_enforce_mode(sepgsql_server_type)
+selinux_validate_context(sepgsql_server_type)
+selinux_compute_access_vector(sepgsql_server_type)
+selinux_compute_create_context(sepgsql_server_type)
+selinux_compute_relabel_context(sepgsql_server_type)
+
+allow sepgsql_server_type sepgsql_database_type : db_database *;
+allow sepgsql_server_type sepgsql_module_type : db_database { install_module };
+allow sepgsql_server_type sepgsql_table_type : { db_table db_column db_tuple } *;
+allow sepgsql_server_type sepgsql_procedure_type : db_procedure *;
+allow sepgsql_server_type sepgsql_blob_type : db_blob *;
+
+# server specific type transitions
+type_transition sepgsql_server_type sepgsql_database_type : db_table sepgsql_sysobj_t;
+type_transition sepgsql_server_type sepgsql_database_type : db_procedure sepgsql_proc_t;
+
+########################################
+#
+# SE-PostgreSQL Administrative domain local policy
+#                    (sepgsql_unconfined_type)
+
+tunable_policy(`sepgsql_enable_unconfined',`
+	allow sepgsql_unconfined_type sepgsql_database_type : db_database *;
+	allow sepgsql_unconfined_type sepgsql_module_type : db_database { install_module };
+	allow sepgsql_unconfined_type sepgsql_table_type : { db_table db_column db_tuple } *;
+	allow sepgsql_unconfined_type { sepgsql_procedure_type - sepgsql_user_proc_t } : db_procedure *;
+	allow sepgsql_unconfined_type sepgsql_user_proc_t : db_procedure { create drop getattr setattr relabelfrom relabelto };
+	allow sepgsql_unconfined_type sepgsql_blob_type : db_blob *;
+	allow sepgsql_unconfined_type postgresql_t : db_blob { import export };
+
+	type_transition { sepgsql_unconfined_type - sepgsql_server_type } sepgsql_database_type : db_procedure sepgsql_proc_t;
+',`
+	type_transition { sepgsql_unconfined_type - sepgsql_server_type } sepgsql_database_type : db_procedure sepgsql_user_proc_t;
+')
+
+########################################
+#
+# SE-PostgreSQL Users domain local policy
+#                     (sepgsql_client_type)
+
+allow sepgsql_client_type sepgsql_db_t : db_database { getattr access get_param set_param};
+
+allow sepgsql_client_type sepgsql_table_t : db_table { getattr use select update insert delete };
+allow sepgsql_client_type sepgsql_table_t : db_column { getattr use select update insert };
+allow sepgsql_client_type sepgsql_table_t : db_tuple { use select update insert delete };
+
+allow sepgsql_client_type sepgsql_sysobj_t : db_table { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t : db_column { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t : db_tuple { use select };
+tunable_policy(`sepgsql_enable_users_ddl',`
+	allow sepgsql_client_type sepgsql_table_t : db_table { create drop setattr };
+	allow sepgsql_client_type sepgsql_table_t : db_column { create drop setattr };
+	allow sepgsql_client_type sepgsql_sysobj_t : db_tuple { update insert delete };
+')
+
+allow sepgsql_client_type sepgsql_secret_table_t : db_table { getattr };
+allow sepgsql_client_type sepgsql_secret_table_t : db_column { getattr };
+
+allow sepgsql_client_type sepgsql_ro_table_t : db_table { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t : db_column { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t : db_tuple { use select };
+
+allow sepgsql_client_type sepgsql_fixed_table_t : db_table { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t : db_column { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t : db_tuple { use select insert };
+
+allow sepgsql_client_type sepgsql_proc_t : db_procedure { getattr execute };
+allow { sepgsql_client_type - sepgsql_unconfined_type } sepgsql_user_proc_t : db_procedure { create drop getattr setattr execute };
+allow sepgsql_client_type sepgsql_trusted_proc_t : db_procedure { getattr execute entrypoint };
+
+allow sepgsql_client_type sepgsql_blob_t : db_blob { create drop getattr setattr read write };
+allow sepgsql_client_type sepgsql_ro_blob_t : db_blob { getattr read };
+allow sepgsql_client_type sepgsql_secret_blob_t : db_blob { getattr };
+
+# call trusted procedure
+type_transition sepgsql_client_type sepgsql_trusted_proc_t : process sepgsql_trusted_domain_t;
+allow sepgsql_client_type sepgsql_trusted_domain_t : process { transition };
+
+# type transitions for rest of domains
+type_transition domain domain : db_database sepgsql_db_t;
+type_transition { domain - sepgsql_server_type } sepgsql_database_type : db_table sepgsql_table_t;
+type_transition { domain - sepgsql_server_type - sepgsql_unconfined_type } sepgsql_database_type : db_procedure sepgsql_user_proc_t;
+type_transition domain sepgsql_database_type : db_blob sepgsql_blob_t;
+
+########################################
+#
+# SE-PostgreSQL Misc policies
+#
+
+# Trusted Procedure Domain
+domain_type(sepgsql_trusted_domain_t)
+role system_r types sepgsql_trusted_domain_t;
+sepgsql_unconfined_domain(sepgsql_trusted_domain_t)
+
+# The following permissions are allowed, even if sepgsql_enable_unconfined is disabled.
+allow sepgsql_trusted_domain_t sepgsql_database_type : db_database { getattr setattr access get_param set_param};
+allow sepgsql_trusted_domain_t sepgsql_table_type : db_table { getattr use select update insert delete lock };
+allow sepgsql_trusted_domain_t sepgsql_table_type : db_column { getattr use select update insert };
+allow sepgsql_trusted_domain_t sepgsql_table_type : db_tuple { use select update insert delete };
+
+allow sepgsql_trusted_domain_t { sepgsql_procedure_type - sepgsql_user_proc_t } : db_procedure { getattr execute };
+allow sepgsql_trusted_domain_t sepgsql_user_proc_t : db_procedure { getattr };
+allow sepgsql_trusted_domain_t sepgsql_blob_type : db_blob { getattr setattr read write };
+
+# Database/Loadable module
+allow sepgsql_database_type sepgsql_module_type : db_database { load_module };
+
+########################################
+#
+# SE-PostgreSQL audit switch
+#
+tunable_policy(`sepgsql_enable_auditallow',`
+	auditallow domain sepgsql_database_type  : db_database all_db_database_perms;
+	auditallow domain sepgsql_table_type     : db_table all_db_table_perms;
+	auditallow domain sepgsql_table_type     : db_column all_db_column_perms;
+	auditallow domain sepgsql_procedure_type : db_procedure all_db_procedure_perms;
+	auditallow domain sepgsql_blob_type      : db_blob all_db_blob_perms;
+	auditallow domain sepgsql_server_type    : db_blob { import export };
+	auditallow domain sepgsql_module_type    : db_database { install_module };
+')
+tunable_policy(`sepgsql_enable_audittuple && sepgsql_enable_auditallow',`
+	auditallow domain sepgsql_table_type     : db_tuple all_db_tuple_perms;
+')
+tunable_policy(`! sepgsql_enable_auditdeny',`
+	dontaudit domain sepgsql_database_type   : db_database all_db_database_perms;
+	dontaudit domain sepgsql_table_type      : db_table all_db_table_perms;
+	dontaudit domain sepgsql_table_type      : db_column all_db_column_perms;
+	dontaudit domain sepgsql_procedure_type  : db_procedure all_db_procedure_perms;
+	dontaudit domain sepgsql_blob_type       : db_blob all_db_blob_perms;
+	dontaudit domain sepgsql_server_type     : db_blob { import export };
+	dontaudit domain sepgsql_module_type     : db_database { install_module };
+')
+tunable_policy(`! sepgsql_enable_audittuple || ! sepgsql_enable_auditdeny',`
+	dontaudit domain sepgsql_table_type      : db_tuple all_db_tuple_perms;
+')
+########################################
+#
+# Allow permission to external domains
+#
+
+# server domains
+optional_policy(`
+	gen_require(`
+		type postgresql_t;
+	')
+	sepgsql_server_domain(postgresql_t)
+')
+
+# unconfined client domain
+optional_policy(`
+	gen_require(`
+		type unconfined_t;
+	')
+	sepgsql_unconfined_domain(unconfined_t)
+')
+
+optional_policy(`
+	gen_require(`
+		type sysadm_t;
+	')
+	sepgsql_unconfined_domain(sysadm_t)
+')
+
+# generic client domain
+optional_policy(`
+	gen_require(`
+		type user_t;
+		role user_r;
+	')
+	sepgsql_client_domain(user_t)
+	sepgsql_trusted_procedure_role(user_r)
+')
+
+optional_policy(`
+	gen_require(`
+		type staff_t;
+		role staff_r;
+	')
+	sepgsql_client_domain(staff_t)
+	sepgsql_trusted_procedure_role(staff_r)
+')
+
+optional_policy(`
+	gen_require(`
+		type user_t;
+		role user_r;
+	')
+	sepgsql_client_domain(user_t)
+	sepgsql_trusted_procedure_role(user_r)
+')
+
+optional_policy(`
+	gen_require(`
+		type guest_t;
+		role guest_r;
+	')
+	sepgsql_client_domain(guest_t)
+	sepgsql_trusted_procedure_role(guest_r)
+')
+
+optional_policy(`
+	gen_require(`
+		type xguest_t;
+		role xguest_r;
+	')
+	sepgsql_client_domain(xguest_t)
+	sepgsql_trusted_procedure_role(xguest_r)
+')
+
+optional_policy(`
+	gen_require(`
+		type httpd_sys_script_t;
+	')
+	sepgsql_client_domain(httpd_sys_script_t)
+')
+
+# RBAC
+optional_policy(`
+	gen_require(`
+		role unconfined_r;
+	')
+	sepgsql_trusted_procedure_role(unconfined_r)
+')
+
+# loadable module types
+optional_policy(`
+	gen_require(`
+		type lib_t;
+	')
+	sepgsql_loadable_module(lib_t)
+')
+
+optional_policy(`
+	gen_require(`
+		type textrel_shlib_t;
+	')
+	sepgsql_loadable_module(textrel_shlib_t)
+')
+
+########################################
+#
+# Hotfixes for labeled networking
+# 
+# NOTE: These changes are to be merged in the later releases.
+corenet_tcp_recvfrom_labeled(sepgsql_server_type, sepgsql_client_type)
+optional_policy(`
+	ipsec_match_default_spd(sepgsql_server_type)
+	ipsec_match_default_spd(sepgsql_client_type)
+')
#4Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Kohei KaiGai (#1)
Re: [0/4] Proposal of SE-PostgreSQL patches

It seems to me some of SE-PostgreSQL patches are not delivered yet,
although [3/4] and [4/4] were already done.

Does anti-spam system caught my previous three messages?
If necessary, I will send them again.

Thanks,

Kohei KaiGai wrote:

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

[1/4] sepostgresql-pgace-8.4devel-3.patch
provides PGACE (PostgreSQL Access Control Extension) framework
[2/4] sepostgresql-sepgsql-8.4devel-3.patch
provides SE-PostgreSQL feature, based on PGACE framework.
[3/4] sepostgresql-pg_dump-8.4devel-3.patch
enables pg_dump to dump database with security attribute.
[4/4] sepostgresql-policy-8.4devel-3.patch
provides the default security policy for SE-PostgreSQL.

- snip -

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#5Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Kohei KaiGai (#4)
Re: [0/4] Proposal of SE-PostgreSQL patches

Kohei KaiGai napsal(a):

It seems to me some of SE-PostgreSQL patches are not delivered yet,
although [3/4] and [4/4] were already done.

Does anti-spam system caught my previous three messages?
If necessary, I will send them again.

There is a file size limitation. If your patch is too big (I guess over
40kB), please gzip it or send only url for download.

Zdenek

#6Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Zdenek Kotala (#5)
Re: [0/4] Proposal of SE-PostgreSQL patches

Zdenek Kotala wrote:

Kohei KaiGai napsal(a):

It seems to me some of SE-PostgreSQL patches are not delivered yet,
although [3/4] and [4/4] were already done.

Does anti-spam system caught my previous three messages?
If necessary, I will send them again.

There is a file size limitation. If your patch is too big (I guess over
40kB), please gzip it or send only url for download.

Zdenek

Thanks for your information,

Your estimation is correct. Two of them are over the limitaion.
So, I'll send it again with gzip'ed attachment.

[kaigai@saba a]$ ls -lh *-8.4devel-*.patch
-rw-r--r-- 1 kaigai users 17K 2008-03-17 13:01 sepostgresql-pg_dump-8.4devel-3.patch
-rw-r--r-- 1 kaigai users 134K 2008-03-17 13:01 sepostgresql-pgace-8.4devel-3.patch
-rw-r--r-- 1 kaigai users 17K 2008-03-17 13:01 sepostgresql-policy-8.4devel-3.patch
-rw-r--r-- 1 kaigai users 138K 2008-03-17 13:01 sepostgresql-sepgsql-8.4devel-3.patch

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#7Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Kohei KaiGai (#1)
1 attachment(s)
[1/4] Proposal of SE-PostgreSQL patches

[1/4] - sepostgresql-pgace-8.4devel-3.patch.gz

This patch provides PGACE (PostgreSQL Access Control Extension) framework.

It has a similar idea of LSM (Linu Security Module).
It can provide a guest module several hooks at strategic points.
The guest module can make its decision whether required actions should be
allowed, or not.
In addition, PGACE also provides falicilites to manage security attribute
of database objects. Any tuple can have a its security attribute, and the
guest module can refer it to control accesses.

A more conprehensive memo at:
http://code.google.com/p/sepgsql/wiki/WhatIsPGACE

(This patch is gzip'ed, bacause it overed the limitation of filesize.)

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

Attachments:

sepostgresql-pgace-8.4devel-3.patch.gzapplication/gzip; name=sepostgresql-pgace-8.4devel-3.patch.gzDownload
#8Kohei KaiGai
kaigai@ak.jp.nec.com
In reply to: Kohei KaiGai (#1)
1 attachment(s)
[2/4] Proposal of SE-PostgreSQL patches

[2/4] - sepostgresql-sepgsql-8.4devel-3.patch.gz

This patch provides SE-PostgreSQL facilities based on PGACE.

Security-Enhanced PostgreSQL (SE-PostgreSQL) is a security extension
built in PostgreSQL, to provide system-wide consistency in access
controls. It enables to apply a single unigied security policy of
SELinux for both operating system and database management system.
In addition, it also provides fine-grained mandatory access which
includes column-/row- level non-bypassable access control even if
privileged database users.

Quick overview at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

(This patch is gzip'ed, bacause it overed the limitation of filesize.)

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

Attachments:

sepostgresql-sepgsql-8.4devel-3.patch.gzapplication/gzip; name=sepostgresql-sepgsql-8.4devel-3.patch.gzDownload
#9Alvaro Herrera
alvherre@commandprompt.com
In reply to: Kohei KaiGai (#1)
Re: [0/4] Proposal of SE-PostgreSQL patches

Kohei KaiGai wrote:

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

Before we go any further, is this work derived from SELinux? If so, is
it covered under the GPL? If so, can it be licensed under BSD terms?

Obviously, if it's not BSD, we cannot include it in Postgres.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

#10KaiGai Kohei
kaigai@kaigai.gr.jp
In reply to: Alvaro Herrera (#9)
Re: [0/4] Proposal of SE-PostgreSQL patches

Alvaro Herrera wrote:

Kohei KaiGai wrote:

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

Before we go any further, is this work derived from SELinux? If so, is
it covered under the GPL? If so, can it be licensed under BSD terms?

Obviously, if it's not BSD, we cannot include it in Postgres.

All of SE-PostgreSQL works are licensed unser BSD terms.
We are considering to push SE-PostgreSQL into upstreamed PostgreSQL from
the beginning, and we understand to choose GPL makes it impossible.

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

#11KaiGai Kohei
kaigai@kaigai.gr.jp
In reply to: Kohei KaiGai (#1)
Re: [0/4] Proposal of SE-PostgreSQL patches

I'll submit the proposal of SE-PostgreSQL patches again, because some of previous
messages are filtered due to attachment and I cannot provide whole of patches yet.
Please refer the pointed URL, as follows.

------
The series of patches are the proposal of Security-Enhanced PostgreSQL (SE-PostgreSQL)
for the upstreamed PostgreSQL 8.4 development cycle.

[1/4] sepostgresql-pgace-8.4devel-3.patch
provides PGACE (PostgreSQL Access Control Extension) framework
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r704.patch

[2/4] sepostgresql-sepgsql-8.4devel-3.patch
provides SE-PostgreSQL feature, based on PGACE framework.
http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r704.patch

[3/4] sepostgresql-pg_dump-8.4devel-3.patch
enables pg_dump to dump database with security attribute.
http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r704.patch

[4/4] sepostgresql-policy-8.4devel-3.patch
provides the default security policy for SE-PostgreSQL.
http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r704.patch

We can provide a quick overview for SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

ENVIRONMENT
-----------
Please confirm your environment.
The followings are requriements of SE-PostgreSQL.
* Fedora 8 or later system
* SELinux is enabled and working
* kernel-2.6.24 or later
* selinux-policy and selinux-policy-devel v3.0.8 or later
* libselinux, policycoreutils

INSTALLATION
------------
$ tar jxvf postgresql-snapshot.tar.bz2
$ cd postgresql-snapshot
$ patch -p1 < ../sepostgresql-pgace-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-sepgsql-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-pg_dump-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-policy-8.4devel-3.patch

$ ./configure --enable-selinux
$ make
$ make -C contrib/sepgsql-policy
$ su
# make install

# /usr/sbin/semodule -i contrib/sepgsql-policy/sepostgresql.pp
(NOTE: semodule is a utility to load/unload security policy modules.)

# /sbin/restorecon -R /usr/local/pgsql
(NOTE: restorecon is a utilicy to initialize security context of files.)

SETUP
-----
# mkdir -p /opt/sepgsql
# chown foo_user:var_group /opt/sepgsql
# chcon -t postgresql_db_t /opt/sepgsql
(NOTE: chcon is a utility to set up security context of files.)
# exit

$ /usr/sbin/run_init /usr/local/pgsql/bin/initdb -D /opt/sepgsql
(NOTE: run_init is a utility to start a program, as if it is branched from init script.)
$ /usr/local/pgsql/bin/pg_ctl -D /opt/sepgsql start

SUMMARYS FOR EVERY PATCHES
--------------------------
[1/4] - sepostgresql-pgace-8.4devel-3.patch

This patch provides PGACE (PostgreSQL Access Control Extension) framework.

It has a similar idea of LSM (Linu Security Module).
It can provide a guest module several hooks at strategic points.
The guest module can make its decision whether required actions should be
allowed, or not.
In addition, PGACE also provides falicilites to manage security attribute
of database objects. Any tuple can have a its security attribute, and the
guest module can refer it to control accesses.

A more conprehensive memo at:
http://code.google.com/p/sepgsql/wiki/WhatIsPGACE

[2/4] - sepostgresql-sepgsql-8.4devel-3.patch

This patch provides SE-PostgreSQL facilities based on PGACE.

Security-Enhanced PostgreSQL (SE-PostgreSQL) is a security extension
built in PostgreSQL, to provide system-wide consistency in access
controls. It enables to apply a single unigied security policy of
SELinux for both operating system and database management system.
In addition, it also provides fine-grained mandatory access which
includes column-/row- level non-bypassable access control even if
privileged database users.

Quick overview at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

[3/4] - sepostgresql-pg_dump-8.4devel-3.patch

This patch gives us a feature to dump database with security attribute.
It is turned on with '--enable-selinux' option at pg_dump/pg_dumpall,
when the server works as SE- version.
No need to say, users need to have enough capabilities to dump whole of
database. It it same when they tries to restore the database.

[4/4] - sepostgresql-policy-8.4devel-3.patch

This patch gives us the default security policy for SE-PostgreSQL.
You can build it as a security policy module. It can be linked with
the existing distributor's policy, and reloaded.

--
KaiGai Kohei <kaigai@kaigai.gr.jp>

#12Alvaro Herrera
alvherre@commandprompt.com
In reply to: KaiGai Kohei (#10)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei wrote:

Alvaro Herrera wrote:

Before we go any further, is this work derived from SELinux? If so, is
it covered under the GPL? If so, can it be licensed under BSD terms?

All of SE-PostgreSQL works are licensed unser BSD terms.
We are considering to push SE-PostgreSQL into upstreamed PostgreSQL from
the beginning, and we understand to choose GPL makes it impossible.

Right. The question is: since this is derived from SE-Linux, is it
affected by SE-Linux license?

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

#13KaiGai Kohei
kaigai@kaigai.gr.jp
In reply to: Alvaro Herrera (#12)
Re: [0/4] Proposal of SE-PostgreSQL patches

Alvaro Herrera wrote:

KaiGai Kohei wrote:

Alvaro Herrera wrote:

Before we go any further, is this work derived from SELinux? If so, is
it covered under the GPL? If so, can it be licensed under BSD terms?

All of SE-PostgreSQL works are licensed unser BSD terms.
We are considering to push SE-PostgreSQL into upstreamed PostgreSQL from
the beginning, and we understand to choose GPL makes it impossible.

Right. The question is: since this is derived from SE-Linux, is it
affected by SE-Linux license?

No, SE-PostgreSQL does not derivered from SELinux.

I guess you worry about SE-PostgreSQL contains a part of SELinux licensed
as GPL, but it is incorrect.
SE-PostgreSQL communicate with SELinux to make its decision in access control,
via an official interface provided by libselinux, because it does not have
information to make its decision.
The libselinux is linked with SE-PostgreSQL, but it is licensed as public
domain software by NSA.

Therefore, we have no issues related to imcompatible licenses.

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

#14Greg Smith
gsmith@gregsmith.com
In reply to: KaiGai Kohei (#11)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

On Mon, 17 Mar 2008, KaiGai Kohei wrote:

I'll submit the proposal of SE-PostgreSQL patches again, because some of previous
messages are filtered due to attachment and I cannot provide whole of patches yet.

This is actually what you should have done from the beginning. And it
only should have gone to the pgsql-hackers list, which is the only one I'm
replying to. Your patches are at this point a proposal, as you say in the
subject, and those go to the pgsql-hackers list with the minimum of files
necessary to support them. pgsql-patches is generally aimed at patches
that have already been discussed on the hackers list, ones that are
basically ready to apply to the source code.

The libselinux is linked with SE-PostgreSQL, but it is licensed as
public domain software by NSA.

As for the licensing issues here, what everyone is looking for is a clear
statement of the SELinux license from the source of that code. The
official NSA statment at http://www.nsa.gov/selinux/info/license.cfm says:

"All source code found on this site is released under the same terms and
conditions as the original sources. For example, the patches to the Linux
kernel, patches to many existing utilities, and some of the new programs
available here are released under the terms and conditions of the GNU
General Public License (GPL). Please refer to the source code for specific
license information."

GPL is a perfectly good license, but it's far from clear whether code
derived from it can be incorporated into PostgreSQL even if you wrote all
of it yourself. I just checked libselinux, and as you say it includes a
LICENSE file that states "This library (libselinux) is public domain
software, i.e. not copyrighted.". That's good, but a similar independant
review will need to happen for every component you interact with here, on
top of a technical review. Luckily this is something a lot of people
would like and that should all get taken care of.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#15Josh Berkus
josh@agliodbs.com
In reply to: Kohei KaiGai (#1)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai,

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

Since I'm (Finally!) expecting the TrustedSolaris folks to put some work into
PostgreSQL as well this year, I'm going to ask them to look over PGACE to see
if this implementation is (still) generic enough to support TS as well. If
it is, then it's probably generic enough to be a general building block.

--
Josh Berkus
PostgreSQL @ Sun
San Francisco

#16Gregory Stark
stark@enterprisedb.com
In reply to: Greg Smith (#14)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

"Greg Smith" <gsmith@gregsmith.com> writes:

On Mon, 17 Mar 2008, KaiGai Kohei wrote:

I'll submit the proposal of SE-PostgreSQL patches again, because some of previous
messages are filtered due to attachment and I cannot provide whole of patches yet.

This is actually what you should have done from the beginning. And it only
should have gone to the pgsql-hackers list, which is the only one I'm replying
to. Your patches are at this point a proposal, as you say in the subject, and
those go to the pgsql-hackers list with the minimum of files necessary to
support them. pgsql-patches is generally aimed at patches that have already
been discussed on the hackers list, ones that are basically ready to apply to
the source code.

Some people shout any time you send patches to -hackers. For the -patches is
there mainly to catch large attachments regardless of their maturity.

But it's true that it's best to post a plan and have discussion prior to
developing big patches.

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Ask me about EnterpriseDB's PostGIS support!

#17Greg Smith
gsmith@gregsmith.com
In reply to: Gregory Stark (#16)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

On Mon, 17 Mar 2008, Gregory Stark wrote:

Some people shout any time you send patches to -hackers.

Right, but if you note the improved version I give the thumbs-up to didn't
include any patches--just links to where you could get them. There's
little reason to include any code as an attachment for a proposal if you
can direct people to the web for them. That's why I suggested sending
"the minimum of files necessary", which in this case was zero.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#18KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Josh Berkus (#15)
Re: [0/4] Proposal of SE-PostgreSQL patches

Josh Berkus wrote:

KaiGai,

The series of patches are the proposal of Security-Enhanced PostgreSQL
(SE-PostgreSQL) for the upstreamed PostgreSQL 8.4 development cycle.

Since I'm (Finally!) expecting the TrustedSolaris folks to put some work into
PostgreSQL as well this year, I'm going to ask them to look over PGACE to see
if this implementation is (still) generic enough to support TS as well. If
it is, then it's probably generic enough to be a general building block.

We can extend PGACE framework to mount TrustedSolaris features.
If they need new hooks which is not used in SE-PostgreSQL, it can
remain the default behavior.
The default PGACE behavior gives us no effects in access controls.

A flexible framework is worthwhile for both operating systems.
Please confirm it to the TS folks.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#19KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Greg Smith (#14)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

Greg Smith wrote:

On Mon, 17 Mar 2008, KaiGai Kohei wrote:

I'll submit the proposal of SE-PostgreSQL patches again, because some
of previous
messages are filtered due to attachment and I cannot provide whole of
patches yet.

This is actually what you should have done from the beginning. And it
only should have gone to the pgsql-hackers list, which is the only one
I'm replying to. Your patches are at this point a proposal, as you say
in the subject, and those go to the pgsql-hackers list with the minimum
of files necessary to support them. pgsql-patches is generally aimed at
patches that have already been discussed on the hackers list, ones that
are basically ready to apply to the source code.

OK, I can understand the purpose of pgsql-hackers and pgsql-patches list.
At first, I'll have a discussion here.

The libselinux is linked with SE-PostgreSQL, but it is licensed as
public domain software by NSA.

As for the licensing issues here, what everyone is looking for is a
clear statement of the SELinux license from the source of that code.
The official NSA statment at http://www.nsa.gov/selinux/info/license.cfm
says:

"All source code found on this site is released under the same terms and
conditions as the original sources. For example, the patches to the
Linux kernel, patches to many existing utilities, and some of the new
programs available here are released under the terms and conditions of
the GNU General Public License (GPL). Please refer to the source code
for specific license information."

GPL is a perfectly good license, but it's far from clear whether code
derived from it can be incorporated into PostgreSQL even if you wrote
all of it yourself. I just checked libselinux, and as you say it
includes a LICENSE file that states "This library (libselinux) is public
domain software, i.e. not copyrighted.". That's good, but a similar
independant review will need to happen for every component you interact
with here, on top of a technical review. Luckily this is something a
lot of people would like and that should all get taken care of.

SE-PostgreSQL internally uses libselinux, glibc and PostgreSQL internal
APIs like SearchSysCache().
I'm not a lawyer, but I believe they cannot enforce us to apply a specific
lisence. So, I clearly say SE-PostgreSQL feature is licensed with the same
one of PostgreSQL.
No need to say, more conprehensive checks and reviews are welcome.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#20Joshua D. Drake
jd@commandprompt.com
In reply to: KaiGai Kohei (#19)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 18 Mar 2008 10:41:42 +0900
KaiGai Kohei <kaigai@ak.jp.nec.com> wrote:

GPL is a perfectly good license, but it's far from clear whether
code derived from it can be incorporated into PostgreSQL even if
you wrote all of it yourself. I just checked libselinux, and as
you say it includes a LICENSE file that states "This library
(libselinux) is public domain software, i.e. not copyrighted.".
That's good, but a similar independant review will need to happen
for every component you interact with here, on top of a technical
review. Luckily this is something a lot of people would like and
that should all get taken care of.

SE-PostgreSQL internally uses libselinux, glibc and PostgreSQL
internal APIs like SearchSysCache().
I'm not a lawyer, but I believe they cannot enforce us to apply a
specific lisence. So, I clearly say SE-PostgreSQL feature is licensed
with the same one of PostgreSQL.
No need to say, more conprehensive checks and reviews are welcome.

Hmmm,

Everything that I read says that libselinux is GPL. That could present
a problem for anyone that wants to use the BSD features of
PostgreSQL :).

I can check with SFLC if people are really curious.

Sincerely,

Joshua D. Drake

- --
The PostgreSQL Company since 1997: http://www.commandprompt.com/
PostgreSQL Community Conference: http://www.postgresqlconference.org/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate
PostgreSQL political pundit | Mocker of Dolphins

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFH3x/wATb/zqfZUUQRAq6WAJ9h2ecrYrsZ5bJUTJGhyS2LZSOqkACfeGoB
EHwcHtq7Ow5k3AlKNPwOVzs=
=yamT
-----END PGP SIGNATURE-----

#21KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Joshua D. Drake (#20)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

Joshua D. Drake wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, 18 Mar 2008 10:41:42 +0900
KaiGai Kohei <kaigai@ak.jp.nec.com> wrote:

GPL is a perfectly good license, but it's far from clear whether
code derived from it can be incorporated into PostgreSQL even if
you wrote all of it yourself. I just checked libselinux, and as
you say it includes a LICENSE file that states "This library
(libselinux) is public domain software, i.e. not copyrighted.".
That's good, but a similar independant review will need to happen
for every component you interact with here, on top of a technical
review. Luckily this is something a lot of people would like and
that should all get taken care of.

SE-PostgreSQL internally uses libselinux, glibc and PostgreSQL
internal APIs like SearchSysCache().
I'm not a lawyer, but I believe they cannot enforce us to apply a
specific lisence. So, I clearly say SE-PostgreSQL feature is licensed
with the same one of PostgreSQL.
No need to say, more conprehensive checks and reviews are welcome.

Hmmm,

Everything that I read says that libselinux is GPL. That could present
a problem for anyone that wants to use the BSD features of
PostgreSQL :).

It is incorrect.
SELinux is indeed GPL because it is a part of kernel feature.
But libselinux is a public domain software, as follows:
https://selinux.svn.sourceforge.net/svnroot/selinux/trunk/libselinux/LICENSE

SE-PostgreSQL is linked with *ONLY* libselinux. It communicate to SELinux
via system call. As you know, GPL does not consider invokation of system calls
as a "link". Thus, we can release SE-PostgreSQL as a BSD licensed software.

Thanks,

I can check with SFLC if people are really curious.

Sincerely,

Joshua D. Drake

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#22Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joshua D. Drake (#20)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

"Joshua D. Drake" <jd@commandprompt.com> writes:

Everything that I read says that libselinux is GPL.

What exactly did you read? The LICENSE file in the source tarball
says

: This library (libselinux) is public domain software, i.e. not copyrighted.
:
: Warranty Exclusion
: ------------------
: You agree that this software is a
: non-commercially developed program that may contain "bugs" (as that
: term is used in the industry) and that it may not function as intended.
: The software is licensed "as is". NSA makes no, and hereby expressly
: disclaims all, warranties, express, implied, statutory, or otherwise
: with respect to the software, including noninfringement and the implied
: warranties of merchantability and fitness for a particular purpose.
:
: Limitation of Liability
: -----------------------
: In no event will NSA be liable for any damages, including loss of data,
: lost profits, cost of cover, or other special, incidental,
: consequential, direct or indirect damages arising from the software or
: the use thereof, however caused and on any theory of liability. This
: limitation will apply even if NSA has been advised of the possibility
: of such damage. You acknowledge that this is a reasonable allocation of
: risk.

I have a feeling that NSA did not bother to run this by any actual
lawyers, because the second and third paragraphs are only meaningful as
part of a license (ie something recipients agree to) and by definition
there is no license on public-domain software. They've given up
*everything*, including the right to make you agree to any terms of
distribution.

Not that anyone would likely be dumb enough to try to sue the NSA,
but it's still pretty funny.

regards, tom lane

#23Joshua D. Drake
jd@commandprompt.com
In reply to: Tom Lane (#22)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Mon, 17 Mar 2008 22:45:14 -0400
Tom Lane <tgl@sss.pgh.pa.us> wrote:

"Joshua D. Drake" <jd@commandprompt.com> writes:

Everything that I read says that libselinux is GPL.

What exactly did you read? The LICENSE file in the source tarball
says

I was reading a directory listing. I found the actual license file and
you are correct.

Not that anyone would likely be dumb enough to try to sue the NSA,
but it's still pretty funny.

One of those few entities on the planet that it just really doesn't
matter how much money you have. You don't sue them. In fact, NSA who?

Joshua D. Drake

- --
The PostgreSQL Company since 1997: http://www.commandprompt.com/
PostgreSQL Community Conference: http://www.postgresqlconference.org/
Donate to the PostgreSQL Project: http://www.postgresql.org/about/donate
PostgreSQL political pundit | Mocker of Dolphins

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFH3y31ATb/zqfZUUQRAgs/AKCJORQO+N4xfTeG6MXvhXFMn06DKwCfT33V
j8xTb5clqdPK3zWnA3XYuMQ=
=mVVu
-----END PGP SIGNATURE-----

#24Josh Berkus
josh@agliodbs.com
In reply to: KaiGai Kohei (#18)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai,

A flexible framework is worthwhile for both operating systems.
Please confirm it to the TS folks.

Yep, that's the idea. Glenn was fine with your stuff last year, I expect
it'll still be fine.

Other than SELinux and TrustedSolaris, does anyone know of other role-based or
multilevel security frameworks we should check against? I'd like to have any
security framework we approve be plug-in adaptable to everything out there.

--
Josh Berkus
PostgreSQL @ Sun
San Francisco

#25KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Gregory Stark (#16)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

Gregory Stark wrote:

"Greg Smith" <gsmith@gregsmith.com> writes:

On Mon, 17 Mar 2008, KaiGai Kohei wrote:

I'll submit the proposal of SE-PostgreSQL patches again, because some of previous
messages are filtered due to attachment and I cannot provide whole of patches yet.

This is actually what you should have done from the beginning. And it only
should have gone to the pgsql-hackers list, which is the only one I'm replying
to. Your patches are at this point a proposal, as you say in the subject, and
those go to the pgsql-hackers list with the minimum of files necessary to
support them. pgsql-patches is generally aimed at patches that have already
been discussed on the hackers list, ones that are basically ready to apply to
the source code.

Some people shout any time you send patches to -hackers. For the -patches is
there mainly to catch large attachments regardless of their maturity.

But it's true that it's best to post a plan and have discussion prior to
developing big patches.

Yes, it might be a better way to develop this feature on reflection.

I'm sorry that I could not submit a proposal by the feature freeze
date of v8.3 unfortunately, so the development of SE-PostgreSQL
(based on v8.2) is overlapped with development cycle of v8.3.

I don't want to repeat same thing twice, so these series of patches
are submitted fot v8.4 development cycle.
The first two of them ([1/4] and [2/4]) are significant part of
SE-PostgreSQL. We can discuss rest of them later. They contains
utility extension and security policy.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#26KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Josh Berkus (#24)
Re: [0/4] Proposal of SE-PostgreSQL patches

Josh Berkus wrote:

KaiGai,

A flexible framework is worthwhile for both operating systems.
Please confirm it to the TS folks.

Yep, that's the idea. Glenn was fine with your stuff last year, I expect
it'll still be fine.

Other than SELinux and TrustedSolaris, does anyone know of other role-based or
multilevel security frameworks we should check against? I'd like to have any
security framework we approve be plug-in adaptable to everything out there.

In the recent news,
http://www.sun.com/aboutsun/pr/2008-03/sunflash.20080313.1.xml

NSA and SUN announces a new project launched which tries to port FLASK
security architecture, it is named as FMAC.
It can be a good candidate to host multilevel database security.
(SELinux is also based on FLASK security architecture.)

SEBSD project is also known. It is a poring of SELinux into BSD platform.
SEBSD: http://www.trustedbsd.org/sebsd.html

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#27Josh Berkus
josh@agliodbs.com
In reply to: KaiGai Kohei (#26)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai,

NSA and SUN announces a new project launched which tries to port FLASK
security architecture, it is named as FMAC.
It can be a good candidate to host multilevel database security.
(SELinux is also based on FLASK security architecture.)

SEBSD project is also known. It is a poring of SELinux into BSD platform.
SEBSD: http://www.trustedbsd.org/sebsd.html

Keen. I'm sure Kathy's team understands all this. It's over my head. ;-)

--
Josh Berkus
PostgreSQL @ Sun
San Francisco

#28KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: KaiGai Kohei (#21)
Re: [PATCHES] [0/4] Proposal of SE-PostgreSQL patches

For easier reviewing, the most fundamental patch to implement PGACE (PostgreSQL
Access Control Extension) was separated into thress parts.

I want to start discussion about PGACE security framework at first.
Any comments are welcome.

[1/3] PGACE core features
http://sepgsql.googlecode.com/files/sepostgresql-8.4devel-pgace-1-core.r713.patch

It adds the following new files:
- src/include/security/pgace.h
declares all of PGACE related hooks and functions.
- src/backend/security/pgaceHooks.c
provides dummy functions to be invoked when no security modules are enabled.
They don't affect anything in access control.
- src/backend/security/pgaceCommon.c
provides common feature for every security modules, including security-attribute
system column support, SQL extention, functions to manage security-attribute of
large object.

[2/3] Security attribute system column
http://sepgsql.googlecode.com/files/sepostgresql-8.4devel-pgace-2-security-attr.r713.patch

Guest modules of PGACE can associate a security attribute with a tuple.
The guest module can utilize this to make its decision in access control.
(Unclassified users cannot access 'Secret' tuples, for example)
This attribute is stored in the padding field of HeapTupleHeaderData, as
oid doing. It requires additional "sizeof(Oid)" bytes to store it.

Users can refer this attribute via system column.
The name of new system column is defined as SECURITY_SYSATTR_NAME
at include/pg_config.h.in, and the guest module decide its name.
In SE-PostgreSQL, it is named as "security_context".

EXAMPLE of security attribute)
postgres=# SELECT security_context, * FROM drink;
security_context | id | name | price | alcohol
------------------------------------------+----+-------+-------+---------
unconfined_u:object_r:sepgsql_table_t:s0 | 1 | water | 100 | f
unconfined_u:object_r:sepgsql_table_t:s0 | 2 | coke | 120 | f
unconfined_u:object_r:sepgsql_table_t:s0 | 3 | juice | 130 | f
system_u:object_r:sepgsql_table_t:s0:c0 | 4 | cofee | 180 | f
system_u:object_r:sepgsql_table_t:s0:c0 | 5 | beer | 240 | t
system_u:object_r:sepgsql_table_t:s0:c0 | 6 | sake | 320 | t
(6 rows)

We can use this security attribute as a target of UPDATE or INSERT statement.
It enables DBA to manage security attribute with normal SQL operation.

[3/3] PGACE security hooks
http://sepgsql.googlecode.com/files/sepostgresql-8.4devel-pgace-3-security-hooks.r713.patch

This patch deploys several PGACE hooks on strategic points in PostgreSQL.
These hooks invoke a security module mounted on PGACE, and it can make its
decision whether this action should be allowed, or not.

The list of PGACE hooks at:
http://code.google.com/p/sepgsql/wiki/WhatIsPGACE
It shouws us more comprehensive specification about what kind of hooks are provided,
what informations are given and what value should be returned.

NOTE: I categorized patched files into three parts. However, some of them
contains security attribute system column facilities and PGACE hooks
facilities.
In this case, I categorized these files into part 2.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#29KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: KaiGai Kohei (#11)
Re: [0/4] Proposal of SE-PostgreSQL patches

I updated the series of SE-PostgreSQL patches for the latest pgsql-8.4devel tree.

[1/4] sepostgresql-pgace-8.4devel-3-r739.patch
provides PGACE (PostgreSQL Access Control Extension) framework.
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r739.patch

[2/4] sepostgresql-sepgsql-8.4devel-3-r739.patch
provides SE-PostgreSQL feature, based on PGACE framework.
http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r739.patch

[3/4] sepostgresql-pg_dump-8.4devel-3-r739.patch
enables to dump databases with security attribute.
http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r739.patch

[4/4] sepostgresql-policy-8.4devel-3-r739.patch
provides the default security policy of SE-PostgreSQL.
http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r739.patch

We provide a quick overview for SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

Thanks,

KaiGai Kohei wrote:

The series of patches are the proposal of Security-Enhanced PostgreSQL (SE-PostgreSQL)
for the upstreamed PostgreSQL 8.4 development cycle.

[1/4] sepostgresql-pgace-8.4devel-3.patch
provides PGACE (PostgreSQL Access Control Extension) framework
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r704.patch

[2/4] sepostgresql-sepgsql-8.4devel-3.patch
provides SE-PostgreSQL feature, based on PGACE framework.
http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r704.patch

[3/4] sepostgresql-pg_dump-8.4devel-3.patch
enables pg_dump to dump database with security attribute.
http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r704.patch

[4/4] sepostgresql-policy-8.4devel-3.patch
provides the default security policy for SE-PostgreSQL.
http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r704.patch

We can provide a quick overview for SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

ENVIRONMENT
-----------
Please confirm your environment.
The followings are requriements of SE-PostgreSQL.
* Fedora 8 or later system
* SELinux is enabled and working
* kernel-2.6.24 or later
* selinux-policy and selinux-policy-devel v3.0.8 or later
* libselinux, policycoreutils

INSTALLATION
------------
$ tar jxvf postgresql-snapshot.tar.bz2
$ cd postgresql-snapshot
$ patch -p1 < ../sepostgresql-pgace-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-sepgsql-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-pg_dump-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-policy-8.4devel-3.patch

$ ./configure --enable-selinux
$ make
$ make -C contrib/sepgsql-policy
$ su
# make install

# /usr/sbin/semodule -i contrib/sepgsql-policy/sepostgresql.pp
(NOTE: semodule is a utility to load/unload security policy modules.)

# /sbin/restorecon -R /usr/local/pgsql
(NOTE: restorecon is a utilicy to initialize security context of files.)

SETUP
-----
# mkdir -p /opt/sepgsql
# chown foo_user:var_group /opt/sepgsql
# chcon -t postgresql_db_t /opt/sepgsql
(NOTE: chcon is a utility to set up security context of files.)
# exit

$ /usr/sbin/run_init /usr/local/pgsql/bin/initdb -D /opt/sepgsql
(NOTE: run_init is a utility to start a program, as if it is branched from init script.)
$ /usr/local/pgsql/bin/pg_ctl -D /opt/sepgsql start

SUMMARYS FOR EVERY PATCHES
--------------------------
[1/4] - sepostgresql-pgace-8.4devel-3.patch

This patch provides PGACE (PostgreSQL Access Control Extension) framework.

It has a similar idea of LSM (Linu Security Module).
It can provide a guest module several hooks at strategic points.
The guest module can make its decision whether required actions should be
allowed, or not.
In addition, PGACE also provides falicilites to manage security attribute
of database objects. Any tuple can have a its security attribute, and the
guest module can refer it to control accesses.

A more conprehensive memo at:
http://code.google.com/p/sepgsql/wiki/WhatIsPGACE

[2/4] - sepostgresql-sepgsql-8.4devel-3.patch

This patch provides SE-PostgreSQL facilities based on PGACE.

Security-Enhanced PostgreSQL (SE-PostgreSQL) is a security extension
built in PostgreSQL, to provide system-wide consistency in access
controls. It enables to apply a single unigied security policy of
SELinux for both operating system and database management system.
In addition, it also provides fine-grained mandatory access which
includes column-/row- level non-bypassable access control even if
privileged database users.

Quick overview at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

[3/4] - sepostgresql-pg_dump-8.4devel-3.patch

This patch gives us a feature to dump database with security attribute.
It is turned on with '--enable-selinux' option at pg_dump/pg_dumpall,
when the server works as SE- version.
No need to say, users need to have enough capabilities to dump whole of
database. It it same when they tries to restore the database.

[4/4] - sepostgresql-policy-8.4devel-3.patch

This patch gives us the default security policy for SE-PostgreSQL.
You can build it as a security policy module. It can be linked with
the existing distributor's policy, and reloaded.

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#30Josh Berkus
josh@agliodbs.com
In reply to: KaiGai Kohei (#29)
Re: [0/4] Proposal of SE-PostgreSQL patches

Folks,

For hackers who don't understand security frameworks, I'm going to make a
strong case for KaiGai's patch. Because of my current presentation
series, I've been talking to PostgreSQL users about security features
around the world for the last several months, and there's a *lot* of
interest in security framework support. Not only are existing users
interested in it, but some potential users (security agencies, banks) who
didn't use PostgreSQL before have come to talk to me becuase of
SE-Postgres.

Further, I've asked the TrustedSolaris folks to take a look at KaiGai's
implementation to see if it was "generic" enough for them to build on as a
test of whether SE-Postgres was too specific to SE-Linux; the answer has
been a tentative "yes, it's generic".

So it would be much better to have this functionality be "mainstream"
rather than a fork. If it does get bounced, please do it becuase of code
quality and not because "nobody is asking for this".

Thanks!

--
--Josh

Josh Berkus
PostgreSQL @ Sun
San Francisco

#31Joshua D. Drake
jd@commandprompt.com
In reply to: Josh Berkus (#30)
Re: [0/4] Proposal of SE-PostgreSQL patches

Josh Berkus wrote:

Folks,

So it would be much better to have this functionality be "mainstream"
rather than a fork. If it does get bounced, please do it becuase of code
quality and not because "nobody is asking for this".

+1

Joshua D. Drake

#32Andrej Ricnik-Bay
andrej.groups@gmail.com
In reply to: Josh Berkus (#30)
Re: [0/4] Proposal of SE-PostgreSQL patches

On 01/05/2008, Josh Berkus <josh@agliodbs.com> wrote:

Further, I've asked the TrustedSolaris folks to take a look at KaiGai's
implementation to see if it was "generic" enough for them to build on as a
test of whether SE-Postgres was too specific to SE-Linux; the answer has
been a tentative "yes, it's generic".

So it would be much better to have this functionality be "mainstream"
rather than a fork. If it does get bounced, please do it becuase of code
quality and not because "nobody is asking for this".

Not a hacker, just a curious reader ... are there equivalent frameworks
for the other supported platforms? E.g. MacOS, *BSD, Windows? Are
the similarities between those (if they exist) close enough not to introduce
a maintenance nightmare?

Cheers,
Andrej

--
Please don't top post, and don't use HTML e-Mail :} Make your quotes concise.

http://www.american.edu/econ/notes/htmlmail.htm

#33Greg Smith
gsmith@gregsmith.com
In reply to: Andrej Ricnik-Bay (#32)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Thu, 1 May 2008, Andrej Ricnik-Bay wrote:

Not a hacker, just a curious reader ... are there equivalent frameworks
for the other supported platforms? E.g. MacOS, *BSD, Windows?

SELinux is a Linux implementation of ideas from an earlier NSA project
named Flask. There is port of another variant of that, Flask/TE, that is
making its way into the BSD variants via a project called SEBSD.
TrustedBSD, Darwin (OS X), and OpenSolaris all have projects in this area
already (the Solaris one just launched last month). A good starter page
is http://www.trustedbsd.org/sebsd.html

Particularly given the common heritage, I suspect that the PostgreSQL side
of all these projects will be similar, and that once those hooks are in
place it will just be a matter of tying them into the higher levels of the
other framework. It would be too ambitious to target all of them all at
once for a first pass, but it may be worth a look at the fundamentals of
SEBSD to make sure the right hooks look like they're in place.

Windows has this thing called "Group Policy" that's supposedly leaped
forward for Windows Server 2008. They are now advertising it as like
SELinux, but better. The presentation PDF I just read on that subject
sounds like something written by the crazy guy at Broadway & 57th street I
used to walk by, as he talked on fruit as if they were his cell phone.
It's such a deluded and wildly misguided bit of sales fluff that you can't
take it seriously, and the whole thing just leaves me feeling sorry for
them instead.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#34Greg Smith
gsmith@gregsmith.com
In reply to: KaiGai Kohei (#29)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Wed, 30 Apr 2008, KaiGai Kohei wrote:

[1/4] sepostgresql-pgace-8.4devel-3-r739.patch
provides PGACE (PostgreSQL Access Control Extension) framework.
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r739.patch

For those overwhelmed by sheer volume here, this is the patch to start
with, because it's got all the core changes to the server. I'm also in
the camp that would like to see this feature added, but rather than just
giving it a +1 I started looking at it.

The overall code is nice: easy to understand, structured modularly. I
have some concerns though. The first two things that jump out at me on an
initial review appear right from the beginning for those who want to take
a look:

-I'm a bit unnerved by both the performance and reliability implications
from how the security check calls are done in every case, even if there is
no SELinux support included. Those checks are sitting in some pretty low
level tuple and heap calls.

The approach taken here is to put all the "#ifdef" logic into the
underlying ACE interface (see patch [2/4]), so that the caller doesn't
have to care. If SELinux support is off then the calls turns into

void x(y) {} or
bool a(b) { return true; }

This is a very clean design, but it's putting extra (possibly optimized
away) calls into a lot of places. While it would be uglier, it might make
sense to put that on/off logic in all the places where the calls are made,
so that when you turn SELinux support off most of the code really does go
completely away rather than just turning into stubs.

-The only error reporting and handling method used is "elog(ERROR,...".
That seems a bit heavy handed for something that can be expected to happen
all the time.

If I understand this correctly, when you're scanning a table with 1000
rows where you're only allowed to see 50% of them, that's going to be 500
call to elog(), one for each tuple you can't see. Having a tuple get
screened out isn't really an error per se, and while I can see how
sensitive installs would want those all reported there are others where
this volume of log activity would be too much. Just because someone with
classified clearance is looking at a big table that also has a lot of
secret info in it, not all installs will want a million errors reported
just because there's data that person can't see available.

At a minimum, this needs some finer log control, and maybe a rethinking
altogether of how to handle error cases.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#35Gregory Stark
stark@enterprisedb.com
In reply to: Greg Smith (#34)
Re: [0/4] Proposal of SE-PostgreSQL patches

"Greg Smith" <gsmith@gregsmith.com> writes:

The approach taken here is to put all the "#ifdef" logic into the underlying
ACE interface (see patch [2/4]), so that the caller doesn't have to care. If
SELinux support is off then the calls turns into

void x(y) {} or
bool a(b) { return true; }

This is a very clean design, but it's putting extra (possibly optimized away)
calls into a lot of places. While it would be uglier, it might make sense to
put that on/off logic in all the places where the calls are made, so that when
you turn SELinux support off most of the code really does go completely away
rather than just turning into stubs.

It's nicer to do it the way they have but we don't generally trust compilers
to inline functions. Is it hard to make those functions into macros?

-The only error reporting and handling method used is "elog(ERROR,...". That
seems a bit heavy handed for something that can be expected to happen all the
time.

If I understand this correctly, when you're scanning a table with 1000 rows
where you're only allowed to see 50% of them, that's going to be 500 call to
elog(), one for each tuple you can't see. Having a tuple get screened out
isn't really an error per se, and while I can see how sensitive installs would
want those all reported there are others where this volume of log activity
would be too much. Just because someone with classified clearance is looking
at a big table that also has a lot of secret info in it, not all installs will
want a million errors reported just because there's data that person can't see
available.

I don't understand, if it's ERROR it would throw an error and stop the current
query. Or is this all within a PG_TRY() ?

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com
Ask me about EnterpriseDB's RemoteDBA services!

#36KaiGai Kohei
kaigai@kaigai.gr.jp
In reply to: Greg Smith (#34)
Re: [0/4] Proposal of SE-PostgreSQL patches

Greg Smith wrote:

On Wed, 30 Apr 2008, KaiGai Kohei wrote:

[1/4] sepostgresql-pgace-8.4devel-3-r739.patch
provides PGACE (PostgreSQL Access Control Extension) framework.

http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r739.patch

For those overwhelmed by sheer volume here, this is the patch to start
with, because it's got all the core changes to the server. I'm also in
the camp that would like to see this feature added, but rather than just
giving it a +1 I started looking at it.

The overall code is nice: easy to understand, structured modularly. I
have some concerns though. The first two things that jump out at me on
an initial review appear right from the beginning for those who want to
take a look:

Thanks for your attention & reviewing.

-I'm a bit unnerved by both the performance and reliability implications
from how the security check calls are done in every case, even if there
is no SELinux support included. Those checks are sitting in some pretty
low level tuple and heap calls.

The approach taken here is to put all the "#ifdef" logic into the
underlying ACE interface (see patch [2/4]), so that the caller doesn't
have to care. If SELinux support is off then the calls turns into

void x(y) {} or
bool a(b) { return true; }

This is a very clean design, but it's putting extra (possibly optimized
away) calls into a lot of places. While it would be uglier, it might
make sense to put that on/off logic in all the places where the calls
are made, so that when you turn SELinux support off most of the code
really does go completely away rather than just turning into stubs.

Your concern is fair enough. I indeed used inline function to avoid unnecessary
invokation in the previous version, as follows:
http://code.google.com/p/sepgsql/source/browse/branches/pgsql-8.2.x/sepgsql/src/include/security/pgace.h

However, I changed this design, because it requires any security modules
have to provides its implementation for any hooks, including just a stub.
In the current design, author of another security modules can leave unused
hooks unchanged. It improves code maintenancability.

But an inspiration hit me just now.
If we declare any hooks as static inline functions which includes #ifdef
block, it can resolve these matters as follows:
---- EXAMPLE ----
static inline bool pgaceHeapTupleInsert(Relation rel, HeapTuple tuple,
bool is_internal, bool with_returning) {
#ifdef HAVE_SELINUX
if (sepgsqlIsEnabled())
return sepgsqlHeapTupleInsert(rel, tuple, is_internal, with_returning);
#endif
return true;
}
----------------
Is it reasonable idea?

-The only error reporting and handling method used is "elog(ERROR,...".
That seems a bit heavy handed for something that can be expected to
happen all the time.

SE-PostgreSQL invokes "elog(ERROR,...", when a given query tries to access
violated columns, tables and so on, but not for each tuple.

In row-level access controls, it filters violated tuples without aborting
query execution. However, "elog(NOTICE,..." can be invoked, if the security
policy requires to generate access denied logs on row-level.

If I understand this correctly, when you're scanning a table with 1000
rows where you're only allowed to see 50% of them, that's going to be
500 call to elog(), one for each tuple you can't see.

The security policy can control whether access denied logs should be
printed, or not.
In the default security policy provided by the patch [4/4], row-level
access denied logs are disabled to avoid flood of logs as you noticed.

If you want to turn on/off row-level logs, use the following command:
# setsebool -P sepgsql_enable_audittuple=(1|0)
It changes the internal state of security policy, and SE-PostgreSQL
works according to this one.

Having a tuple
get screened out isn't really an error per se, and while I can see how
sensitive installs would want those all reported there are others where
this volume of log activity would be too much. Just because someone
with classified clearance is looking at a big table that also has a lot
of secret info in it, not all installs will want a million errors
reported just because there's data that person can't see available.

At a minimum, this needs some finer log control, and maybe a rethinking
altogether of how to handle error cases.

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

#37Tom Lane
tgl@sss.pgh.pa.us
In reply to: KaiGai Kohei (#29)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

I updated the series of SE-PostgreSQL patches for the latest pgsql-8.4devel tree.

I tried to do a bit of testing of this, but it does not work on current
Fedora 8, because the policy module doesn't build:

[tgl@rh2 sepgsql-policy]$ make
make -f /usr/share/selinux/devel/Makefile NAME=targeted
make[1]: Entering directory `/home/tgl/sepgsql/contrib/sepgsql-policy'
Compiling targeted sepostgresql module
/usr/bin/checkmodule: loading policy configuration from tmp/sepostgresql.tmp
sepostgresql.te:349:ERROR 'syntax error' at token 'corenet_tcp_recvfrom_labeled' on line 5675:
# NOTE: These changes are to be merged in the later releases.
corenet_tcp_recvfrom_labeled(sepgsql_server_type, sepgsql_client_type)
/usr/bin/checkmodule: error(s) encountered while parsing configuration
make[1]: *** [tmp/sepostgresql.mod] Error 1
make[1]: Leaving directory `/home/tgl/sepgsql/contrib/sepgsql-policy'
make: *** [sepostgresql.pp] Error 2
[tgl@rh2 sepgsql-policy]$

In the meantime, here are some random comments after my failed test
build and a very fast scan through the patch:

The patch tries to re-add ipcclean to the source tree --- probably a
merge error?

autoconf complains about the description-free AC_DEFINEs

Doesn't compile warning-free if selinux not enabled ... for that matter,
it doesn't compile warning-free if selinux IS enabled.

No documentation updates whatsoever :-(

About half of the patch seems to be conditional on
#ifdef SECURITY_SYSATTR_NAME
and the other half on
#ifdef HAVE_SELINUX
This seems bizarre: is there really any chance that there are two
independently usable chunks of code here? And why is it conditional
on a macro that is a field name, rather than conditional on a feature
macro? That is, I'd expect to see something like
#ifdef ENABLE_SEPOSTGRES
throughout.

For that matter, what is the point of treating SECURITY_SYSATTR_NAME
as a configurable thing in the first place? I can hardly imagine a
worse idea than a security-critical column having different names in
different installations.

The patch hasn't got a mode in which SELinux support is compiled in but
not active. This is a good way to ensure that no one will ever ship
standard RPMs with the feature compiled in, because they will be entirely
nonfunctional for people who aren't interested in setting up SELinux.
I think you need an "enable_sepostgres" GUC, or something like that.
(Of course, the overhead of the per-row security column would probably
discourage anyone from wanting to use such a configuration anyway,
so maybe the point is moot.)

sepgsql-policy has got usability problems:
* It should pay attention to the configured installation PREFIX instead of
hardwiring a couple of random possible installation locations
* It can only support the build machine's SELINUXTYPE --- how am I supposed
to produce RPMs that support all available types?

The contents and use of sepgsqlGetTupleName() make it look like the
entire security scheme is based on object name alone. That doesn't
even account for schemas, let alone overloaded function names. Please
tell me this is not as broken-by-design as it looks.

I occasionally tell people "try to make the patch look like it's always
been there". This is pretty far from meeting that goal. Random bits
of code that are commented "PGACE:" are obviously not intended to just
fit in. You've generally ignored the Postgres code layout conventions
(pgindent will help to some extent but it's far from a panacea) and our
commenting conventions --- eg, hardly any of the functions have header
comments, and the ones that do follow conventions seen noplace in the
Postgres code, like using "@" on parameter names. In general the number
and quality of the comments is far below the standard for Postgres code,
and the lack of any implementation documentation isn't helping.

Another big problem, which I understand your motivation for but that
doesn't make the code any less ugly, is that you've got trivial bits
of code that're separated by two(!) levels of hook calls from where
they're actually being used. Not only does that make it unreadable
but the files that actually do the work combine bits of code that
should be scattered across a lot of modules, causing those files to
be just horrid from a modularity standpoint --- they've got their
fingers stuck in everyplace. If you want this to get applied you need
to start thinking of it as an integral part of the code, not an add-on.

Some other bits of add-on-itis:
* If you need a dedicated LWLock, declare it in lwlock.h.
* If you need a node type, declare it in nodes.h (T_SEvalItem is utterly
broken)

Why in the world would you have security restrictions associated with
TOAST tuples? Seems like all the interesting restrictions should be
on the parent table.

Don't randomly invent your own style of management of a postmaster
child process. For one thing, this code doesn't cope with either
unexpected death of the postmaster or unexpected death of the child.
If you need another child, manage it in postmaster.c the same way
the other children are managed.

The code in hooks.c looks suspiciously not-HOT-aware, eg use of
ItemIdIsUsed() for what probably needs to be ItemIdIsNormal().
(Not that this code ought to be fetching the tuple for itself
in the first place --- probable big performance loss there...)

pgaceHooks.c seems to be a useless layer of indirection
--- lose it all, and inline into callers instead.

Is the hard-wired shmem cache size really adequate? Why are you
using such a cache in shared memory at all, rather than backend-local?
The locking implications likely take away more performance than you
save by not having each session need to load up its cache.
(We don't use shared catalog caches, in general.)

If we're going to support assignment to system columns, we probably
want a general solution that will work for OID not only the security
column. Also, I'm unconvinced that setting resjunk = true for such
targetlist entries is a good idea.

The whole "early security" business looks like a mess :-(. I suspect
you should rip all that out of the backend and add a step to initdb
that fills in those tables.

The idea of input functions that alter system tables scares me.

elog() should not be used for user-facing errors. I couldn't easily
tell just which of the messages are likely to be seen by users and
which ones should be "can't happen" cases, but certainly there are
a whole lot of these that need to be ereport()s. Likely there need
to be some new ERRCODEs too.

__lookupRelationForm() strikes me as a complete crock. It probably
means that you've selected the wrong places to call its callers from.
This gets back to the point above that adding additional fetches of
tuples isn't good for performance anyway.

Don't use identifiers with a leading double-underscore. These are
reserved for system-private identifiers according to the C standard.

Use of a function in genbki.sh is very likely not portable.

use of flock() is probably not portable and even less probably necessary.

Declaring a function foo() rather than foo(void) is poor style ---
at least some compilers will complain about that.

I see a lot of "Copyright 2007 KaiGai Kohei" notices. Are you
willing to assign those copyrights to the Postgres Global Development
Group? If not, we'll at least need statements along the line of
"Distributed under the PostgreSQL license".

regards, tom lane

#38Greg Smith
gsmith@gregsmith.com
In reply to: Tom Lane (#37)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Mon, 5 May 2008, Tom Lane wrote:

elog() should not be used for user-facing errors. I couldn't easily
tell just which of the messages are likely to be seen by users and
which ones should be "can't happen" cases, but certainly there are
a whole lot of these that need to be ereport()s. Likely there need
to be some new ERRCODEs too.

And it would be a nice step toward the scenarios I was asking about if
there was a GUC variable for what level to log security violations at. I
realize now the tuple-level warnings are going into the SELinux logs
rather than the PostgreSQL ones, but it should be easier to change policy
violations that impact the server to something other than just ERROR.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#39Tom Lane
tgl@sss.pgh.pa.us
In reply to: Josh Berkus (#30)
Re: [0/4] Proposal of SE-PostgreSQL patches

Josh Berkus <josh@agliodbs.com> writes:

For hackers who don't understand security frameworks, I'm going to make a
strong case for KaiGai's patch.
...
So it would be much better to have this functionality be "mainstream"
rather than a fork. If it does get bounced, please do it becuase of code
quality and not because "nobody is asking for this".

Well, let's be perfectly blunt here: this is an extremely sizable patch
that will be of interest to less than 1% of our users (and I think I'm
being generous in that estimate). If it's going to get in, it's going
to have to not cost us anything much on reliability, maintainability,
or performance --- rank those however you please, there is someone out
there who will be most interested in any one of them.

My look at the code today convinced me that it's not going to get
applied without a whole lot of further work. I think what we must
figure out in this commit-fest is whether to encourage KaiGai to start
doing that work, or to decide that it probably is a dead issue and he
shouldn't bother.

As to reliability: the issue that worries me the most was already raised
by Greg Smith --- this patch puts security checks and consequent catalog
lookups into some mighty low-level places that IMHO have no business
triggering catalog accesses. If I'd been able to make the patch work
today, I'd have tested whether it could get through the regression tests
with CLOBBER_CACHE_ALWAYS defined. I'd be happier if it were refactored
to put the security checks only into executor code paths, and not try to
enforce security restrictions against the system itself. (Thought
experiment: what happens if SELinux denies access to a row of
pg_security to the code that is supposed to be checking security?
Or try this one: it looks to me like you can set up the system to
pretend to some user that the pg_class rows for certain indexes don't
exist, even though he has update rights on their parent table. Instant
index corruption.)

As to maintainability: I already posted a lot of unhappy remarks on code
style and readability. I don't think there's anything unfixable there,
but there's a lot of work to do to convert what was evidently written as
an arms-length add-on into a sensible part of core Postgres.

As to performance: frankly, I'm afraid the performance is abysmal.
This was what I was mainly hoping to check out if I could have gotten
it to build today. We need to at least get some rough pgbench readings
before deciding whether it's worth pushing forward.

regards, tom lane

#40Tom Lane
tgl@sss.pgh.pa.us
In reply to: Tom Lane (#37)
Re: [0/4] Proposal of SE-PostgreSQL patches

I wrote:

I tried to do a bit of testing of this, but it does not work on current
Fedora 8, because the policy module doesn't build:

I got past that by commenting out the last few lines of sepostgresql.te,
which apparently are intended for some SELinux feature that's not
shipped yet in F8.

After that, and a whole bunch of foolery with manually putting the right
security labels on files (because the contrib module is unhelpful for
test installations with nonstandard PREFIXes), I managed to get a
version that worked well enough to test. What I found out:

* It does not come close to passing the regression tests. I saw a lot of
! ERROR: unrecognized node type: 903
which suggests that something's been screwed up about parse analysis
(903 = T_A_Const, which shouldn't get further than parse analysis),
and it dumps core in the TRUNCATE test.

* pgbench shows a relatively marginal speed difference, which is not
too surprising since it pushes only a few tuples around per query.
The worst case for sepostgres is likely to be bulk operations.
I tried "select count(*) from accounts" (at scale factor 20, so this
is 2000000 tuples) and got about 550 msec from CVS HEAD, about
1340 msec from HEAD plus patch. That's with no actual useful policy
loaded, mind you.

So the overhead is indeed pretty bad, but it seems reasonable to think
that with some optimization effort it could be brought down to where
it'd be acceptable for people who really need the feature.

AFAICS the only thing left that really needs to be discussed more during
this commit-fest is the business about whether it's sane to be trying to
apply selinux restrictions in simple_heap_update and friends. The more
I think about that the more I think it's simply a bad idea. Those
functions are used primarily (if not solely) for system-initiated
catalog updates, and I fail to see any plausible reason to let
user-written policy be applied at that level. For instance, it would
be a completely bad move to allow such policy to prevent autovacuum
from updating relfrozenxid values. Furthermore, those functions are
much too low-level to have any idea of the reason for the change they
are being asked to make, so they can't apply any intelligence to the
allow-or-not decision. Lastly, I don't see any use-case for policy there
that wouldn't be served as well or better by the standard SQL privilege
mechanism. So I think that really all needs to be ripped out, and
do enforcement in the executor instead.

regards, tom lane

#41Andrew Sullivan
ajs@commandprompt.com
In reply to: Tom Lane (#40)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Tue, May 06, 2008 at 02:56:41PM -0400, Tom Lane wrote:

AFAICS the only thing left that really needs to be discussed more during
this commit-fest is the business about whether it's sane to be trying to
apply selinux restrictions in simple_heap_update and friends.

I don't have any opinion about the patches, obviously, but I'm
wondering whether there is, somewhere, an outline of what the _goals_
of this system are. If we have requirements that we can measure the
implementation against, we can know whether to throw away a particular
goal as being basically incompatible with the design of Postgres
(i.e. not an "enhancement" but a "reconception") or else as being
implementable with another approach.

A

--
Andrew Sullivan
ajs@commandprompt.com
+1 503 667 4564 x104
http://www.commandprompt.com/

#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Sullivan (#41)
Re: [0/4] Proposal of SE-PostgreSQL patches

Andrew Sullivan <ajs@commandprompt.com> writes:

I don't have any opinion about the patches, obviously, but I'm
wondering whether there is, somewhere, an outline of what the _goals_
of this system are.

The only documentation I've seen is

http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

which contains only examples of enforcing restrictions on *user*
queries and tables.

regards, tom lane

#43Andrew Sullivan
ajs@commandprompt.com
In reply to: Tom Lane (#42)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Tue, May 06, 2008 at 03:28:25PM -0400, Tom Lane wrote:

The only documentation I've seen is

http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

which contains only examples of enforcing restrictions on *user*
queries and tables.

I agree that, having just read that, anything that involves itself
with the system catalogues and such is way overstepping the stated
design goal.

There is an issue in most high-security systems having to do with
side-channel leakage of supposedly sensitive data. So, the mere
exsistence of certain tables, columns, or users might be regarded as
security-sensitive data. I'm not sure I see how to get around that
without mucking in the areas that are causing some of the trouble.

But I think before we get into that discussion, a fairly clear
statement of exactly which problems are going to be in scope is
needed.

FWIW, I support and think important the row- and column- level access
controls this seems to be proposing, at least in principle. Whether
that's a support that will extend to 2x overhead on everything is
rather a different matter. Also, I am more than prepared to trade
away some cases in order to get a broadly useful functionality (so if
you can't hide the existence of a table, but all efforts to learn its
contents don't work, I might be willing to support that trade-off).

A

--
Andrew Sullivan
ajs@commandprompt.com
+1 503 667 4564 x104
http://www.commandprompt.com/

#44Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Sullivan (#43)
Re: [0/4] Proposal of SE-PostgreSQL patches

Andrew Sullivan <ajs@commandprompt.com> writes:

There is an issue in most high-security systems having to do with
side-channel leakage of supposedly sensitive data. So, the mere
exsistence of certain tables, columns, or users might be regarded as
security-sensitive data. I'm not sure I see how to get around that
without mucking in the areas that are causing some of the trouble.

Well, the setup that I suggested would still allow people to set
restrictions that would prevent *user* queries from seeing rows in the
system catalogs. I'm not sure that's a good idea either --- pg_dump,
meet foot gun --- but at least it can't corrupt the functioning of the
server itself.

But I think before we get into that discussion, a fairly clear
statement of exactly which problems are going to be in scope is
needed.

Agreed, that would help.

FWIW, I support and think important the row- and column- level access
controls this seems to be proposing, at least in principle. Whether
that's a support that will extend to 2x overhead on everything is
rather a different matter. Also, I am more than prepared to trade
away some cases in order to get a broadly useful functionality (so if
you can't hide the existence of a table, but all efforts to learn its
contents don't work, I might be willing to support that trade-off).

Yeah, that's something that we need to think about too. ISTM that this
patch's proposed restrictions on SQL object access are largely
duplicative of SQL-standard access permissions, and they'll become more
so if the pending patch to implement SQL column permissions gets in.
I think a good case could be made for throwing out all of that and using
the SELinux code only for row-level filtering.

(And of course the next question after that is why we should want to
depend on SELinux at all, rather than implementing row filtering
in the framework of SQL permissions...)

regards, tom lane

#45Greg Smith
gsmith@gregsmith.com
In reply to: Tom Lane (#44)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Tue, 6 May 2008, Tom Lane wrote:

And of course the next question after that is why we should want to
depend on SELinux at all, rather than implementing row filtering in the
framework of SQL permissions...

It may be the case that clean row and column filtering at the SQL layer
are pre-requisites for a clean SELinux implementation, where the only
difference is that the permission checks are handled by asking SELinux
instead of looking in the catalog.

As for why SQL restrictions alone aren't enough...the simple answer is
because it's not SELinux, which I say in all seriousness because it is
turning into a requirement in some places.

SELinux lets you control what a user login is capable of no matter what
application they run, and managing those capabilities can happen in one
place--the SELinux tools. There's lots of ways to address OS login
problems. Let's say the logins have a PAM plug-in that restrict what you
can login to based on what machine you're on, and also require one of
those randomly generating key cards so that you can't steal someone else's
username/password. If you've got a scheme like that, and the database
enforces SELinux restrictions, it doesn't matter whether your DBA followed
all the PostgreSQL security rules correctly, as long as they got the
SELinux mapping part right. And you don't have to make sure whatever
custom security mechanism you've integrated into the login or post-login
process is recognized by the database proper at all, as long as the
restrictions can be mapped to the SELinux+database space.

Simple example of something hard to replicate without this framework:
you discover someone is a rat. You update your list of active users and
push that to all your servers. Now even if said rat is already logged
into the database server and busy doing 'psql -o /disk/usbkey -c "select *
from secretdata"' you just cut them off in the middle of the
query--without needing to find all the database servers and execute "alter
table secretdata set ...", just by doing simple user account maintenance
the way people are already comfortable with and have procedures for.

That's the basic idea here--put the authorization into one layer where
it's easy (for some definitions of "easy") to manage and extensible as
needed, without having to touch the individual applications directly, just
by adjusting what permissions you publish when data is requested. I'm
sure someone can raise issues or suggest alternate implemenations for my
specific examples, but much like other privledge escalation defense
mechanisms these environments look for redundant layers of security. In
reality users of this would aim for a completely locked down base
PostgreSQL *and* a completely locked down SELinux implementation
integrated into that, reinforcing one another, rather than just relying on
one level of security.

--
* Greg Smith gsmith@gregsmith.com http://www.gregsmith.com Baltimore, MD

#46KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#37)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom, Thanks for your reviewing.

Tom Lane wrote:

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

I updated the series of SE-PostgreSQL patches for the latest pgsql-8.4devel tree.

I tried to do a bit of testing of this, but it does not work on current
Fedora 8, because the policy module doesn't build:

[tgl@rh2 sepgsql-policy]$ make
make -f /usr/share/selinux/devel/Makefile NAME=targeted
make[1]: Entering directory `/home/tgl/sepgsql/contrib/sepgsql-policy'
Compiling targeted sepostgresql module
/usr/bin/checkmodule: loading policy configuration from tmp/sepostgresql.tmp
sepostgresql.te:349:ERROR 'syntax error' at token 'corenet_tcp_recvfrom_labeled' on line 5675:
# NOTE: These changes are to be merged in the later releases.
corenet_tcp_recvfrom_labeled(sepgsql_server_type, sepgsql_client_type)
/usr/bin/checkmodule: error(s) encountered while parsing configuration
make[1]: *** [tmp/sepostgresql.mod] Error 1
make[1]: Leaving directory `/home/tgl/sepgsql/contrib/sepgsql-policy'
make: *** [sepostgresql.pp] Error 2
[tgl@rh2 sepgsql-policy]$

This policy can be built on Fedora 9 or rawhide now.
The latest selinux-policy on Fedora 8 does not contain labeled networking
interfaces, so it makes errors.

FYI,
I also have a discussion to merge the SE-PostgreSQL security policy module
into the default upstreamed policy (called as reference policy).
http://marc.info/?t=120574668300001&amp;r=1&amp;w=2

I guess it will be merged former than the release date of PostgreSQL v8.4,
so it may not be necessary to include it within contrib/ .

In the next patch set, I like to provide it with different form.

In the meantime, here are some random comments after my failed test
build and a very fast scan through the patch:

The patch tries to re-add ipcclean to the source tree --- probably a
merge error?

I don't intend to modify ipcclean.
It is a bug in patch generation scripts, to be fixed soon.

autoconf complains about the description-free AC_DEFINEs

OK, I add the following descriptions for my AC_DEFINEs.

AC_DEFINE(SECURITY_SYSATTR_NAME, "security_context",
[Enables system column for security attribute support])
AC_DEFINE_UNQUOTED(HAVE_SELINUX, 1,
[Enables SE-PostgreSQL feature])

Doesn't compile warning-free if selinux not enabled ... for that matter,
it doesn't compile warning-free if selinux IS enabled.

Does it mean you run configure script without --enable-selinux?
I also confirmed some warnings to be fixed in the next patch set.
Or, is selinux disabled on your workstation?

No documentation updates whatsoever :-(

OK, I'll add a new documentation at doc/src/sgml .
Is it your intention, isn't it?

About half of the patch seems to be conditional on
#ifdef SECURITY_SYSATTR_NAME
and the other half on
#ifdef HAVE_SELINUX
This seems bizarre: is there really any chance that there are two
independently usable chunks of code here? And why is it conditional
on a macro that is a field name, rather than conditional on a feature
macro? That is, I'd expect to see something like
#ifdef ENABLE_SEPOSTGRES
throughout.

SECURITY_SYSATTR_NAME is a name of security attribute system column,
and used to enable/disable this feature provided by PGACE.
I think PGACE has possible users more than SELinux, like Solaris TX.
Applying separated symbols are worthwhile when a new security module
requires security attribute but it is not SELinux.

For that matter, what is the point of treating SECURITY_SYSATTR_NAME
as a configurable thing in the first place? I can hardly imagine a
worse idea than a security-critical column having different names in
different installations.

SECURITY_SYSATTR_NAME is defined as "security_context" in SE-PostgreSQL.
However, it is a special term of SELinux.
If we can agree this name, we don't have to abstract the name of security
attribute system column.

The patch hasn't got a mode in which SELinux support is compiled in but
not active. This is a good way to ensure that no one will ever ship
standard RPMs with the feature compiled in, because they will be entirely
nonfunctional for people who aren't interested in setting up SELinux.
I think you need an "enable_sepostgres" GUC, or something like that.
(Of course, the overhead of the per-row security column would probably
discourage anyone from wanting to use such a configuration anyway,
so maybe the point is moot.)

We can turn on/off SELinux globally, not bounded to SE-PostgreSQL.
The reason why I didn't provide a mode bit like "enable_sepostgresql"
is to keep consistency in system configuration.
It is undesirable situation to disable SELinux on a partial inter-process
communication channels.

BTW, what does it mean the overhead of the per-row security column?
When SELinux is disabled, it is not labeled and does not consume any
additional spaces.

sepgsql-policy has got usability problems:
* It should pay attention to the configured installation PREFIX instead of
hardwiring a couple of random possible installation locations
* It can only support the build machine's SELINUXTYPE --- how am I supposed
to produce RPMs that support all available types?

As noted above, I'll provide its security policy in a different way.
The hardcoded parameters are also changed to configurable ones.

The contents and use of sepgsqlGetTupleName() make it look like the
entire security scheme is based on object name alone. That doesn't
even account for schemas, let alone overloaded function names. Please
tell me this is not as broken-by-design as it looks.

The result of sepgsqlGetTupleName() is used to generate access denied
logs as a name of target object, not used to access controls.

I occasionally tell people "try to make the patch look like it's always
been there". This is pretty far from meeting that goal. Random bits
of code that are commented "PGACE:" are obviously not intended to just
fit in. You've generally ignored the Postgres code layout conventions
(pgindent will help to some extent but it's far from a panacea) and our
commenting conventions --- eg, hardly any of the functions have header
comments, and the ones that do follow conventions seen noplace in the
Postgres code, like using "@" on parameter names. In general the number
and quality of the comments is far below the standard for Postgres code,
and the lack of any implementation documentation isn't helping.

OK, I'll improvement coding style, comments and so on.

Another big problem, which I understand your motivation for but that
doesn't make the code any less ugly, is that you've got trivial bits
of code that're separated by two(!) levels of hook calls from where
they're actually being used. Not only does that make it unreadable
but the files that actually do the work combine bits of code that
should be scattered across a lot of modules, causing those files to
be just horrid from a modularity standpoint --- they've got their
fingers stuck in everyplace. If you want this to get applied you need
to start thinking of it as an integral part of the code, not an add-on.

I thought small patches help reviewer check it comfortably.
However, it is unwelcome style...
I'll update the next patch without separating both features.

Some other bits of add-on-itis:
* If you need a dedicated LWLock, declare it in lwlock.h.
* If you need a node type, declare it in nodes.h (T_SEvalItem is utterly
broken)

OK, I'll move them.

Why in the world would you have security restrictions associated with
TOAST tuples? Seems like all the interesting restrictions should be
on the parent table.

sepgsqlHeapTuple*() hooks are also invoked for tuples within TOAST tables,
but it does not apply any restriction. When given tuple is belong to
TOAST tables, SE-PostgreSQL skips its checks.

Don't randomly invent your own style of management of a postmaster
child process. For one thing, this code doesn't cope with either
unexpected death of the postmaster or unexpected death of the child.
If you need another child, manage it in postmaster.c the same way
the other children are managed.

OK,

The code in hooks.c looks suspiciously not-HOT-aware, eg use of
ItemIdIsUsed() for what probably needs to be ItemIdIsNormal().
(Not that this code ought to be fetching the tuple for itself
in the first place --- probable big performance loss there...)

Does GetTupleForTrigger() help me as a sample to obtain the older
version of tuple on the hooks of simaple_heap_update()?

pgaceHooks.c seems to be a useless layer of indirection
--- lose it all, and inline into callers instead.

OK, I'll push them into inline function and remove pgaceHooks.c.

Is the hard-wired shmem cache size really adequate? Why are you
using such a cache in shared memory at all, rather than backend-local?
The locking implications likely take away more performance than you
save by not having each session need to load up its cache.
(We don't use shared catalog caches, in general.)

I think caches of security policy should be placed on shared memory.
If backend held it locally, it requires some system call invokations
per connection at least, although the security policy is seldom reloaded.
However, we have to invalidate the cache when it is reloaded.
If every backend have its cache, cache invalidation will be a uneasy task.

If we're going to support assignment to system columns, we probably
want a general solution that will work for OID not only the security
column. Also, I'm unconvinced that setting resjunk = true for such
targetlist entries is a good idea.

OK, it is possible to expand.
However, why are you unconvinced for setting resjunk = true, when users
try to update system column? I think it is a reasonable way to compute
right hand of terms, like:
UPDATE foo SET security_context = security_context::text || ':Classified' ...

The whole "early security" business looks like a mess :-(. I suspect
you should rip all that out of the backend and add a step to initdb
that fills in those tables.

I also think "early security" codes are ad-hoc. :-(
Pushing it into initdb seems me a good idea.
I'll try to consider whether it is possible, or not.

The idea of input functions that alter system tables scares me.

Are you saying about pg_security system catalog?

elog() should not be used for user-facing errors. I couldn't easily
tell just which of the messages are likely to be seen by users and
which ones should be "can't happen" cases, but certainly there are
a whole lot of these that need to be ereport()s. Likely there need
to be some new ERRCODEs too.

OK, I'll replace elog() by ereport().
Is adding a new error code (ERRCODE_SECURITY_VIOLATION) in Class XX appropriate?

__lookupRelationForm() strikes me as a complete crock. It probably
means that you've selected the wrong places to call its callers from.
This gets back to the point above that adding additional fetches of
tuples isn't good for performance anyway.

The purpose of __lookupRelationForm() is to obtain the HeapTuple of
parent relation when new attributes are inserted into pg_attribute
system catalog.
But we cannot refer the tuple of parent table because CommandCounterIncrement()
are not invoked between inserting a tuple into pg_class and pg_attribute.

Is there any good idea to refer a tuple of parent table just before
tuples are inserted into pg_attribute?

Don't use identifiers with a leading double-underscore. These are
reserved for system-private identifiers according to the C standard.

OK, I'll fix rest of them.

Use of a function in genbki.sh is very likely not portable.

OK, I'll consider something

use of flock() is probably not portable and even less probably necessary.

OK, I'll fix it.

Declaring a function foo() rather than foo(void) is poor style ---
at least some compilers will complain about that.

OK, I'll fix these kind of function declarations.

I see a lot of "Copyright 2007 KaiGai Kohei" notices. Are you
willing to assign those copyrights to the Postgres Global Development
Group? If not, we'll at least need statements along the line of
"Distributed under the PostgreSQL license".

No need to say, I'm willing to assign these copytights to the PostgreSQL
Global Development Group.
Can I replace them on the next patch set?

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#47KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#40)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

After that, and a whole bunch of foolery with manually putting the right
security labels on files (because the contrib module is unhelpful for
test installations with nonstandard PREFIXes), I managed to get a
version that worked well enough to test. What I found out:

I'll improve the way to provide security policy.
Please wait for a while.

* It does not come close to passing the regression tests. I saw a lot of
! ERROR: unrecognized node type: 903
which suggests that something's been screwed up about parse analysis
(903 = T_A_Const, which shouldn't get further than parse analysis),

Could you tell me what queries hit these errors?
I guess this message was generated in expression_tree_walker() called within
sepgsqlExprWalker(), but it is invoked after query rewriter.

and it dumps core in the TRUNCATE test.

This bug came from misoperations of List.

* pgbench shows a relatively marginal speed difference, which is not
too surprising since it pushes only a few tuples around per query.
The worst case for sepostgres is likely to be bulk operations.
I tried "select count(*) from accounts" (at scale factor 20, so this
is 2000000 tuples) and got about 550 msec from CVS HEAD, about
1340 msec from HEAD plus patch. That's with no actual useful policy
loaded, mind you.

So the overhead is indeed pretty bad, but it seems reasonable to think
that with some optimization effort it could be brought down to where
it'd be acceptable for people who really need the feature.

Thanks for your information.
It indeed has performance degrading, but, I expect users who want to apply
SELinux policy don't put their first priority on edge performance.

AFAICS the only thing left that really needs to be discussed more during
this commit-fest is the business about whether it's sane to be trying to
apply selinux restrictions in simple_heap_update and friends. The more
I think about that the more I think it's simply a bad idea. Those
functions are used primarily (if not solely) for system-initiated
catalog updates, and I fail to see any plausible reason to let
user-written policy be applied at that level. For instance, it would
be a completely bad move to allow such policy to prevent autovacuum
from updating relfrozenxid values.

In generally, fewer and more fundamental security checks are more
comprehensive. simple_heap_update() can trap any updating, called
from more than 80 places.

The purpose of SE-PostgreSQL is to apply security policy on user's
queries, not an internal one. Therefore, we don't apply any policy
on some of *internal* operations, like updating TOAST table.

Currently I don't apply any special care for autovacuum, however,
it is a solution to handle *internal* updating as an exception for
checks. (Because it is NOT came from external users.)

Furthermore, those functions are
much too low-level to have any idea of the reason for the change they
are being asked to make, so they can't apply any intelligence to the
allow-or-not decision.

We can abstract finer-grained access control unit later, however,
its reverse is difficult.
For example, we have to have the following permission to create
a new table.
- Insert a new tuple into pg_class
- Insert a new tuple into pg_type
- Insert new tuples into pg_attribute

These are abstracted in the default security policy.
If you want non-administrative users to create/drop table,
set sepgsql_enable_users_ddl boolean to turn on/off the permission set.

# setsebool sepgsql_enable_users_ddl=1

Lastly, I don't see any use-case for policy there
that wouldn't be served as well or better by the standard SQL privilege
mechanism. So I think that really all needs to be ripped out, and
do enforcement in the executor instead.

The primary purpose of SE-PostgreSQL is to apply common access control
policy on database objects, as if clients access filesystem objects.

See the following diagram:
http://sepgsql.googlecode.com/files/sepgsql_dfc.png

It shows two users within different domain tries to communicate each
other, and any message have to go through inter-processes communication
method like files, networks, and so on.
(Security policy enforces single directed data flow, from lower to higher.)

SELinux can prevent data leaking via shared files because it is managed
by operating system. However, it is impossible for database objects.

SE-PostgreSQL apply (system-wide) common security policy on database objects.
This concept enables to maintain consistency of access control policy.

The standard SQL privilegs machanism is suitable to control accesses
on database objects, however, it is not easy to maintain its consistency
with operating systems's policy.

Is it appropriate answer for your question?

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#48Andrew Sullivan
ajs@commandprompt.com
In reply to: Greg Smith (#45)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Wed, May 07, 2008 at 12:01:21AM -0400, Greg Smith wrote:

It may be the case that clean row and column filtering at the SQL layer are
pre-requisites for a clean SELinux implementation, where the only
difference is that the permission checks are handled by asking SELinux
instead of looking in the catalog.

That strikes me as an approach more likely to be fruitful.

I get the point about imposing all the restrictions at the SELinux
layer. But the way to do that, I think, is to make the individual
policies possible to implement in PostgreSQL simpliciter, and then
have some interface to the SELinux permissions system so that it
becomes possible to set those definitions outside Postgres. (I know
that the latter raises all sorts of nasty DoS scenarios. That's
clearly one of the problems that will need addressing.)

Again, I support the effort in principle; I'm just not sure that the
current proof-of-concept work is what will be needed to address the
design goals. I do think that somewhat clearer scope definitions
would be a big help in deciding which modifications are really needed,
and where.

A

--
Andrew Sullivan
ajs@commandprompt.com
+1 503 667 4564 x104
http://www.commandprompt.com/

#49Tom Lane
tgl@sss.pgh.pa.us
In reply to: KaiGai Kohei (#47)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Tom Lane wrote:

* It does not come close to passing the regression tests. I saw a lot of
! ERROR: unrecognized node type: 903
which suggests that something's been screwed up about parse analysis
(903 = T_A_Const, which shouldn't get further than parse analysis),

Could you tell me what queries hit these errors?

I remember seeing it on some EXECUTEs, but you really ought to run the
tests for yourself. A *minimum* requirement on any submitted patch
is that it should pass the regression tests.

regards, tom lane

#50Marc Munro
marc@bloodnok.com
In reply to: Tom Lane (#49)
Re: [0/4] Proposal of SE-PostgreSQL patches

In a digest for Tue, 2008-05-06 at 22:57 -0300, Tom Lane wrote:
...[discussion of SE-PostgreSQL patch deleted]...

(And of course the next question after that is why we should want to
depend on SELinux at all, rather than implementing row filtering
in the framework of SQL permissions...)

I would love to see something like this to replace Veil which I develop
and support. What sort of row filtering did you have in mind?

As a database application developer I have found being able to define
access controls in terms of data relationships to be tremendously useful
and I would love to see something like this built into postgres.

As far as I have been able to understand SE-PostgreSQL, it is aimed at a
very security-conscious, and expert, customer base but it cannot offer
the sort of relationally-defined security access that Veil is intended
for (I'd be happy to be wrong about this). On the other hand Veil is
not going to be able to provide the degree of certainty (provability?)
of SE-PostgreSQL.

As an example of relationally-defined security, suppose I want only the
members of a project team to be able to see project information:

In the veil demo application (
http://veil.projects.postgresql.org/curdocs/demo-model.html ) we can
assign a developer to a project by inserting into the assignments table
a record for that developer, the given project and a specific role.
Once assigned, the developer can see project_details for that project
that previously were unavailable.

If row filtering is to be implemented directly within Postgres, I would
like this sort of capability to be considered. For the record, Veil was
written to provide similar functionality to Oracle's Virtual Private
Databases.

__
Marc

#51Josh Berkus
josh@agliodbs.com
In reply to: Andrew Sullivan (#43)
Re: [0/4] Proposal of SE-PostgreSQL patches

Andrew, Marc,

FWIW, I support and think important the row- and column- level access
controls this seems to be proposing, at least in principle. Whether
that's a support that will extend to 2x overhead on everything is
rather a different matter. Also, I am more than prepared to trade
away some cases in order to get a broadly useful functionality (so if
you can't hide the existence of a table, but all efforts to learn its
contents don't work, I might be willing to support that trade-off).

Well, there are two different goals we can satisfy. One is to help
support the kind of VPS functionality that Veil is designed for, and the
majority of users want. The second goal is upholding the kind of
security systems demanded by highly secure environments which have
statutory requirements about how security should work.

That is, while Veil-like funcitonality is what most developers want,
it's not what NSA/Banks/military want, who have their own ideas about
security. I think we can conceivably capture both.

I do think that SE functionality which goes beyond reasonable SQL
requirements should be a build-time options because I don't feasably see
ways to implement them that won't cause a big performance hit.

Also, I think you should be aware that for serious multilevel security
hackers (one of whom will be working on Postgres soon) SEPostgres is the
beginning and not the end. One of the requirements of many militaries,
for example, is not merely data hiding by data substitution, where the
row contents you see depend on your security clearance.

Also, re: pg_dump: it's actually a desired feature that, for example,
some users only be able to dump a subset of the database. Including
some DBAs. One of the issues which SE/Mulitlevel tries to address is
"what happens if you don't trust your DBA 100%?" So if we can retain
that, it's actually a feature and not a bug.

--Josh

#52KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: KaiGai Kohei (#46)
Re: [0/4] Proposal of SE-PostgreSQL patches

The whole "early security" business looks like a mess :-(. I suspect
you should rip all that out of the backend and add a step to initdb
that fills in those tables.

I also think "early security" codes are ad-hoc. :-(
Pushing it into initdb seems me a good idea.
I'll try to consider whether it is possible, or not.

The purpose of "early security" code is to manage relationship security
identifier and text representation before pg_security creation.

Therefore, we can make it redundant if initializing security attributes
can be done later. In the next patch set, I'll inject a hook to initialize
them at the last of bootstraping phase, and remove "early security" code.

Any tuples inserted during bootstraping mode are unlabeled, and this
operation is always allowed. Then, this hook is invoked after setting
up all system catalog, and it labels whole of database, as if "restorecon"
command initialize security context of filesystem objects.

How do you think about this design?
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#53KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#49)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Tom Lane wrote:

* It does not come close to passing the regression tests. I saw a lot of
! ERROR: unrecognized node type: 903
which suggests that something's been screwed up about parse analysis
(903 = T_A_Const, which shouldn't get further than parse analysis),

Could you tell me what queries hit these errors?

I remember seeing it on some EXECUTEs, but you really ought to run the
tests for yourself. A *minimum* requirement on any submitted patch
is that it should pass the regression tests.

Some of the test fails contains minor differences from expected results, like:

| SELECT '' AS "xxx", *
| FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a);
| xxx | a | b | c | d
| -----+---+---+------+---
| - | 0 | | zero |
| | 2 | 3 | two | 2
| | 4 | 1 | four | 2
| + | 0 | | zero |
| (3 rows)

and, some of them are trivial ones, like:

| SELECT p1.oid, p1.typname
| FROM pg_type as p1
| WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
| (SELECT 1 FROM pg_type as p2
| WHERE p2.typname = ('_' || p1.typname)::name AND
| p2.typelem = p1.oid and p1.typarray = p2.oid);
| - oid | typname
| ------+---------
| - 210 | smgr
| - 705 | unknown
| -(2 rows)
| + oid | typname
| +------+----------------
| + 210 | smgr
| + 705 | unknown
| + 3403 | security_label
| +(3 rows)

Isn't it necessary to consider them as regressions?

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#54Tom Lane
tgl@sss.pgh.pa.us
In reply to: KaiGai Kohei (#53)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Some of the test fails contains minor differences from expected results, like:

| SELECT '' AS "xxx", *
| FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a);
| xxx | a | b | c | d
| -----+---+---+------+---
| - | 0 | | zero |
| | 2 | 3 | two | 2
| | 4 | 1 | four | 2
| + | 0 | | zero |
| (3 rows)

Yeah, I remember those. What needs to be looked at here is *why* the
output is changing. For a patch that allegedly does not touch the
planner, it's fairly disturbing that you don't get the same results.

and, some of them are trivial ones, like:

| SELECT p1.oid, p1.typname
| FROM pg_type as p1
| WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
| (SELECT 1 FROM pg_type as p2
| WHERE p2.typname = ('_' || p1.typname)::name AND
| p2.typelem = p1.oid and p1.typarray = p2.oid);
| - oid | typname
| ------+---------
| - 210 | smgr
| - 705 | unknown
| -(2 rows)
| + oid | typname
| +------+----------------
| + 210 | smgr
| + 705 | unknown
| + 3403 | security_label
| +(3 rows)

Are you sure that the security_label type should not have an array type?
I do not offhand see a good argument for that. If it really shouldn't,
we can change the expected output here, but you've got to make that
case first.

regards, tom lane

#55KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#54)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Some of the test fails contains minor differences from expected results, like:

| SELECT '' AS "xxx", *
| FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a);
| xxx | a | b | c | d
| -----+---+---+------+---
| - | 0 | | zero |
| | 2 | 3 | two | 2
| | 4 | 1 | four | 2
| + | 0 | | zero |
| (3 rows)

Yeah, I remember those. What needs to be looked at here is *why* the
output is changing. For a patch that allegedly does not touch the
planner, it's fairly disturbing that you don't get the same results.

SE-PostgreSQL does not touch the planner, but it modifies given query
to filter violated tuples for the current user.
Thus, the above query is dealt as if the following query is inputed.

SELECT '' AS "xxx", *
FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a)
ON sepgsql_tuple_perms(t1.security_context, SEPGSQL_PERMS_SELECT, ...)
and sepgsql_tuple_perms(t2.security_context, SEPGSQL_PERMS_SELECT, ...);

sepgsql_tuple_perms() returns true, if the security policy allows user
to access a given tuple. It returns false, if not so.

The result of EXPLAIN shows it more clearly:

| kaigai=# EXPLAIN SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a);
| QUERY PLAN
| -----------------------------------------------------------------------------------------------
| Hash Join (cost=29023.54..82599.93 rows=1380 width=44)
| Hash Cond: (t2.a = t1.a)
| -> Seq Scan on j2_tbl t2 (cost=0.00..53526.05 rows=713 width=8)
| Filter: pg_catalog.sepgsql_tuple_perms(tableoid, security_context, 12288, t2.*)
| -> Hash (cost=29018.70..29018.70 rows=387 width=40)
| -> Seq Scan on j1_tbl t1 (cost=0.00..29018.70 rows=387 width=40)
| Filter: pg_catalog.sepgsql_tuple_perms(tableoid, security_context, 12288, t1.*)
| (7 rows)

and, some of them are trivial ones, like:

| SELECT p1.oid, p1.typname
| FROM pg_type as p1
| WHERE p1.typtype in ('b','e') AND p1.typname NOT LIKE E'\\_%' AND NOT EXISTS
| (SELECT 1 FROM pg_type as p2
| WHERE p2.typname = ('_' || p1.typname)::name AND
| p2.typelem = p1.oid and p1.typarray = p2.oid);
| - oid | typname
| ------+---------
| - 210 | smgr
| - 705 | unknown
| -(2 rows)
| + oid | typname
| +------+----------------
| + 210 | smgr
| + 705 | unknown
| + 3403 | security_label
| +(3 rows)

Are you sure that the security_label type should not have an array type?
I do not offhand see a good argument for that. If it really shouldn't,
we can change the expected output here, but you've got to make that
case first.

Yes, security_label type should not have an array type.
It is defined with typelem=0 and typarray=0.
The purpose of this type is to represent the new system column of
security attribute ("security_context" column).

So, I think it is a case that a new expented output should be modified.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#56Tom Lane
tgl@sss.pgh.pa.us
In reply to: KaiGai Kohei (#55)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Tom Lane wrote:

Yeah, I remember those. What needs to be looked at here is *why* the
output is changing. For a patch that allegedly does not touch the
planner, it's fairly disturbing that you don't get the same results.

SE-PostgreSQL does not touch the planner, but it modifies given query
to filter violated tuples for the current user.

Hmm. Is that really a good idea, compared to hard-wiring the checks
into nodeSeqscan and friends? I didn't look at the query-rewriting
portion of the patch in any detail, but I'd tend not to trust such
a technique very far: getting it right is going to be quite complex
and probably bug prone.

Are you sure that the security_label type should not have an array type?

Yes, security_label type should not have an array type.

You didn't provide one ounce of justification for making it not obey the
expected behavior, so I'm not accepting this position. It doesn't seem
to me to be all that unlikely that users would want to compute with
arrays of security labels. As an example:
select ... where security_label in ('foo', 'bar')
which will become an = ANY(ARRAY[]) construct under the hood.

regards, tom lane

#57Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#56)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Tom Lane wrote:

Yeah, I remember those. What needs to be looked at here is *why* the
output is changing. For a patch that allegedly does not touch the
planner, it's fairly disturbing that you don't get the same results.

SE-PostgreSQL does not touch the planner, but it modifies given query
to filter violated tuples for the current user.

Hmm. Is that really a good idea, compared to hard-wiring the checks
into nodeSeqscan and friends? I didn't look at the query-rewriting
portion of the patch in any detail, but I'd tend not to trust such
a technique very far: getting it right is going to be quite complex
and probably bug prone.

My eyebrows went up when I read this too. Presumably, if it's hardwired
like you suggest then the planner can't take any account of the filter,
though. Do we want it to?

OTOH, I'm not happy about silently rewriting queries, either - it would
make optimising queries a lot harder, I suspect.

cheers

andrew

#58Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#57)
Re: [0/4] Proposal of SE-PostgreSQL patches

Andrew Dunstan <andrew@dunslane.net> writes:

Tom Lane wrote:

Hmm. Is that really a good idea, compared to hard-wiring the checks
into nodeSeqscan and friends?

My eyebrows went up when I read this too. Presumably, if it's hardwired
like you suggest then the planner can't take any account of the filter,
though. Do we want it to?

Well, the planner could have hardwired knowledge about the existence of
the hardwired filters --- if anything, that'd probably be easier than
hacking it to have a similar level of knowledge about generic-looking
function calls. But in reality, since we don't know at plan time which
userid will execute the constructed plan, I'm not sure we could come up
with useful estimates anyway.

regards, tom lane

#59KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#56)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

KaiGai Kohei <kaigai@ak.jp.nec.com> writes:

Tom Lane wrote:

Yeah, I remember those. What needs to be looked at here is *why* the
output is changing. For a patch that allegedly does not touch the
planner, it's fairly disturbing that you don't get the same results.

SE-PostgreSQL does not touch the planner, but it modifies given query
to filter violated tuples for the current user.

Hmm. Is that really a good idea, compared to hard-wiring the checks
into nodeSeqscan and friends? I didn't look at the query-rewriting
portion of the patch in any detail, but I'd tend not to trust suchte
a technique very far: getting it right is going to be quite complex
and probably bug prone.

In the prior base version (8.2.x and 8.3.x), I tended to implement
these stuffs in the modular part as far as possible, because massive
patched hanks makes more difficult to follow the mainstreamed PostgreSQL. :-(

However, the hard-wides checks look like a good idea for me.
I tried to implement a prototype of the disign, and currently it works fine.
If we can replace the implementation of tuple-level access controls by this
design, it makes the implementation simpler.

Now, I add a hook into ExecScan(). It can return true or false, to decide
whether a given tuple is filtered or not.
Permissions to be evaluated are delivered via Scan structure. A variable
named as pgaceTuplePerms (uint32) is added to keep permission set for
tuple level access controls into Scan structure.
If the security module put a proper bitmask on pgaceTuplePerms of RangeTblEntry,
it is copied to related Scan structure later.

Are you sure that the security_label type should not have an array type?

Yes, security_label type should not have an array type.

You didn't provide one ounce of justification for making it not obey the
expected behavior, so I'm not accepting this position. It doesn't seem
to me to be all that unlikely that users would want to compute with
arrays of security labels. As an example:
select ... where security_label in ('foo', 'bar')
which will become an = ANY(ARRAY[]) construct under the hood.

Ah.., I didn't intend such kind of usage, so security_label type does not
have operators to use it directly, not only array support.

I'll add it in the next patch set.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#60KaiGai Kohei
kaigai@ak.jp.nec.com
In reply to: Tom Lane (#37)
Re: [0/4] Proposal of SE-PostgreSQL patches

Tom Lane wrote:

The idea of input functions that alter system tables scares me.

An example:
SELECT 'system_u:object_r:sepgsql_table_t:SystemHigh'::security_label;

can insert a new tuple into pg_security, but it is not a desirable behavior.

To fix this, I'll remove security_label type and define "security_context"
system column as a text type column, and translate the contents into
an internal identifical representation just before update or insert a tuple.

It enables to avoid to insert a temporary used (unnecessary) security context,
and enables to use various kind of text functions.

Please comment it, if you have anything.

Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

#61Dawid Kuroczko
qnex42@gmail.com
In reply to: KaiGai Kohei (#46)
Re: [0/4] Proposal of SE-PostgreSQL patches

On Wed, May 7, 2008 at 7:52 AM, KaiGai Kohei <kaigai@ak.jp.nec.com> wrote:

Tom, Thanks for your reviewing.

The patch hasn't got a mode in which SELinux support is compiled in but
not active. This is a good way to ensure that no one will ever ship
standard RPMs with the feature compiled in, because they will be entirely
nonfunctional for people who aren't interested in setting up SELinux.
I think you need an "enable_sepostgres" GUC, or something like that.
(Of course, the overhead of the per-row security column would probably
discourage anyone from wanting to use such a configuration anyway,
so maybe the point is moot.)

We can turn on/off SELinux globally, not bounded to SE-PostgreSQL.
The reason why I didn't provide a mode bit like "enable_sepostgresql"
is to keep consistency in system configuration.

Hmm, I think ACE should be a CREATE DATABASE parameter.

If I were to create a SE-database I would wish that disabling it was
more difficult than changing a GUC in database. And being able to
set it on per-database basis would help get SE/ACE enabled by
packagers.

Regards,
Dawid
--
Solving [site load issues] with [more database replication] is a lot
like solving your own personal problems with heroin - at first it
sorta works, but after a while things just get out of hand.

#62Bruce Momjian
bruce@momjian.us
In reply to: KaiGai Kohei (#29)
Re: [0/4] Proposal of SE-PostgreSQL patches

Added to TODO:

* Improve server security options

http://archives.postgresql.org/pgsql-hackers/2008-04/msg01875.php
http://archives.postgresql.org/pgsql-hackers/2008-05/msg00000.php

---------------------------------------------------------------------------

KaiGai Kohei wrote:

I updated the series of SE-PostgreSQL patches for the latest pgsql-8.4devel tree.

[1/4] sepostgresql-pgace-8.4devel-3-r739.patch
provides PGACE (PostgreSQL Access Control Extension) framework.
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r739.patch

[2/4] sepostgresql-sepgsql-8.4devel-3-r739.patch
provides SE-PostgreSQL feature, based on PGACE framework.
http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r739.patch

[3/4] sepostgresql-pg_dump-8.4devel-3-r739.patch
enables to dump databases with security attribute.
http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r739.patch

[4/4] sepostgresql-policy-8.4devel-3-r739.patch
provides the default security policy of SE-PostgreSQL.
http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r739.patch

We provide a quick overview for SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

Thanks,

KaiGai Kohei wrote:

The series of patches are the proposal of Security-Enhanced PostgreSQL (SE-PostgreSQL)
for the upstreamed PostgreSQL 8.4 development cycle.

[1/4] sepostgresql-pgace-8.4devel-3.patch
provides PGACE (PostgreSQL Access Control Extension) framework
http://sepgsql.googlecode.com/files/sepostgresql-pgace-8.4devel-3-r704.patch

[2/4] sepostgresql-sepgsql-8.4devel-3.patch
provides SE-PostgreSQL feature, based on PGACE framework.
http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r704.patch

[3/4] sepostgresql-pg_dump-8.4devel-3.patch
enables pg_dump to dump database with security attribute.
http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r704.patch

[4/4] sepostgresql-policy-8.4devel-3.patch
provides the default security policy for SE-PostgreSQL.
http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r704.patch

We can provide a quick overview for SE-PostgreSQL at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

ENVIRONMENT
-----------
Please confirm your environment.
The followings are requriements of SE-PostgreSQL.
* Fedora 8 or later system
* SELinux is enabled and working
* kernel-2.6.24 or later
* selinux-policy and selinux-policy-devel v3.0.8 or later
* libselinux, policycoreutils

INSTALLATION
------------
$ tar jxvf postgresql-snapshot.tar.bz2
$ cd postgresql-snapshot
$ patch -p1 < ../sepostgresql-pgace-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-sepgsql-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-pg_dump-8.4devel-3.patch
$ patch -p1 < ../sepostgresql-policy-8.4devel-3.patch

$ ./configure --enable-selinux
$ make
$ make -C contrib/sepgsql-policy
$ su
# make install

# /usr/sbin/semodule -i contrib/sepgsql-policy/sepostgresql.pp
(NOTE: semodule is a utility to load/unload security policy modules.)

# /sbin/restorecon -R /usr/local/pgsql
(NOTE: restorecon is a utilicy to initialize security context of files.)

SETUP
-----
# mkdir -p /opt/sepgsql
# chown foo_user:var_group /opt/sepgsql
# chcon -t postgresql_db_t /opt/sepgsql
(NOTE: chcon is a utility to set up security context of files.)
# exit

$ /usr/sbin/run_init /usr/local/pgsql/bin/initdb -D /opt/sepgsql
(NOTE: run_init is a utility to start a program, as if it is branched from init script.)
$ /usr/local/pgsql/bin/pg_ctl -D /opt/sepgsql start

SUMMARYS FOR EVERY PATCHES
--------------------------
[1/4] - sepostgresql-pgace-8.4devel-3.patch

This patch provides PGACE (PostgreSQL Access Control Extension) framework.

It has a similar idea of LSM (Linu Security Module).
It can provide a guest module several hooks at strategic points.
The guest module can make its decision whether required actions should be
allowed, or not.
In addition, PGACE also provides falicilites to manage security attribute
of database objects. Any tuple can have a its security attribute, and the
guest module can refer it to control accesses.

A more conprehensive memo at:
http://code.google.com/p/sepgsql/wiki/WhatIsPGACE

[2/4] - sepostgresql-sepgsql-8.4devel-3.patch

This patch provides SE-PostgreSQL facilities based on PGACE.

Security-Enhanced PostgreSQL (SE-PostgreSQL) is a security extension
built in PostgreSQL, to provide system-wide consistency in access
controls. It enables to apply a single unigied security policy of
SELinux for both operating system and database management system.
In addition, it also provides fine-grained mandatory access which
includes column-/row- level non-bypassable access control even if
privileged database users.

Quick overview at:
http://code.google.com/p/sepgsql/wiki/WhatIsSEPostgreSQL

[3/4] - sepostgresql-pg_dump-8.4devel-3.patch

This patch gives us a feature to dump database with security attribute.
It is turned on with '--enable-selinux' option at pg_dump/pg_dumpall,
when the server works as SE- version.
No need to say, users need to have enough capabilities to dump whole of
database. It it same when they tries to restore the database.

[4/4] - sepostgresql-policy-8.4devel-3.patch

This patch gives us the default security policy for SE-PostgreSQL.
You can build it as a security policy module. It can be linked with
the existing distributor's policy, and reloaded.

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

#63Josh Berkus
josh@agliodbs.com
In reply to: Bruce Momjian (#62)
Re: [0/4] Proposal of SE-PostgreSQL patches

Bruce, KaiGai,

Is PGACE ready for CommitFest, now?

--Josh

#64KaiGai Kohei
kaigai@kaigai.gr.jp
In reply to: Josh Berkus (#63)
Re: [0/4] Proposal of SE-PostgreSQL patches

Josh Berkus wrote:

Bruce, KaiGai,

Is PGACE ready for CommitFest, now?

--Josh

Yes, it's ready now.

See the following message:
http://archives.postgresql.org/pgsql-hackers/2008-06/msg00980.php
http://archives.postgresql.org/pgsql-hackers/2008-06/msg00840.php

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

#65Josh Berkus
josh@agliodbs.com
In reply to: KaiGai Kohei (#64)
Re: [0/4] Proposal of SE-PostgreSQL patches

KaiGai Kohei wrote:

Josh Berkus wrote:

Bruce, KaiGai,

Is PGACE ready for CommitFest, now?

--Josh

Yes, it's ready now.

OK, added to CommitFest.

--Josh