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-2020, 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 {
618  return (sepgsql_mode != SEPGSQL_MODE_DISABLED ? true : false);
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  const char *scontext,
680  const char *tcontext,
681  uint16 tclass,
682  uint32 audited,
683  const char *audit_name)
684 {
686  const char *class_name;
687  const char *av_name;
688  int i;
689 
690  /* lookup name of the object class */
691  Assert(tclass < SEPG_CLASS_MAX);
692  class_name = selinux_catalog[tclass].class_name;
693 
694  /* lookup name of the permissions */
695  initStringInfo(&buf);
696  appendStringInfo(&buf, "%s {",
697  (denied ? "denied" : "allowed"));
698  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
699  {
700  if (audited & (1UL << i))
701  {
702  av_name = selinux_catalog[tclass].av[i].av_name;
703  appendStringInfo(&buf, " %s", av_name);
704  }
705  }
706  appendStringInfoString(&buf, " }");
707 
708  /*
709  * Call external audit module, if loaded
710  */
711  appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
712  scontext, tcontext, class_name);
713  if (audit_name)
714  appendStringInfo(&buf, " name=\"%s\"", audit_name);
715 
716  ereport(LOG, (errmsg("SELinux: %s", buf.data)));
717 }
718 
719 /*
720  * sepgsql_compute_avd
721  *
722  * It actually asks SELinux what permissions are allowed on a pair of
723  * the security contexts and object class. It also returns what permissions
724  * should be audited on access violation or allowed.
725  * In most cases, subject's security context (scontext) is a client, and
726  * target security context (tcontext) is a database object.
727  *
728  * The access control decision shall be set on the given av_decision.
729  * The av_decision.allowed has a bitmask of SEPG_<class>__<perms>
730  * to suggest a set of allowed actions in this object class.
731  */
732 void
733 sepgsql_compute_avd(const char *scontext,
734  const char *tcontext,
735  uint16 tclass,
736  struct av_decision *avd)
737 {
738  const char *tclass_name;
739  security_class_t tclass_ex;
740  struct av_decision avd_ex;
741  int i,
742  deny_unknown = security_deny_unknown();
743 
744  /* Get external code of the object class */
745  Assert(tclass < SEPG_CLASS_MAX);
746  Assert(tclass == selinux_catalog[tclass].class_code);
747 
748  tclass_name = selinux_catalog[tclass].class_name;
749  tclass_ex = string_to_security_class(tclass_name);
750 
751  if (tclass_ex == 0)
752  {
753  /*
754  * If the current security policy does not support permissions
755  * corresponding to database objects, we fill up them with dummy data.
756  * If security_deny_unknown() returns positive value, undefined
757  * permissions should be denied. Otherwise, allowed
758  */
759  avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0);
760  avd->auditallow = 0U;
761  avd->auditdeny = ~0U;
762  avd->flags = 0;
763 
764  return;
765  }
766 
767  /*
768  * Ask SELinux what is allowed set of permissions on a pair of the
769  * security contexts and the given object class.
770  */
771  if (security_compute_av_flags_raw((security_context_t) scontext,
772  (security_context_t) tcontext,
773  tclass_ex, 0, &avd_ex) < 0)
774  ereport(ERROR,
775  (errcode(ERRCODE_INTERNAL_ERROR),
776  errmsg("SELinux could not compute av_decision: "
777  "scontext=%s tcontext=%s tclass=%s: %m",
778  scontext, tcontext, tclass_name)));
779 
780  /*
781  * SELinux returns its access control decision as a set of permissions
782  * represented in external code which depends on run-time environment. So,
783  * we need to translate it to the internal representation before returning
784  * results for the caller.
785  */
786  memset(avd, 0, sizeof(struct av_decision));
787 
788  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
789  {
790  access_vector_t av_code_ex;
791  const char *av_name = selinux_catalog[tclass].av[i].av_name;
792  uint32 av_code = selinux_catalog[tclass].av[i].av_code;
793 
794  av_code_ex = string_to_av_perm(tclass_ex, av_name);
795  if (av_code_ex == 0)
796  {
797  /* fill up undefined permissions */
798  if (!deny_unknown)
799  avd->allowed |= av_code;
800  avd->auditdeny |= av_code;
801 
802  continue;
803  }
804 
805  if (avd_ex.allowed & av_code_ex)
806  avd->allowed |= av_code;
807  if (avd_ex.auditallow & av_code_ex)
808  avd->auditallow |= av_code;
809  if (avd_ex.auditdeny & av_code_ex)
810  avd->auditdeny |= av_code;
811  }
812 }
813 
814 /*
815  * sepgsql_compute_create
816  *
817  * It returns a default security context to be assigned on a new database
818  * object. SELinux compute it based on a combination of client, upper object
819  * which owns the new object and object class.
820  *
821  * For example, when a client (staff_u:staff_r:staff_t:s0) tries to create
822  * a new table within a schema (system_u:object_r:sepgsql_schema_t:s0),
823  * SELinux looks-up its security policy. If it has a special rule on the
824  * combination of these security contexts and object class (db_table),
825  * it returns the security context suggested by the special rule.
826  * Otherwise, it returns the security context of schema, as is.
827  *
828  * We expect the caller already applies sanity/validation checks on the
829  * given security context.
830  *
831  * scontext: security context of the subject (mostly, peer process).
832  * tcontext: security context of the upper database object.
833  * tclass: class code (SEPG_CLASS_*) of the new object in creation
834  */
835 char *
836 sepgsql_compute_create(const char *scontext,
837  const char *tcontext,
838  uint16 tclass,
839  const char *objname)
840 {
841  security_context_t ncontext;
842  security_class_t tclass_ex;
843  const char *tclass_name;
844  char *result;
845 
846  /* Get external code of the object class */
847  Assert(tclass < SEPG_CLASS_MAX);
848 
849  tclass_name = selinux_catalog[tclass].class_name;
850  tclass_ex = string_to_security_class(tclass_name);
851 
852  /*
853  * Ask SELinux what is the default context for the given object class on a
854  * pair of security contexts
855  */
856  if (security_compute_create_name_raw((security_context_t) scontext,
857  (security_context_t) tcontext,
858  tclass_ex,
859  objname,
860  &ncontext) < 0)
861  ereport(ERROR,
862  (errcode(ERRCODE_INTERNAL_ERROR),
863  errmsg("SELinux could not compute a new context: "
864  "scontext=%s tcontext=%s tclass=%s: %m",
865  scontext, tcontext, tclass_name)));
866 
867  /*
868  * libselinux returns malloc()'ed string, so we need to copy it on the
869  * palloc()'ed region.
870  */
871  PG_TRY();
872  {
873  result = pstrdup(ncontext);
874  }
875  PG_FINALLY();
876  {
877  freecon(ncontext);
878  }
879  PG_END_TRY();
880 
881  return result;
882 }
883 
884 /*
885  * sepgsql_check_perms
886  *
887  * It makes access control decision without userspace caching mechanism.
888  * If SELinux denied the required accesses on the pair of security labels,
889  * it raises an error or returns false.
890  *
891  * scontext: security label of the subject (mostly, peer process)
892  * tcontext: security label of the object being referenced
893  * tclass: class code (SEPG_CLASS_*) of the object being referenced
894  * required: a mask of required permissions (SEPG_<class>__<perm>)
895  * audit_name: a human readable object name for audit logs, or NULL.
896  * abort_on_violation: true, if error shall be raised on access violation
897  */
898 bool
899 sepgsql_check_perms(const char *scontext,
900  const char *tcontext,
901  uint16 tclass,
903  const char *audit_name,
904  bool abort_on_violation)
905 {
906  struct av_decision avd;
907  uint32 denied;
908  uint32 audited;
909  bool result = true;
910 
911  sepgsql_compute_avd(scontext, tcontext, tclass, &avd);
912 
913  denied = required & ~avd.allowed;
914 
916  audited = (denied ? denied : required);
917  else
918  audited = (denied ? (denied & avd.auditdeny)
919  : (required & avd.auditallow));
920 
921  if (denied &&
922  sepgsql_getenforce() > 0 &&
923  (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE) == 0)
924  result = false;
925 
926  /*
927  * It records a security audit for the request, if needed. But, when
928  * SE-PgSQL performs 'internal' mode, it needs to keep silent.
929  */
930  if (audited && sepgsql_mode != SEPGSQL_MODE_INTERNAL)
931  {
932  sepgsql_audit_log(denied,
933  scontext,
934  tcontext,
935  tclass,
936  audited,
937  audit_name);
938  }
939 
940  if (!result && abort_on_violation)
941  ereport(ERROR,
942  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
943  errmsg("SELinux: security policy violation")));
944  return result;
945 }
#define SEPG_DB_PROCEDURE__GETATTR
Definition: sepgsql.h:162
#define SEPG_DB_PROCEDURE__DROP
Definition: sepgsql.h:161
#define SEPG_LNK_FILE__RENAME
Definition: sepgsql.h:88
#define SEPGSQL_MODE_INTERNAL
Definition: sepgsql.h:30
#define SEPG_DB_SCHEMA__DROP
Definition: sepgsql.h:128
#define SEPG_DB_PROCEDURE__EXECUTE
Definition: sepgsql.h:166
#define SEPG_CHR_FILE__UNLINK
Definition: sepgsql.h:94
#define SEPG_BLK_FILE__GETATTR
Definition: sepgsql.h:100
#define SEPG_DB_VIEW__EXPAND
Definition: sepgsql.h:213
static int sepgsql_mode
Definition: selinux.c:610
#define SEPG_CLASS_DB_TUPLE
Definition: sepgsql.h:50
#define SEPG_BLK_FILE__RENAME
Definition: sepgsql.h:102
#define SEPG_DB_TUPLE__INSERT
Definition: sepgsql.h:184
#define SEPG_CHR_FILE__GETATTR
Definition: sepgsql.h:93
#define SEPG_CLASS_MAX
Definition: sepgsql.h:54
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_LNK_FILE__UNLINK
Definition: sepgsql.h:87
#define SEPG_DIR__RMDIR
Definition: sepgsql.h:80
#define SEPG_CLASS_SOCK_FILE
Definition: sepgsql.h:42
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:173
#define SEPG_DIR__REPARENT
Definition: sepgsql.h:81
#define SEPG_DIR__ADD_NAME
Definition: sepgsql.h:78
const char * av_name
Definition: selinux.c:36
#define SEPG_DIR__UNLINK
Definition: sepgsql.h:75
#define SEPG_PROCESS__DYNTRANSITION
Definition: sepgsql.h:60
#define SEPG_SOCK_FILE__UNLINK
Definition: sepgsql.h:108
#define SEPG_DB_COLUMN__RELABELTO
Definition: sepgsql.h:175
#define SEPG_FILE__CREATE
Definition: sepgsql.h:65
#define SEPG_DB_TABLE__TRUNCATE
Definition: sepgsql.h:148
#define SEPG_DB_LANGUAGE__CREATE
Definition: sepgsql.h:198
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define SEPG_DB_VIEW__RELABELTO
Definition: sepgsql.h:212
void sepgsql_compute_avd(const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
Definition: selinux.c:733
#define SEPG_DB_VIEW__SETATTR
Definition: sepgsql.h:210
#define SEPG_DB_TUPLE__RELABELFROM
Definition: sepgsql.h:180
#define SEPG_DB_LANGUAGE__RELABELTO
Definition: sepgsql.h:203
#define SEPG_DB_TABLE__DELETE
Definition: sepgsql.h:146
#define SEPG_DB_SEQUENCE__GETATTR
Definition: sepgsql.h:152
#define SEPG_SOCK_FILE__GETATTR
Definition: sepgsql.h:107
#define SEPG_DIR__WRITE
Definition: sepgsql.h:72
#define SEPG_LNK_FILE__READ
Definition: sepgsql.h:83
int errcode(int sqlerrcode)
Definition: elog.c:608
#define SEPG_SOCK_FILE__CREATE
Definition: sepgsql.h:106
bool sepgsql_getenforce(void)
Definition: selinux.c:651
#define SEPG_CHR_FILE__WRITE
Definition: sepgsql.h:91
#define SEPGSQL_MODE_DISABLED
Definition: sepgsql.h:31
#define SEPG_DB_COLUMN__INSERT
Definition: sepgsql.h:178
#define SEPG_SOCK_FILE__READ
Definition: sepgsql.h:104
#define SEPG_DB_SCHEMA__GETATTR
Definition: sepgsql.h:129
#define SEPG_LNK_FILE__CREATE
Definition: sepgsql.h:85
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define SEPG_DB_DATABASE__RELABELFROM
Definition: sepgsql.h:122
#define SEPG_PROCESS__TRANSITION
Definition: sepgsql.h:59
#define LOG
Definition: elog.h:26
#define SEPG_CLASS_FIFO_FILE
Definition: sepgsql.h:43
#define SEPG_CLASS_BLK_FILE
Definition: sepgsql.h:41
#define SEPG_DB_BLOB__CREATE
Definition: sepgsql.h:187
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:174
#define SEPG_BLK_FILE__UNLINK
Definition: sepgsql.h:101
#define SEPG_DB_TUPLE__DELETE
Definition: sepgsql.h:185
#define SEPG_FILE__WRITE
Definition: sepgsql.h:64
#define SEPG_DB_SEQUENCE__SETATTR
Definition: sepgsql.h:153
#define SEPG_CLASS_DB_DATABASE
Definition: sepgsql.h:44
#define SEPG_DB_COLUMN__GETATTR
Definition: sepgsql.h:172
#define SEPG_CLASS_CHR_FILE
Definition: sepgsql.h:40
#define SEPG_FILE__RENAME
Definition: sepgsql.h:68
#define SEPG_SOCK_FILE__RENAME
Definition: sepgsql.h:109
#define SEPG_DIR__SEARCH
Definition: sepgsql.h:77
#define SEPG_DB_LANGUAGE__DROP
Definition: sepgsql.h:199
#define SEPG_DB_SCHEMA__RELABELFROM
Definition: sepgsql.h:131
#define SEPG_DB_SEQUENCE__RELABELFROM
Definition: sepgsql.h:154
#define SEPG_DB_TUPLE__SELECT
Definition: sepgsql.h:182
#define SEPG_DB_LANGUAGE__SETATTR
Definition: sepgsql.h:201
#define SEPG_DB_TABLE__SELECT
Definition: sepgsql.h:143
#define SEPG_CLASS_PROCESS
Definition: sepgsql.h:36
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
#define SEPG_DB_BLOB__RELABELTO
Definition: sepgsql.h:192
int sepgsql_get_mode(void)
Definition: selinux.c:625
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
unsigned short uint16
Definition: c.h:358
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define SEPG_FIFO_FILE__WRITE
Definition: sepgsql.h:112
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define SEPG_DB_PROCEDURE__CREATE
Definition: sepgsql.h:160
#define ERROR
Definition: elog.h:43
#define SEPG_DB_LANGUAGE__IMPLEMENT
Definition: sepgsql.h:204
#define SEPG_DB_BLOB__DROP
Definition: sepgsql.h:188
#define SEPG_DB_COLUMN__SELECT
Definition: sepgsql.h:176
#define SEPG_DB_SEQUENCE__GET_VALUE
Definition: sepgsql.h:156
void sepgsql_audit_log(bool denied, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
Definition: selinux.c:678
#define SEPG_DB_VIEW__CREATE
Definition: sepgsql.h:207
#define SEPG_LNK_FILE__WRITE
Definition: sepgsql.h:84
uint32 av_code
Definition: selinux.c:37
#define SEPG_FIFO_FILE__GETATTR
Definition: sepgsql.h:114
#define SEPG_DB_TABLE__UPDATE
Definition: sepgsql.h:144
int sepgsql_set_mode(int new_mode)
Definition: selinux.c:634
#define SEPG_FILE__READ
Definition: sepgsql.h:63
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define SEPG_DB_PROCEDURE__RELABELFROM
Definition: sepgsql.h:164
bool sepgsql_get_debug_audit(void)
Definition: hooks.c:75
#define SEPG_DB_TABLE__INSERT
Definition: sepgsql.h:145
static char * buf
Definition: pg_test_fsync.c:67
#define SEPG_DB_BLOB__GETATTR
Definition: sepgsql.h:189
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
#define SEPG_BLK_FILE__READ
Definition: sepgsql.h:97
static struct @18 selinux_catalog[]
#define SEPG_DB_VIEW__GETATTR
Definition: sepgsql.h:209
#define SEPG_DB_TABLE__DROP
Definition: sepgsql.h:138
unsigned int uint32
Definition: c.h:359
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:165
#define SEPG_DB_SEQUENCE__RELABELTO
Definition: sepgsql.h:155
#define SEPG_DB_BLOB__WRITE
Definition: sepgsql.h:194
#define SEPG_DB_SEQUENCE__NEXT_VALUE
Definition: sepgsql.h:157
#define SEPG_DB_SEQUENCE__SET_VALUE
Definition: sepgsql.h:158
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142
#define SEPG_DB_BLOB__RELABELFROM
Definition: sepgsql.h:191
#define ereport(elevel, rest)
Definition: elog.h:141
#define SEPG_FIFO_FILE__UNLINK
Definition: sepgsql.h:115
#define SEPG_FIFO_FILE__CREATE
Definition: sepgsql.h:113
#define SEPG_DB_DATABASE__GETATTR
Definition: sepgsql.h:120
#define SEPG_DB_COLUMN__UPDATE
Definition: sepgsql.h:177
#define SEPG_DB_TUPLE__UPDATE
Definition: sepgsql.h:183
#define SEPG_CHR_FILE__RENAME
Definition: sepgsql.h:95
#define SEPG_DB_BLOB__EXPORT
Definition: sepgsql.h:196
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_CHR_FILE__CREATE
Definition: sepgsql.h:92
#define SEPG_DB_SCHEMA__SEARCH
Definition: sepgsql.h:133
struct @18::@19 av[32]
#define PG_FINALLY()
Definition: elog.h:339
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:171
#define SEPG_FILE__UNLINK
Definition: sepgsql.h:67
#define SEPG_LNK_FILE__GETATTR
Definition: sepgsql.h:86
#define SEPG_DB_BLOB__READ
Definition: sepgsql.h:193
#define SEPG_CLASS_FILE
Definition: sepgsql.h:37
#define SEPG_DB_TABLE__RELABELFROM
Definition: sepgsql.h:141
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_DATABASE__DROP
Definition: sepgsql.h:119
#define SEPG_DB_SCHEMA__SETATTR
Definition: sepgsql.h:130
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:899
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:170
#define SEPG_DIR__READ
Definition: sepgsql.h:71
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define SEPG_DB_VIEW__RELABELFROM
Definition: sepgsql.h:211
uint16 class_code
Definition: selinux.c:33
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:167
bool sepgsql_is_enabled(void)
Definition: selinux.c:616
#define Assert(condition)
Definition: c.h:739
#define SEPG_DIR__REMOVE_NAME
Definition: sepgsql.h:79
#define SEPG_CLASS_DIR
Definition: sepgsql.h:38
#define SEPG_DB_DATABASE__SETATTR
Definition: sepgsql.h:121
#define SEPG_DB_SEQUENCE__CREATE
Definition: sepgsql.h:150
#define SEPG_DB_LANGUAGE__EXECUTE
Definition: sepgsql.h:205
#define SEPG_DB_TABLE__CREATE
Definition: sepgsql.h:137
const char * class_name
Definition: selinux.c:32
#define SEPG_DB_SCHEMA__CREATE
Definition: sepgsql.h:127
#define SEPG_DB_TABLE__GETATTR
Definition: sepgsql.h:139
#define SEPG_DB_VIEW__DROP
Definition: sepgsql.h:208
#define SEPG_BLK_FILE__CREATE
Definition: sepgsql.h:99
#define SEPG_FIFO_FILE__RENAME
Definition: sepgsql.h:116
#define SEPG_DB_DATABASE__RELABELTO
Definition: sepgsql.h:123
#define SEPG_DIR__GETATTR
Definition: sepgsql.h:74
#define SEPG_DIR__RENAME
Definition: sepgsql.h:76
#define SEPG_PROCESS__SETCURRENT
Definition: sepgsql.h:61
#define SEPG_DB_DATABASE__ACCESS
Definition: sepgsql.h:124
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:836
#define SEPG_DB_LANGUAGE__GETATTR
Definition: sepgsql.h:200
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define SEPG_DB_SEQUENCE__DROP
Definition: sepgsql.h:151
#define SEPG_FILE__GETATTR
Definition: sepgsql.h:66
#define SEPG_SOCK_FILE__WRITE
Definition: sepgsql.h:105
#define SEPG_CLASS_DB_BLOB
Definition: sepgsql.h:51
#define SEPG_DB_BLOB__SETATTR
Definition: sepgsql.h:190
int i
#define SEPG_BLK_FILE__WRITE
Definition: sepgsql.h:98
#define SEPG_DB_LANGUAGE__RELABELFROM
Definition: sepgsql.h:202
#define SEPG_CLASS_DB_LANGUAGE
Definition: sepgsql.h:52
#define SEPG_DIR__CREATE
Definition: sepgsql.h:73
#define SEPG_CHR_FILE__READ
Definition: sepgsql.h:90
#define PG_TRY()
Definition: elog.h:322
#define SEPG_DB_TUPLE__RELABELTO
Definition: sepgsql.h:181
#define SEPG_DB_DATABASE__LOAD_MODULE
Definition: sepgsql.h:125
#define SEPG_FIFO_FILE__READ
Definition: sepgsql.h:111
#define SEPG_DB_PROCEDURE__SETATTR
Definition: sepgsql.h:163
#define SEPG_DB_SCHEMA__RELABELTO
Definition: sepgsql.h:132
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
#define SEPG_DB_TABLE__LOCK
Definition: sepgsql.h:147
#define PG_END_TRY()
Definition: elog.h:347
#define SEPG_DB_PROCEDURE__INSTALL
Definition: sepgsql.h:168
#define SEPG_FILE__APPEND
Definition: sepgsql.h:69
#define SEPG_CLASS_LNK_FILE
Definition: sepgsql.h:39
#define SEPG_DB_BLOB__IMPORT
Definition: sepgsql.h:195