PostgreSQL Source Code  git master
selinux.c
Go to the documentation of this file.
1 /* -------------------------------------------------------------------------
2  *
3  * contrib/sepgsql/selinux.c
4  *
5  * Interactions between userspace and selinux in kernelspace,
6  * using libselinux api.
7  *
8  * Copyright (c) 2010-2022, PostgreSQL Global Development Group
9  *
10  * -------------------------------------------------------------------------
11  */
12 #include "postgres.h"
13 
14 #include "lib/stringinfo.h"
15 
16 #include "sepgsql.h"
17 
18 /*
19  * selinux_catalog
20  *
21  * This mapping table enables to translate the name of object classes and
22  * access vectors to/from their own codes.
23  * When we ask SELinux whether the required privileges are allowed or not,
24  * we use security_compute_av(3). It needs us to represent object classes
25  * and access vectors using 'external' codes defined in the security policy.
26  * It is determined in the runtime, not build time. So, it needs an internal
27  * service to translate object class/access vectors which we want to check
28  * into the code which kernel want to be given.
29  */
30 static struct
31 {
32  const char *class_name;
34  struct
35  {
36  const char *av_name;
38  } av[32];
39 } selinux_catalog[] =
40 
41 {
42  {
43  "process", SEPG_CLASS_PROCESS,
44  {
45  {
46  "transition", SEPG_PROCESS__TRANSITION
47  },
48  {
49  "dyntransition", SEPG_PROCESS__DYNTRANSITION
50  },
51  {
52  "setcurrent", SEPG_PROCESS__SETCURRENT
53  },
54  {
55  NULL, 0UL
56  }
57  }
58  },
59  {
60  "file", SEPG_CLASS_FILE,
61  {
62  {
63  "read", SEPG_FILE__READ
64  },
65  {
66  "write", SEPG_FILE__WRITE
67  },
68  {
69  "create", SEPG_FILE__CREATE
70  },
71  {
72  "getattr", SEPG_FILE__GETATTR
73  },
74  {
75  "unlink", SEPG_FILE__UNLINK
76  },
77  {
78  "rename", SEPG_FILE__RENAME
79  },
80  {
81  "append", SEPG_FILE__APPEND
82  },
83  {
84  NULL, 0UL
85  }
86  }
87  },
88  {
89  "dir", SEPG_CLASS_DIR,
90  {
91  {
92  "read", SEPG_DIR__READ
93  },
94  {
95  "write", SEPG_DIR__WRITE
96  },
97  {
98  "create", SEPG_DIR__CREATE
99  },
100  {
101  "getattr", SEPG_DIR__GETATTR
102  },
103  {
104  "unlink", SEPG_DIR__UNLINK
105  },
106  {
107  "rename", SEPG_DIR__RENAME
108  },
109  {
110  "search", SEPG_DIR__SEARCH
111  },
112  {
113  "add_name", SEPG_DIR__ADD_NAME
114  },
115  {
116  "remove_name", SEPG_DIR__REMOVE_NAME
117  },
118  {
119  "rmdir", SEPG_DIR__RMDIR
120  },
121  {
122  "reparent", SEPG_DIR__REPARENT
123  },
124  {
125  NULL, 0UL
126  }
127  }
128  },
129  {
130  "lnk_file", SEPG_CLASS_LNK_FILE,
131  {
132  {
133  "read", SEPG_LNK_FILE__READ
134  },
135  {
136  "write", SEPG_LNK_FILE__WRITE
137  },
138  {
139  "create", SEPG_LNK_FILE__CREATE
140  },
141  {
142  "getattr", SEPG_LNK_FILE__GETATTR
143  },
144  {
145  "unlink", SEPG_LNK_FILE__UNLINK
146  },
147  {
148  "rename", SEPG_LNK_FILE__RENAME
149  },
150  {
151  NULL, 0UL
152  }
153  }
154  },
155  {
156  "chr_file", SEPG_CLASS_CHR_FILE,
157  {
158  {
159  "read", SEPG_CHR_FILE__READ
160  },
161  {
162  "write", SEPG_CHR_FILE__WRITE
163  },
164  {
165  "create", SEPG_CHR_FILE__CREATE
166  },
167  {
168  "getattr", SEPG_CHR_FILE__GETATTR
169  },
170  {
171  "unlink", SEPG_CHR_FILE__UNLINK
172  },
173  {
174  "rename", SEPG_CHR_FILE__RENAME
175  },
176  {
177  NULL, 0UL
178  }
179  }
180  },
181  {
182  "blk_file", SEPG_CLASS_BLK_FILE,
183  {
184  {
185  "read", SEPG_BLK_FILE__READ
186  },
187  {
188  "write", SEPG_BLK_FILE__WRITE
189  },
190  {
191  "create", SEPG_BLK_FILE__CREATE
192  },
193  {
194  "getattr", SEPG_BLK_FILE__GETATTR
195  },
196  {
197  "unlink", SEPG_BLK_FILE__UNLINK
198  },
199  {
200  "rename", SEPG_BLK_FILE__RENAME
201  },
202  {
203  NULL, 0UL
204  }
205  }
206  },
207  {
208  "sock_file", SEPG_CLASS_SOCK_FILE,
209  {
210  {
211  "read", SEPG_SOCK_FILE__READ
212  },
213  {
214  "write", SEPG_SOCK_FILE__WRITE
215  },
216  {
217  "create", SEPG_SOCK_FILE__CREATE
218  },
219  {
220  "getattr", SEPG_SOCK_FILE__GETATTR
221  },
222  {
223  "unlink", SEPG_SOCK_FILE__UNLINK
224  },
225  {
226  "rename", SEPG_SOCK_FILE__RENAME
227  },
228  {
229  NULL, 0UL
230  }
231  }
232  },
233  {
234  "fifo_file", SEPG_CLASS_FIFO_FILE,
235  {
236  {
237  "read", SEPG_FIFO_FILE__READ
238  },
239  {
240  "write", SEPG_FIFO_FILE__WRITE
241  },
242  {
243  "create", SEPG_FIFO_FILE__CREATE
244  },
245  {
246  "getattr", SEPG_FIFO_FILE__GETATTR
247  },
248  {
249  "unlink", SEPG_FIFO_FILE__UNLINK
250  },
251  {
252  "rename", SEPG_FIFO_FILE__RENAME
253  },
254  {
255  NULL, 0UL
256  }
257  }
258  },
259  {
260  "db_database", SEPG_CLASS_DB_DATABASE,
261  {
262  {
263  "create", SEPG_DB_DATABASE__CREATE
264  },
265  {
266  "drop", SEPG_DB_DATABASE__DROP
267  },
268  {
269  "getattr", SEPG_DB_DATABASE__GETATTR
270  },
271  {
272  "setattr", SEPG_DB_DATABASE__SETATTR
273  },
274  {
275  "relabelfrom", SEPG_DB_DATABASE__RELABELFROM
276  },
277  {
278  "relabelto", SEPG_DB_DATABASE__RELABELTO
279  },
280  {
281  "access", SEPG_DB_DATABASE__ACCESS
282  },
283  {
284  "load_module", SEPG_DB_DATABASE__LOAD_MODULE
285  },
286  {
287  NULL, 0UL
288  },
289  }
290  },
291  {
292  "db_schema", SEPG_CLASS_DB_SCHEMA,
293  {
294  {
295  "create", SEPG_DB_SCHEMA__CREATE
296  },
297  {
298  "drop", SEPG_DB_SCHEMA__DROP
299  },
300  {
301  "getattr", SEPG_DB_SCHEMA__GETATTR
302  },
303  {
304  "setattr", SEPG_DB_SCHEMA__SETATTR
305  },
306  {
307  "relabelfrom", SEPG_DB_SCHEMA__RELABELFROM
308  },
309  {
310  "relabelto", SEPG_DB_SCHEMA__RELABELTO
311  },
312  {
313  "search", SEPG_DB_SCHEMA__SEARCH
314  },
315  {
316  "add_name", SEPG_DB_SCHEMA__ADD_NAME
317  },
318  {
319  "remove_name", SEPG_DB_SCHEMA__REMOVE_NAME
320  },
321  {
322  NULL, 0UL
323  },
324  }
325  },
326  {
327  "db_table", SEPG_CLASS_DB_TABLE,
328  {
329  {
330  "create", SEPG_DB_TABLE__CREATE
331  },
332  {
333  "drop", SEPG_DB_TABLE__DROP
334  },
335  {
336  "getattr", SEPG_DB_TABLE__GETATTR
337  },
338  {
339  "setattr", SEPG_DB_TABLE__SETATTR
340  },
341  {
342  "relabelfrom", SEPG_DB_TABLE__RELABELFROM
343  },
344  {
345  "relabelto", SEPG_DB_TABLE__RELABELTO
346  },
347  {
348  "select", SEPG_DB_TABLE__SELECT
349  },
350  {
351  "update", SEPG_DB_TABLE__UPDATE
352  },
353  {
354  "insert", SEPG_DB_TABLE__INSERT
355  },
356  {
357  "delete", SEPG_DB_TABLE__DELETE
358  },
359  {
360  "lock", SEPG_DB_TABLE__LOCK
361  },
362  {
363  "truncate", SEPG_DB_TABLE__TRUNCATE
364  },
365  {
366  NULL, 0UL
367  },
368  }
369  },
370  {
371  "db_sequence", SEPG_CLASS_DB_SEQUENCE,
372  {
373  {
374  "create", SEPG_DB_SEQUENCE__CREATE
375  },
376  {
377  "drop", SEPG_DB_SEQUENCE__DROP
378  },
379  {
380  "getattr", SEPG_DB_SEQUENCE__GETATTR
381  },
382  {
383  "setattr", SEPG_DB_SEQUENCE__SETATTR
384  },
385  {
386  "relabelfrom", SEPG_DB_SEQUENCE__RELABELFROM
387  },
388  {
389  "relabelto", SEPG_DB_SEQUENCE__RELABELTO
390  },
391  {
392  "get_value", SEPG_DB_SEQUENCE__GET_VALUE
393  },
394  {
395  "next_value", SEPG_DB_SEQUENCE__NEXT_VALUE
396  },
397  {
398  "set_value", SEPG_DB_SEQUENCE__SET_VALUE
399  },
400  {
401  NULL, 0UL
402  },
403  }
404  },
405  {
406  "db_procedure", SEPG_CLASS_DB_PROCEDURE,
407  {
408  {
409  "create", SEPG_DB_PROCEDURE__CREATE
410  },
411  {
413  },
414  {
415  "getattr", SEPG_DB_PROCEDURE__GETATTR
416  },
417  {
418  "setattr", SEPG_DB_PROCEDURE__SETATTR
419  },
420  {
421  "relabelfrom", SEPG_DB_PROCEDURE__RELABELFROM
422  },
423  {
424  "relabelto", SEPG_DB_PROCEDURE__RELABELTO
425  },
426  {
427  "execute", SEPG_DB_PROCEDURE__EXECUTE
428  },
429  {
430  "entrypoint", SEPG_DB_PROCEDURE__ENTRYPOINT
431  },
432  {
433  "install", SEPG_DB_PROCEDURE__INSTALL
434  },
435  {
436  NULL, 0UL
437  },
438  }
439  },
440  {
441  "db_column", SEPG_CLASS_DB_COLUMN,
442  {
443  {
444  "create", SEPG_DB_COLUMN__CREATE
445  },
446  {
447  "drop", SEPG_DB_COLUMN__DROP
448  },
449  {
450  "getattr", SEPG_DB_COLUMN__GETATTR
451  },
452  {
453  "setattr", SEPG_DB_COLUMN__SETATTR
454  },
455  {
456  "relabelfrom", SEPG_DB_COLUMN__RELABELFROM
457  },
458  {
459  "relabelto", SEPG_DB_COLUMN__RELABELTO
460  },
461  {
462  "select", SEPG_DB_COLUMN__SELECT
463  },
464  {
465  "update", SEPG_DB_COLUMN__UPDATE
466  },
467  {
468  "insert", SEPG_DB_COLUMN__INSERT
469  },
470  {
471  NULL, 0UL
472  },
473  }
474  },
475  {
476  "db_tuple", SEPG_CLASS_DB_TUPLE,
477  {
478  {
479  "relabelfrom", SEPG_DB_TUPLE__RELABELFROM
480  },
481  {
482  "relabelto", SEPG_DB_TUPLE__RELABELTO
483  },
484  {
485  "select", SEPG_DB_TUPLE__SELECT
486  },
487  {
488  "update", SEPG_DB_TUPLE__UPDATE
489  },
490  {
491  "insert", SEPG_DB_TUPLE__INSERT
492  },
493  {
494  "delete", SEPG_DB_TUPLE__DELETE
495  },
496  {
497  NULL, 0UL
498  },
499  }
500  },
501  {
502  "db_blob", SEPG_CLASS_DB_BLOB,
503  {
504  {
505  "create", SEPG_DB_BLOB__CREATE
506  },
507  {
508  "drop", SEPG_DB_BLOB__DROP
509  },
510  {
511  "getattr", SEPG_DB_BLOB__GETATTR
512  },
513  {
514  "setattr", SEPG_DB_BLOB__SETATTR
515  },
516  {
517  "relabelfrom", SEPG_DB_BLOB__RELABELFROM
518  },
519  {
520  "relabelto", SEPG_DB_BLOB__RELABELTO
521  },
522  {
523  "read", SEPG_DB_BLOB__READ
524  },
525  {
526  "write", SEPG_DB_BLOB__WRITE
527  },
528  {
529  "import", SEPG_DB_BLOB__IMPORT
530  },
531  {
532  "export", SEPG_DB_BLOB__EXPORT
533  },
534  {
535  NULL, 0UL
536  },
537  }
538  },
539  {
540  "db_language", SEPG_CLASS_DB_LANGUAGE,
541  {
542  {
543  "create", SEPG_DB_LANGUAGE__CREATE
544  },
545  {
546  "drop", SEPG_DB_LANGUAGE__DROP
547  },
548  {
549  "getattr", SEPG_DB_LANGUAGE__GETATTR
550  },
551  {
552  "setattr", SEPG_DB_LANGUAGE__SETATTR
553  },
554  {
555  "relabelfrom", SEPG_DB_LANGUAGE__RELABELFROM
556  },
557  {
558  "relabelto", SEPG_DB_LANGUAGE__RELABELTO
559  },
560  {
561  "implement", SEPG_DB_LANGUAGE__IMPLEMENT
562  },
563  {
564  "execute", SEPG_DB_LANGUAGE__EXECUTE
565  },
566  {
567  NULL, 0UL
568  },
569  }
570  },
571  {
572  "db_view", SEPG_CLASS_DB_VIEW,
573  {
574  {
575  "create", SEPG_DB_VIEW__CREATE
576  },
577  {
578  "drop", SEPG_DB_VIEW__DROP
579  },
580  {
581  "getattr", SEPG_DB_VIEW__GETATTR
582  },
583  {
584  "setattr", SEPG_DB_VIEW__SETATTR
585  },
586  {
587  "relabelfrom", SEPG_DB_VIEW__RELABELFROM
588  },
589  {
590  "relabelto", SEPG_DB_VIEW__RELABELTO
591  },
592  {
593  "expand", SEPG_DB_VIEW__EXPAND
594  },
595  {
596  NULL, 0UL
597  },
598  }
599  },
600 };
601 
602 /*
603  * sepgsql_mode
604  *
605  * SEPGSQL_MODE_DISABLED: Disabled on runtime
606  * SEPGSQL_MODE_DEFAULT: Same as system settings
607  * SEPGSQL_MODE_PERMISSIVE: Always permissive mode
608  * SEPGSQL_MODE_INTERNAL: Same as permissive, except for no audit logs
609  */
611 
612 /*
613  * sepgsql_is_enabled
614  */
615 bool
617 {
619 }
620 
621 /*
622  * sepgsql_get_mode
623  */
624 int
626 {
627  return sepgsql_mode;
628 }
629 
630 /*
631  * sepgsql_set_mode
632  */
633 int
634 sepgsql_set_mode(int new_mode)
635 {
636  int old_mode = sepgsql_mode;
637 
638  sepgsql_mode = new_mode;
639 
640  return old_mode;
641 }
642 
643 /*
644  * sepgsql_getenforce
645  *
646  * It returns whether the current working mode tries to enforce access
647  * control decision, or not. It shall be enforced when sepgsql_mode is
648  * SEPGSQL_MODE_DEFAULT and system is running in enforcing mode.
649  */
650 bool
652 {
654  selinux_status_getenforce() > 0)
655  return true;
656 
657  return false;
658 }
659 
660 /*
661  * sepgsql_audit_log
662  *
663  * It generates a security audit record. It writes out audit records
664  * into standard PG's logfile.
665  *
666  * SELinux can control what should be audited and should not using
667  * "auditdeny" and "auditallow" rules in the security policy. In the
668  * default, all the access violations are audited, and all the access
669  * allowed are not audited. But we can set up the security policy, so
670  * we can have exceptions. So, it is necessary to follow the suggestion
671  * come from the security policy. (av_decision.auditallow and auditdeny)
672  *
673  * Security audit is an important feature, because it enables us to check
674  * what was happen if we have a security incident. In fact, ISO/IEC15408
675  * defines several security functionalities for audit features.
676  */
677 void
678 sepgsql_audit_log(bool denied,
679  bool enforcing,
680  const char *scontext,
681  const char *tcontext,
682  uint16 tclass,
683  uint32 audited,
684  const char *audit_name)
685 {
687  const char *class_name;
688  const char *av_name;
689  int i;
690 
691  /* lookup name of the object class */
692  Assert(tclass < SEPG_CLASS_MAX);
693  class_name = selinux_catalog[tclass].class_name;
694 
695  /* lookup name of the permissions */
697  appendStringInfo(&buf, "%s {",
698  (denied ? "denied" : "allowed"));
699  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
700  {
701  if (audited & (1UL << i))
702  {
703  av_name = selinux_catalog[tclass].av[i].av_name;
704  appendStringInfo(&buf, " %s", av_name);
705  }
706  }
707  appendStringInfoString(&buf, " }");
708 
709  /*
710  * Call external audit module, if loaded
711  */
712  appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
713  scontext, tcontext, class_name);
714  if (audit_name)
715  appendStringInfo(&buf, " name=\"%s\"", audit_name);
716 
717  if (enforcing)
718  appendStringInfoString(&buf, " permissive=0");
719  else
720  appendStringInfoString(&buf, " permissive=1");
721 
722  ereport(LOG, (errmsg("SELinux: %s", buf.data)));
723 }
724 
725 /*
726  * sepgsql_compute_avd
727  *
728  * It actually asks SELinux what permissions are allowed on a pair of
729  * the security contexts and object class. It also returns what permissions
730  * should be audited on access violation or allowed.
731  * In most cases, subject's security context (scontext) is a client, and
732  * target security context (tcontext) is a database object.
733  *
734  * The access control decision shall be set on the given av_decision.
735  * The av_decision.allowed has a bitmask of SEPG_<class>__<perms>
736  * to suggest a set of allowed actions in this object class.
737  */
738 void
739 sepgsql_compute_avd(const char *scontext,
740  const char *tcontext,
741  uint16 tclass,
742  struct av_decision *avd)
743 {
744  const char *tclass_name;
745  security_class_t tclass_ex;
746  struct av_decision avd_ex;
747  int i,
748  deny_unknown = security_deny_unknown();
749 
750  /* Get external code of the object class */
751  Assert(tclass < SEPG_CLASS_MAX);
752  Assert(tclass == selinux_catalog[tclass].class_code);
753 
754  tclass_name = selinux_catalog[tclass].class_name;
755  tclass_ex = string_to_security_class(tclass_name);
756 
757  if (tclass_ex == 0)
758  {
759  /*
760  * If the current security policy does not support permissions
761  * corresponding to database objects, we fill up them with dummy data.
762  * If security_deny_unknown() returns positive value, undefined
763  * permissions should be denied. Otherwise, allowed
764  */
765  avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0);
766  avd->auditallow = 0U;
767  avd->auditdeny = ~0U;
768  avd->flags = 0;
769 
770  return;
771  }
772 
773  /*
774  * Ask SELinux what is allowed set of permissions on a pair of the
775  * security contexts and the given object class.
776  */
777  if (security_compute_av_flags_raw(scontext,
778  tcontext,
779  tclass_ex, 0, &avd_ex) < 0)
780  ereport(ERROR,
781  (errcode(ERRCODE_INTERNAL_ERROR),
782  errmsg("SELinux could not compute av_decision: "
783  "scontext=%s tcontext=%s tclass=%s: %m",
784  scontext, tcontext, tclass_name)));
785 
786  /*
787  * SELinux returns its access control decision as a set of permissions
788  * represented in external code which depends on run-time environment. So,
789  * we need to translate it to the internal representation before returning
790  * results for the caller.
791  */
792  memset(avd, 0, sizeof(struct av_decision));
793 
794  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
795  {
796  access_vector_t av_code_ex;
797  const char *av_name = selinux_catalog[tclass].av[i].av_name;
798  uint32 av_code = selinux_catalog[tclass].av[i].av_code;
799 
800  av_code_ex = string_to_av_perm(tclass_ex, av_name);
801  if (av_code_ex == 0)
802  {
803  /* fill up undefined permissions */
804  if (!deny_unknown)
805  avd->allowed |= av_code;
806  avd->auditdeny |= av_code;
807 
808  continue;
809  }
810 
811  if (avd_ex.allowed & av_code_ex)
812  avd->allowed |= av_code;
813  if (avd_ex.auditallow & av_code_ex)
814  avd->auditallow |= av_code;
815  if (avd_ex.auditdeny & av_code_ex)
816  avd->auditdeny |= av_code;
817  }
818 }
819 
820 /*
821  * sepgsql_compute_create
822  *
823  * It returns a default security context to be assigned on a new database
824  * object. SELinux compute it based on a combination of client, upper object
825  * which owns the new object and object class.
826  *
827  * For example, when a client (staff_u:staff_r:staff_t:s0) tries to create
828  * a new table within a schema (system_u:object_r:sepgsql_schema_t:s0),
829  * SELinux looks-up its security policy. If it has a special rule on the
830  * combination of these security contexts and object class (db_table),
831  * it returns the security context suggested by the special rule.
832  * Otherwise, it returns the security context of schema, as is.
833  *
834  * We expect the caller already applies sanity/validation checks on the
835  * given security context.
836  *
837  * scontext: security context of the subject (mostly, peer process).
838  * tcontext: security context of the upper database object.
839  * tclass: class code (SEPG_CLASS_*) of the new object in creation
840  */
841 char *
842 sepgsql_compute_create(const char *scontext,
843  const char *tcontext,
844  uint16 tclass,
845  const char *objname)
846 {
847  char *ncontext;
848  security_class_t tclass_ex;
849  const char *tclass_name;
850  char *result;
851 
852  /* Get external code of the object class */
853  Assert(tclass < SEPG_CLASS_MAX);
854 
855  tclass_name = selinux_catalog[tclass].class_name;
856  tclass_ex = string_to_security_class(tclass_name);
857 
858  /*
859  * Ask SELinux what is the default context for the given object class on a
860  * pair of security contexts
861  */
862  if (security_compute_create_name_raw(scontext,
863  tcontext,
864  tclass_ex,
865  objname,
866  &ncontext) < 0)
867  ereport(ERROR,
868  (errcode(ERRCODE_INTERNAL_ERROR),
869  errmsg("SELinux could not compute a new context: "
870  "scontext=%s tcontext=%s tclass=%s: %m",
871  scontext, tcontext, tclass_name)));
872 
873  /*
874  * libselinux returns malloc()'ed string, so we need to copy it on the
875  * palloc()'ed region.
876  */
877  PG_TRY();
878  {
879  result = pstrdup(ncontext);
880  }
881  PG_FINALLY();
882  {
883  freecon(ncontext);
884  }
885  PG_END_TRY();
886 
887  return result;
888 }
889 
890 /*
891  * sepgsql_check_perms
892  *
893  * It makes access control decision without userspace caching mechanism.
894  * If SELinux denied the required accesses on the pair of security labels,
895  * it raises an error or returns false.
896  *
897  * scontext: security label of the subject (mostly, peer process)
898  * tcontext: security label of the object being referenced
899  * tclass: class code (SEPG_CLASS_*) of the object being referenced
900  * required: a mask of required permissions (SEPG_<class>__<perm>)
901  * audit_name: a human-readable object name for audit logs, or NULL.
902  * abort_on_violation: true, if error shall be raised on access violation
903  */
904 bool
905 sepgsql_check_perms(const char *scontext,
906  const char *tcontext,
907  uint16 tclass,
909  const char *audit_name,
910  bool abort_on_violation)
911 {
912  struct av_decision avd;
913  uint32 denied;
914  uint32 audited;
915  bool result = true;
916  bool enforcing;
917 
918  sepgsql_compute_avd(scontext, tcontext, tclass, &avd);
919 
920  denied = required & ~avd.allowed;
921 
923  audited = (denied ? denied : required);
924  else
925  audited = (denied ? (denied & avd.auditdeny)
926  : (required & avd.auditallow));
927 
928  enforcing = sepgsql_getenforce() > 0 &&
929  (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE) == 0;
930 
931  if (denied && enforcing)
932  result = false;
933 
934  /*
935  * It records a security audit for the request, if needed. But, when
936  * SE-PgSQL performs 'internal' mode, it needs to keep silent.
937  */
938  if (audited && sepgsql_mode != SEPGSQL_MODE_INTERNAL)
939  {
940  sepgsql_audit_log(denied,
941  enforcing,
942  scontext,
943  tcontext,
944  tclass,
945  audited,
946  audit_name);
947  }
948 
949  if (!result && abort_on_violation)
950  ereport(ERROR,
951  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
952  errmsg("SELinux: security policy violation")));
953  return result;
954 }
unsigned short uint16
Definition: c.h:440
unsigned int uint32
Definition: c.h:441
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define LOG
Definition: elog.h:25
#define PG_END_TRY()
Definition: elog.h:324
#define PG_TRY()
Definition: elog.h:299
#define PG_FINALLY()
Definition: elog.h:316
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
bool sepgsql_get_debug_audit(void)
Definition: hooks.c:75
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
char * pstrdup(const char *in)
Definition: mcxt.c:1305
static char * buf
Definition: pg_test_fsync.c:67
struct @10::@11 av[32]
int sepgsql_get_mode(void)
Definition: selinux.c:625
void sepgsql_compute_avd(const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
Definition: selinux.c:739
static int sepgsql_mode
Definition: selinux.c:610
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:842
void sepgsql_audit_log(bool denied, bool enforcing, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
Definition: selinux.c:678
const char * av_name
Definition: selinux.c:36
bool sepgsql_check_perms(const char *scontext, const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: selinux.c:905
uint16 class_code
Definition: selinux.c:33
const char * class_name
Definition: selinux.c:32
int sepgsql_set_mode(int new_mode)
Definition: selinux.c:634
static struct @10 selinux_catalog[]
bool sepgsql_is_enabled(void)
Definition: selinux.c:616
uint32 av_code
Definition: selinux.c:37
bool sepgsql_getenforce(void)
Definition: selinux.c:651
#define SEPG_DIR__RENAME
Definition: sepgsql.h:76
#define SEPG_DB_BLOB__WRITE
Definition: sepgsql.h:194
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:170
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:173
#define SEPG_DB_TABLE__GETATTR
Definition: sepgsql.h:139
#define SEPG_SOCK_FILE__RENAME
Definition: sepgsql.h:109
#define SEPGSQL_MODE_INTERNAL
Definition: sepgsql.h:30
#define SEPG_FIFO_FILE__READ
Definition: sepgsql.h:111
#define SEPG_DB_SCHEMA__DROP
Definition: sepgsql.h:128
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define SEPG_DB_PROCEDURE__CREATE
Definition: sepgsql.h:160
#define SEPG_DB_LANGUAGE__RELABELTO
Definition: sepgsql.h:203
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define SEPG_FIFO_FILE__WRITE
Definition: sepgsql.h:112
#define SEPG_DB_SCHEMA__SETATTR
Definition: sepgsql.h:130
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
#define SEPG_DB_BLOB__EXPORT
Definition: sepgsql.h:196
#define SEPG_DB_SCHEMA__CREATE
Definition: sepgsql.h:127
#define SEPG_BLK_FILE__CREATE
Definition: sepgsql.h:99
#define SEPG_CLASS_DB_DATABASE
Definition: sepgsql.h:44
#define SEPG_DB_PROCEDURE__RELABELFROM
Definition: sepgsql.h:164
#define SEPG_DB_BLOB__READ
Definition: sepgsql.h:193
#define SEPG_DB_TABLE__CREATE
Definition: sepgsql.h:137
#define SEPG_DB_SEQUENCE__CREATE
Definition: sepgsql.h:150
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
#define SEPG_DIR__SEARCH
Definition: sepgsql.h:77
#define SEPG_DB_LANGUAGE__GETATTR
Definition: sepgsql.h:200
#define SEPG_DB_SEQUENCE__SETATTR
Definition: sepgsql.h:153
#define SEPG_DB_TABLE__DELETE
Definition: sepgsql.h:146
#define SEPG_CLASS_BLK_FILE
Definition: sepgsql.h:41
#define SEPG_DB_TABLE__LOCK
Definition: sepgsql.h:147
#define SEPG_CLASS_FIFO_FILE
Definition: sepgsql.h:43
#define SEPG_CLASS_DIR
Definition: sepgsql.h:38
#define SEPG_DB_LANGUAGE__DROP
Definition: sepgsql.h:199
#define SEPG_DB_SEQUENCE__RELABELFROM
Definition: sepgsql.h:154
#define SEPG_CLASS_CHR_FILE
Definition: sepgsql.h:40
#define SEPG_CHR_FILE__READ
Definition: sepgsql.h:90
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
#define SEPG_DB_VIEW__RELABELTO
Definition: sepgsql.h:212
#define SEPG_DB_TABLE__TRUNCATE
Definition: sepgsql.h:148
#define SEPG_FILE__UNLINK
Definition: sepgsql.h:67
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:171
#define SEPG_DB_BLOB__SETATTR
Definition: sepgsql.h:190
#define SEPG_DB_TABLE__RELABELFROM
Definition: sepgsql.h:141
#define SEPG_DB_PROCEDURE__INSTALL
Definition: sepgsql.h:168
#define SEPG_CLASS_LNK_FILE
Definition: sepgsql.h:39
#define SEPG_CLASS_FILE
Definition: sepgsql.h:37
#define SEPG_FILE__CREATE
Definition: sepgsql.h:65
#define SEPG_LNK_FILE__CREATE
Definition: sepgsql.h:85
#define SEPG_CHR_FILE__WRITE
Definition: sepgsql.h:91
#define SEPG_DB_TUPLE__RELABELTO
Definition: sepgsql.h:181
#define SEPG_DB_DATABASE__ACCESS
Definition: sepgsql.h:124
#define SEPG_FILE__RENAME
Definition: sepgsql.h:68
#define SEPG_FILE__READ
Definition: sepgsql.h:63
#define SEPG_CHR_FILE__UNLINK
Definition: sepgsql.h:94
#define SEPG_CHR_FILE__CREATE
Definition: sepgsql.h:92
#define SEPG_DB_VIEW__CREATE
Definition: sepgsql.h:207
#define SEPG_DB_PROCEDURE__GETATTR
Definition: sepgsql.h:162
#define SEPG_DB_TABLE__INSERT
Definition: sepgsql.h:145
#define SEPG_CLASS_SOCK_FILE
Definition: sepgsql.h:42
#define SEPG_SOCK_FILE__GETATTR
Definition: sepgsql.h:107
#define SEPG_FILE__APPEND
Definition: sepgsql.h:69
#define SEPG_DB_COLUMN__RELABELTO
Definition: sepgsql.h:175
#define SEPG_BLK_FILE__UNLINK
Definition: sepgsql.h:101
#define SEPG_DB_PROCEDURE__DROP
Definition: sepgsql.h:161
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_PROCEDURE__EXECUTE
Definition: sepgsql.h:166
#define SEPG_DB_SEQUENCE__RELABELTO
Definition: sepgsql.h:155
#define SEPG_BLK_FILE__RENAME
Definition: sepgsql.h:102
#define SEPG_BLK_FILE__WRITE
Definition: sepgsql.h:98
#define SEPG_DB_LANGUAGE__RELABELFROM
Definition: sepgsql.h:202
#define SEPG_DB_LANGUAGE__EXECUTE
Definition: sepgsql.h:205
#define SEPG_DB_SEQUENCE__GETATTR
Definition: sepgsql.h:152
#define SEPG_DB_DATABASE__SETATTR
Definition: sepgsql.h:121
#define SEPG_DB_BLOB__IMPORT
Definition: sepgsql.h:195
#define SEPG_FILE__GETATTR
Definition: sepgsql.h:66
#define SEPG_DB_VIEW__RELABELFROM
Definition: sepgsql.h:211
#define SEPG_DIR__ADD_NAME
Definition: sepgsql.h:78
#define SEPG_PROCESS__SETCURRENT
Definition: sepgsql.h:61
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142
#define SEPG_DIR__WRITE
Definition: sepgsql.h:72
#define SEPG_DB_LANGUAGE__IMPLEMENT
Definition: sepgsql.h:204
#define SEPG_DB_TUPLE__SELECT
Definition: sepgsql.h:182
#define SEPG_FILE__WRITE
Definition: sepgsql.h:64
#define SEPG_DB_TUPLE__INSERT
Definition: sepgsql.h:184
#define SEPG_CLASS_MAX
Definition: sepgsql.h:54
#define SEPG_DB_TABLE__UPDATE
Definition: sepgsql.h:144
#define SEPG_LNK_FILE__WRITE
Definition: sepgsql.h:84
#define SEPG_CHR_FILE__GETATTR
Definition: sepgsql.h:93
#define SEPG_DB_BLOB__RELABELTO
Definition: sepgsql.h:192
#define SEPG_DB_VIEW__EXPAND
Definition: sepgsql.h:213
#define SEPG_PROCESS__TRANSITION
Definition: sepgsql.h:59
#define SEPG_DB_SEQUENCE__NEXT_VALUE
Definition: sepgsql.h:157
#define SEPG_DB_BLOB__GETATTR
Definition: sepgsql.h:189
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:174
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:165
#define SEPG_DB_COLUMN__GETATTR
Definition: sepgsql.h:172
#define SEPG_DB_DATABASE__RELABELTO
Definition: sepgsql.h:123
#define SEPG_DB_TUPLE__UPDATE
Definition: sepgsql.h:183
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_DB_BLOB__CREATE
Definition: sepgsql.h:187
#define SEPG_DIR__RMDIR
Definition: sepgsql.h:80
#define SEPG_SOCK_FILE__READ
Definition: sepgsql.h:104
#define SEPG_DB_SCHEMA__RELABELFROM
Definition: sepgsql.h:131
#define SEPG_PROCESS__DYNTRANSITION
Definition: sepgsql.h:60
#define SEPG_DB_TUPLE__RELABELFROM
Definition: sepgsql.h:180
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:167
#define SEPG_DIR__READ
Definition: sepgsql.h:71
#define SEPG_DB_PROCEDURE__SETATTR
Definition: sepgsql.h:163
#define SEPG_DIR__UNLINK
Definition: sepgsql.h:75
#define SEPG_DB_LANGUAGE__CREATE
Definition: sepgsql.h:198
#define SEPG_SOCK_FILE__WRITE
Definition: sepgsql.h:105
#define SEPG_LNK_FILE__UNLINK
Definition: sepgsql.h:87
#define SEPG_BLK_FILE__GETATTR
Definition: sepgsql.h:100
#define SEPG_DB_TUPLE__DELETE
Definition: sepgsql.h:185
#define SEPG_CLASS_DB_LANGUAGE
Definition: sepgsql.h:52
#define SEPG_LNK_FILE__READ
Definition: sepgsql.h:83
#define SEPG_DB_DATABASE__DROP
Definition: sepgsql.h:119
#define SEPG_LNK_FILE__RENAME
Definition: sepgsql.h:88
#define SEPG_DIR__GETATTR
Definition: sepgsql.h:74
#define SEPG_DB_DATABASE__GETATTR
Definition: sepgsql.h:120
#define SEPG_DIR__REMOVE_NAME
Definition: sepgsql.h:79
#define SEPG_DB_DATABASE__LOAD_MODULE
Definition: sepgsql.h:125
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
#define SEPG_DB_TABLE__DROP
Definition: sepgsql.h:138
#define SEPG_DB_SCHEMA__GETATTR
Definition: sepgsql.h:129
#define SEPG_LNK_FILE__GETATTR
Definition: sepgsql.h:86
#define SEPG_DB_VIEW__GETATTR
Definition: sepgsql.h:209
#define SEPG_DB_COLUMN__INSERT
Definition: sepgsql.h:178
#define SEPG_DIR__REPARENT
Definition: sepgsql.h:81
#define SEPG_DB_SCHEMA__SEARCH
Definition: sepgsql.h:133
#define SEPG_SOCK_FILE__CREATE
Definition: sepgsql.h:106
#define SEPG_DB_COLUMN__SELECT
Definition: sepgsql.h:176
#define SEPG_DB_TABLE__SELECT
Definition: sepgsql.h:143
#define SEPG_DB_COLUMN__UPDATE
Definition: sepgsql.h:177
#define SEPG_CHR_FILE__RENAME
Definition: sepgsql.h:95
#define SEPG_DB_VIEW__SETATTR
Definition: sepgsql.h:210
#define SEPG_FIFO_FILE__CREATE
Definition: sepgsql.h:113
#define SEPG_DB_BLOB__RELABELFROM
Definition: sepgsql.h:191
#define SEPG_FIFO_FILE__GETATTR
Definition: sepgsql.h:114
#define SEPG_DIR__CREATE
Definition: sepgsql.h:73
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
#define SEPG_DB_LANGUAGE__SETATTR
Definition: sepgsql.h:201
#define SEPG_DB_SCHEMA__RELABELTO
Definition: sepgsql.h:132
#define SEPG_DB_SEQUENCE__SET_VALUE
Definition: sepgsql.h:158
#define SEPG_CLASS_PROCESS
Definition: sepgsql.h:36
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_DB_BLOB__DROP
Definition: sepgsql.h:188
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define SEPG_BLK_FILE__READ
Definition: sepgsql.h:97
#define SEPG_CLASS_DB_TUPLE
Definition: sepgsql.h:50
#define SEPG_DB_SEQUENCE__DROP
Definition: sepgsql.h:151
#define SEPGSQL_MODE_DISABLED
Definition: sepgsql.h:31
#define SEPG_DB_DATABASE__RELABELFROM
Definition: sepgsql.h:122
#define SEPG_CLASS_DB_BLOB
Definition: sepgsql.h:51
#define SEPG_FIFO_FILE__UNLINK
Definition: sepgsql.h:115
#define SEPG_DB_VIEW__DROP
Definition: sepgsql.h:208
#define SEPG_DB_SEQUENCE__GET_VALUE
Definition: sepgsql.h:156
#define SEPG_SOCK_FILE__UNLINK
Definition: sepgsql.h:108
#define SEPG_FIFO_FILE__RENAME
Definition: sepgsql.h:116
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59