PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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  NULL, 0UL
364  },
365  }
366  },
367  {
368  "db_sequence", SEPG_CLASS_DB_SEQUENCE,
369  {
370  {
371  "create", SEPG_DB_SEQUENCE__CREATE
372  },
373  {
374  "drop", SEPG_DB_SEQUENCE__DROP
375  },
376  {
377  "getattr", SEPG_DB_SEQUENCE__GETATTR
378  },
379  {
380  "setattr", SEPG_DB_SEQUENCE__SETATTR
381  },
382  {
383  "relabelfrom", SEPG_DB_SEQUENCE__RELABELFROM
384  },
385  {
386  "relabelto", SEPG_DB_SEQUENCE__RELABELTO
387  },
388  {
389  "get_value", SEPG_DB_SEQUENCE__GET_VALUE
390  },
391  {
392  "next_value", SEPG_DB_SEQUENCE__NEXT_VALUE
393  },
394  {
395  "set_value", SEPG_DB_SEQUENCE__SET_VALUE
396  },
397  {
398  NULL, 0UL
399  },
400  }
401  },
402  {
403  "db_procedure", SEPG_CLASS_DB_PROCEDURE,
404  {
405  {
406  "create", SEPG_DB_PROCEDURE__CREATE
407  },
408  {
410  },
411  {
412  "getattr", SEPG_DB_PROCEDURE__GETATTR
413  },
414  {
415  "setattr", SEPG_DB_PROCEDURE__SETATTR
416  },
417  {
418  "relabelfrom", SEPG_DB_PROCEDURE__RELABELFROM
419  },
420  {
421  "relabelto", SEPG_DB_PROCEDURE__RELABELTO
422  },
423  {
424  "execute", SEPG_DB_PROCEDURE__EXECUTE
425  },
426  {
427  "entrypoint", SEPG_DB_PROCEDURE__ENTRYPOINT
428  },
429  {
430  "install", SEPG_DB_PROCEDURE__INSTALL
431  },
432  {
433  NULL, 0UL
434  },
435  }
436  },
437  {
438  "db_column", SEPG_CLASS_DB_COLUMN,
439  {
440  {
441  "create", SEPG_DB_COLUMN__CREATE
442  },
443  {
444  "drop", SEPG_DB_COLUMN__DROP
445  },
446  {
447  "getattr", SEPG_DB_COLUMN__GETATTR
448  },
449  {
450  "setattr", SEPG_DB_COLUMN__SETATTR
451  },
452  {
453  "relabelfrom", SEPG_DB_COLUMN__RELABELFROM
454  },
455  {
456  "relabelto", SEPG_DB_COLUMN__RELABELTO
457  },
458  {
459  "select", SEPG_DB_COLUMN__SELECT
460  },
461  {
462  "update", SEPG_DB_COLUMN__UPDATE
463  },
464  {
465  "insert", SEPG_DB_COLUMN__INSERT
466  },
467  {
468  NULL, 0UL
469  },
470  }
471  },
472  {
473  "db_tuple", SEPG_CLASS_DB_TUPLE,
474  {
475  {
476  "relabelfrom", SEPG_DB_TUPLE__RELABELFROM
477  },
478  {
479  "relabelto", SEPG_DB_TUPLE__RELABELTO
480  },
481  {
482  "select", SEPG_DB_TUPLE__SELECT
483  },
484  {
485  "update", SEPG_DB_TUPLE__UPDATE
486  },
487  {
488  "insert", SEPG_DB_TUPLE__INSERT
489  },
490  {
491  "delete", SEPG_DB_TUPLE__DELETE
492  },
493  {
494  NULL, 0UL
495  },
496  }
497  },
498  {
499  "db_blob", SEPG_CLASS_DB_BLOB,
500  {
501  {
502  "create", SEPG_DB_BLOB__CREATE
503  },
504  {
505  "drop", SEPG_DB_BLOB__DROP
506  },
507  {
508  "getattr", SEPG_DB_BLOB__GETATTR
509  },
510  {
511  "setattr", SEPG_DB_BLOB__SETATTR
512  },
513  {
514  "relabelfrom", SEPG_DB_BLOB__RELABELFROM
515  },
516  {
517  "relabelto", SEPG_DB_BLOB__RELABELTO
518  },
519  {
520  "read", SEPG_DB_BLOB__READ
521  },
522  {
523  "write", SEPG_DB_BLOB__WRITE
524  },
525  {
526  "import", SEPG_DB_BLOB__IMPORT
527  },
528  {
529  "export", SEPG_DB_BLOB__EXPORT
530  },
531  {
532  NULL, 0UL
533  },
534  }
535  },
536  {
537  "db_language", SEPG_CLASS_DB_LANGUAGE,
538  {
539  {
540  "create", SEPG_DB_LANGUAGE__CREATE
541  },
542  {
543  "drop", SEPG_DB_LANGUAGE__DROP
544  },
545  {
546  "getattr", SEPG_DB_LANGUAGE__GETATTR
547  },
548  {
549  "setattr", SEPG_DB_LANGUAGE__SETATTR
550  },
551  {
552  "relabelfrom", SEPG_DB_LANGUAGE__RELABELFROM
553  },
554  {
555  "relabelto", SEPG_DB_LANGUAGE__RELABELTO
556  },
557  {
558  "implement", SEPG_DB_LANGUAGE__IMPLEMENT
559  },
560  {
561  "execute", SEPG_DB_LANGUAGE__EXECUTE
562  },
563  {
564  NULL, 0UL
565  },
566  }
567  },
568  {
569  "db_view", SEPG_CLASS_DB_VIEW,
570  {
571  {
572  "create", SEPG_DB_VIEW__CREATE
573  },
574  {
575  "drop", SEPG_DB_VIEW__DROP
576  },
577  {
578  "getattr", SEPG_DB_VIEW__GETATTR
579  },
580  {
581  "setattr", SEPG_DB_VIEW__SETATTR
582  },
583  {
584  "relabelfrom", SEPG_DB_VIEW__RELABELFROM
585  },
586  {
587  "relabelto", SEPG_DB_VIEW__RELABELTO
588  },
589  {
590  "expand", SEPG_DB_VIEW__EXPAND
591  },
592  {
593  NULL, 0UL
594  },
595  }
596  },
597 };
598 
599 /*
600  * sepgsql_mode
601  *
602  * SEPGSQL_MODE_DISABLED: Disabled on runtime
603  * SEPGSQL_MODE_DEFAULT: Same as system settings
604  * SEPGSQL_MODE_PERMISSIVE: Always permissive mode
605  * SEPGSQL_MODE_INTERNAL: Same as permissive, except for no audit logs
606  */
608 
609 /*
610  * sepgsql_is_enabled
611  */
612 bool
614 {
615  return (sepgsql_mode != SEPGSQL_MODE_DISABLED ? true : false);
616 }
617 
618 /*
619  * sepgsql_get_mode
620  */
621 int
623 {
624  return sepgsql_mode;
625 }
626 
627 /*
628  * sepgsql_set_mode
629  */
630 int
631 sepgsql_set_mode(int new_mode)
632 {
633  int old_mode = sepgsql_mode;
634 
635  sepgsql_mode = new_mode;
636 
637  return old_mode;
638 }
639 
640 /*
641  * sepgsql_getenforce
642  *
643  * It returns whether the current working mode tries to enforce access
644  * control decision, or not. It shall be enforced when sepgsql_mode is
645  * SEPGSQL_MODE_DEFAULT and system is running in enforcing mode.
646  */
647 bool
649 {
651  selinux_status_getenforce() > 0)
652  return true;
653 
654  return false;
655 }
656 
657 /*
658  * sepgsql_audit_log
659  *
660  * It generates a security audit record. In the default, it writes out
661  * audit records into standard PG's logfile. It also allows to set up
662  * external audit log receiver, such as auditd in Linux, using the
663  * sepgsql_audit_hook.
664  *
665  * SELinux can control what should be audited and should not using
666  * "auditdeny" and "auditallow" rules in the security policy. In the
667  * default, all the access violations are audited, and all the access
668  * allowed are not audited. But we can set up the security policy, so
669  * we can have exceptions. So, it is necessary to follow the suggestion
670  * come from the security policy. (av_decision.auditallow and auditdeny)
671  *
672  * Security audit is an important feature, because it enables us to check
673  * what was happen if we have a security incident. In fact, ISO/IEC15408
674  * defines several security functionalities for audit features.
675  */
676 void
677 sepgsql_audit_log(bool denied,
678  const char *scontext,
679  const char *tcontext,
680  uint16 tclass,
681  uint32 audited,
682  const char *audit_name)
683 {
685  const char *class_name;
686  const char *av_name;
687  int i;
688 
689  /* lookup name of the object class */
690  Assert(tclass < SEPG_CLASS_MAX);
691  class_name = selinux_catalog[tclass].class_name;
692 
693  /* lookup name of the permissions */
694  initStringInfo(&buf);
695  appendStringInfo(&buf, "%s {",
696  (denied ? "denied" : "allowed"));
697  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
698  {
699  if (audited & (1UL << i))
700  {
701  av_name = selinux_catalog[tclass].av[i].av_name;
702  appendStringInfo(&buf, " %s", av_name);
703  }
704  }
705  appendStringInfo(&buf, " }");
706 
707  /*
708  * Call external audit module, if loaded
709  */
710  appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
711  scontext, tcontext, class_name);
712  if (audit_name)
713  appendStringInfo(&buf, " name=\"%s\"", audit_name);
714 
715  ereport(LOG, (errmsg("SELinux: %s", buf.data)));
716 }
717 
718 /*
719  * sepgsql_compute_avd
720  *
721  * It actually asks SELinux what permissions are allowed on a pair of
722  * the security contexts and object class. It also returns what permissions
723  * should be audited on access violation or allowed.
724  * In most cases, subject's security context (scontext) is a client, and
725  * target security context (tcontext) is a database object.
726  *
727  * The access control decision shall be set on the given av_decision.
728  * The av_decision.allowed has a bitmask of SEPG_<class>__<perms>
729  * to suggest a set of allowed actions in this object class.
730  */
731 void
732 sepgsql_compute_avd(const char *scontext,
733  const char *tcontext,
734  uint16 tclass,
735  struct av_decision *avd)
736 {
737  const char *tclass_name;
738  security_class_t tclass_ex;
739  struct av_decision avd_ex;
740  int i,
741  deny_unknown = security_deny_unknown();
742 
743  /* Get external code of the object class */
744  Assert(tclass < SEPG_CLASS_MAX);
745  Assert(tclass == selinux_catalog[tclass].class_code);
746 
747  tclass_name = selinux_catalog[tclass].class_name;
748  tclass_ex = string_to_security_class(tclass_name);
749 
750  if (tclass_ex == 0)
751  {
752  /*
753  * If the current security policy does not support permissions
754  * corresponding to database objects, we fill up them with dummy data.
755  * If security_deny_unknown() returns positive value, undefined
756  * permissions should be denied. Otherwise, allowed
757  */
758  avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0);
759  avd->auditallow = 0U;
760  avd->auditdeny = ~0U;
761  avd->flags = 0;
762 
763  return;
764  }
765 
766  /*
767  * Ask SELinux what is allowed set of permissions on a pair of the
768  * security contexts and the given object class.
769  */
770  if (security_compute_av_flags_raw((security_context_t) scontext,
771  (security_context_t) tcontext,
772  tclass_ex, 0, &avd_ex) < 0)
773  ereport(ERROR,
774  (errcode(ERRCODE_INTERNAL_ERROR),
775  errmsg("SELinux could not compute av_decision: "
776  "scontext=%s tcontext=%s tclass=%s: %m",
777  scontext, tcontext, tclass_name)));
778 
779  /*
780  * SELinux returns its access control decision as a set of permissions
781  * represented in external code which depends on run-time environment. So,
782  * we need to translate it to the internal representation before returning
783  * results for the caller.
784  */
785  memset(avd, 0, sizeof(struct av_decision));
786 
787  for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
788  {
789  access_vector_t av_code_ex;
790  const char *av_name = selinux_catalog[tclass].av[i].av_name;
791  uint32 av_code = selinux_catalog[tclass].av[i].av_code;
792 
793  av_code_ex = string_to_av_perm(tclass_ex, av_name);
794  if (av_code_ex == 0)
795  {
796  /* fill up undefined permissions */
797  if (!deny_unknown)
798  avd->allowed |= av_code;
799  avd->auditdeny |= av_code;
800 
801  continue;
802  }
803 
804  if (avd_ex.allowed & av_code_ex)
805  avd->allowed |= av_code;
806  if (avd_ex.auditallow & av_code_ex)
807  avd->auditallow |= av_code;
808  if (avd_ex.auditdeny & av_code_ex)
809  avd->auditdeny |= av_code;
810  }
811 
812  return;
813 }
814 
815 /*
816  * sepgsql_compute_create
817  *
818  * It returns a default security context to be assigned on a new database
819  * object. SELinux compute it based on a combination of client, upper object
820  * which owns the new object and object class.
821  *
822  * For example, when a client (staff_u:staff_r:staff_t:s0) tries to create
823  * a new table within a schema (system_u:object_r:sepgsql_schema_t:s0),
824  * SELinux looks-up its security policy. If it has a special rule on the
825  * combination of these security contexts and object class (db_table),
826  * it returns the security context suggested by the special rule.
827  * Otherwise, it returns the security context of schema, as is.
828  *
829  * We expect the caller already applies sanity/validation checks on the
830  * given security context.
831  *
832  * scontext: security context of the subject (mostly, peer process).
833  * tcontext: security context of the upper database object.
834  * tclass: class code (SEPG_CLASS_*) of the new object in creation
835  */
836 char *
837 sepgsql_compute_create(const char *scontext,
838  const char *tcontext,
839  uint16 tclass,
840  const char *objname)
841 {
842  security_context_t ncontext;
843  security_class_t tclass_ex;
844  const char *tclass_name;
845  char *result;
846 
847  /* Get external code of the object class */
848  Assert(tclass < SEPG_CLASS_MAX);
849 
850  tclass_name = selinux_catalog[tclass].class_name;
851  tclass_ex = string_to_security_class(tclass_name);
852 
853  /*
854  * Ask SELinux what is the default context for the given object class on a
855  * pair of security contexts
856  */
857  if (security_compute_create_name_raw((security_context_t) scontext,
858  (security_context_t) tcontext,
859  tclass_ex,
860  objname,
861  &ncontext) < 0)
862  ereport(ERROR,
863  (errcode(ERRCODE_INTERNAL_ERROR),
864  errmsg("SELinux could not compute a new context: "
865  "scontext=%s tcontext=%s tclass=%s: %m",
866  scontext, tcontext, tclass_name)));
867 
868  /*
869  * libselinux returns malloc()'ed string, so we need to copy it on the
870  * palloc()'ed region.
871  */
872  PG_TRY();
873  {
874  result = pstrdup(ncontext);
875  }
876  PG_CATCH();
877  {
878  freecon(ncontext);
879  PG_RE_THROW();
880  }
881  PG_END_TRY();
882  freecon(ncontext);
883 
884  return result;
885 }
886 
887 /*
888  * sepgsql_check_perms
889  *
890  * It makes access control decision without userspace caching mechanism.
891  * If SELinux denied the required accesses on the pair of security labels,
892  * it raises an error or returns false.
893  *
894  * scontext: security label of the subject (mostly, peer process)
895  * tcontext: security label of the object being referenced
896  * tclass: class code (SEPG_CLASS_*) of the object being referenced
897  * required: a mask of required permissions (SEPG_<class>__<perm>)
898  * audit_name: a human readable object name for audit logs, or NULL.
899  * abort_on_violation: true, if error shall be raised on access violation
900  */
901 bool
902 sepgsql_check_perms(const char *scontext,
903  const char *tcontext,
904  uint16 tclass,
905  uint32 required,
906  const char *audit_name,
907  bool abort_on_violation)
908 {
909  struct av_decision avd;
910  uint32 denied;
911  uint32 audited;
912  bool result = true;
913 
914  sepgsql_compute_avd(scontext, tcontext, tclass, &avd);
915 
916  denied = required & ~avd.allowed;
917 
919  audited = (denied ? denied : required);
920  else
921  audited = (denied ? (denied & avd.auditdeny)
922  : (required & avd.auditallow));
923 
924  if (denied &&
925  sepgsql_getenforce() > 0 &&
926  (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE) == 0)
927  result = false;
928 
929  /*
930  * It records a security audit for the request, if needed. But, when
931  * SE-PgSQL performs 'internal' mode, it needs to keep silent.
932  */
933  if (audited && sepgsql_mode != SEPGSQL_MODE_INTERNAL)
934  {
935  sepgsql_audit_log(denied,
936  scontext,
937  tcontext,
938  tclass,
939  audited,
940  audit_name);
941  }
942 
943  if (!result && abort_on_violation)
944  ereport(ERROR,
945  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
946  errmsg("SELinux: security policy violation")));
947  return result;
948 }
#define SEPG_DB_PROCEDURE__GETATTR
Definition: sepgsql.h:161
#define SEPG_DB_PROCEDURE__DROP
Definition: sepgsql.h:160
#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:165
#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:212
static int sepgsql_mode
Definition: selinux.c:607
#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:183
#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:172
#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:174
#define SEPG_FILE__CREATE
Definition: sepgsql.h:65
#define SEPG_DB_LANGUAGE__CREATE
Definition: sepgsql.h:197
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define SEPG_DB_VIEW__RELABELTO
Definition: sepgsql.h:211
void sepgsql_compute_avd(const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
Definition: selinux.c:732
#define SEPG_DB_VIEW__SETATTR
Definition: sepgsql.h:209
#define SEPG_DB_TUPLE__RELABELFROM
Definition: sepgsql.h:179
#define SEPG_DB_LANGUAGE__RELABELTO
Definition: sepgsql.h:202
#define SEPG_DB_TABLE__DELETE
Definition: sepgsql.h:146
#define SEPG_DB_SEQUENCE__GETATTR
Definition: sepgsql.h:151
#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:575
#define SEPG_SOCK_FILE__CREATE
Definition: sepgsql.h:106
bool sepgsql_getenforce(void)
Definition: selinux.c:648
#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:177
#define SEPG_SOCK_FILE__READ
Definition: sepgsql.h:104
return result
Definition: formatting.c:1633
#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:186
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:173
#define SEPG_BLK_FILE__UNLINK
Definition: sepgsql.h:101
#define SEPG_DB_TUPLE__DELETE
Definition: sepgsql.h:184
#define SEPG_FILE__WRITE
Definition: sepgsql.h:64
#define SEPG_DB_SEQUENCE__SETATTR
Definition: sepgsql.h:152
#define SEPG_CLASS_DB_DATABASE
Definition: sepgsql.h:44
#define SEPG_DB_COLUMN__GETATTR
Definition: sepgsql.h:171
#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:198
#define SEPG_DB_SCHEMA__RELABELFROM
Definition: sepgsql.h:131
#define SEPG_DB_SEQUENCE__RELABELFROM
Definition: sepgsql.h:153
#define SEPG_DB_TUPLE__SELECT
Definition: sepgsql.h:181
#define SEPG_DB_LANGUAGE__SETATTR
Definition: sepgsql.h:200
#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:191
int sepgsql_get_mode(void)
Definition: selinux.c:622
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
unsigned short uint16
Definition: c.h:267
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#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:159
#define ERROR
Definition: elog.h:43
#define SEPG_DB_LANGUAGE__IMPLEMENT
Definition: sepgsql.h:203
#define SEPG_DB_BLOB__DROP
Definition: sepgsql.h:187
#define SEPG_DB_COLUMN__SELECT
Definition: sepgsql.h:175
#define SEPG_DB_SEQUENCE__GET_VALUE
Definition: sepgsql.h:155
void sepgsql_audit_log(bool denied, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
Definition: selinux.c:677
#define SEPG_DB_VIEW__CREATE
Definition: sepgsql.h:206
#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:631
#define SEPG_FILE__READ
Definition: sepgsql.h:63
#define SEPG_DB_PROCEDURE__RELABELFROM
Definition: sepgsql.h:163
bool sepgsql_get_debug_audit(void)
Definition: hooks.c:76
#define SEPG_DB_TABLE__INSERT
Definition: sepgsql.h:145
static char * buf
Definition: pg_test_fsync.c:66
#define SEPG_DB_BLOB__GETATTR
Definition: sepgsql.h:188
#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:208
#define SEPG_DB_TABLE__DROP
Definition: sepgsql.h:138
unsigned int uint32
Definition: c.h:268
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:164
#define SEPG_DB_SEQUENCE__RELABELTO
Definition: sepgsql.h:154
#define SEPG_DB_BLOB__WRITE
Definition: sepgsql.h:193
#define SEPG_DB_SEQUENCE__NEXT_VALUE
Definition: sepgsql.h:156
#define SEPG_DB_SEQUENCE__SET_VALUE
Definition: sepgsql.h:157
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142
#define SEPG_DB_BLOB__RELABELFROM
Definition: sepgsql.h:190
#define ereport(elevel, rest)
Definition: elog.h:122
#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:176
#define SEPG_DB_TUPLE__UPDATE
Definition: sepgsql.h:182
#define SEPG_CHR_FILE__RENAME
Definition: sepgsql.h:95
#define SEPG_DB_BLOB__EXPORT
Definition: sepgsql.h:195
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#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 SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:170
#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:192
#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:902
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:169
#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:210
#define PG_CATCH()
Definition: elog.h:293
uint16 class_code
Definition: selinux.c:33
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:166
bool sepgsql_is_enabled(void)
Definition: selinux.c:613
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#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:149
#define SEPG_DB_LANGUAGE__EXECUTE
Definition: sepgsql.h:204
#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:207
#define PG_RE_THROW()
Definition: elog.h:314
#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:837
#define SEPG_DB_LANGUAGE__GETATTR
Definition: sepgsql.h:199
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define SEPG_DB_SEQUENCE__DROP
Definition: sepgsql.h:150
#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:189
int i
#define SEPG_BLK_FILE__WRITE
Definition: sepgsql.h:98
#define SEPG_DB_LANGUAGE__RELABELFROM
Definition: sepgsql.h:201
#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:284
#define SEPG_DB_TUPLE__RELABELTO
Definition: sepgsql.h:180
#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:162
#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:300
#define SEPG_DB_PROCEDURE__INSTALL
Definition: sepgsql.h:167
#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:194