PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
selinux.c File Reference
#include "postgres.h"
#include "lib/stringinfo.h"
#include "sepgsql.h"
Include dependency graph for selinux.c:

Go to the source code of this file.

Functions

bool sepgsql_is_enabled (void)
 
int sepgsql_get_mode (void)
 
int sepgsql_set_mode (int new_mode)
 
bool sepgsql_getenforce (void)
 
void sepgsql_audit_log (bool denied, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
 
void sepgsql_compute_avd (const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
 
char * sepgsql_compute_create (const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
 
bool sepgsql_check_perms (const char *scontext, const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
 

Variables

struct {
   const char *   class_name
 
   uint16   class_code
 
   struct {
      const char *   av_name
 
      uint32   av_code
 
   }   av [32]
 
selinux_catalog []
 
static int sepgsql_mode = SEPGSQL_MODE_INTERNAL
 

Function Documentation

void sepgsql_audit_log ( bool  denied,
const char *  scontext,
const char *  tcontext,
uint16  tclass,
uint32  audited,
const char *  audit_name 
)

Definition at line 677 of file selinux.c.

References appendStringInfo(), Assert, av_name, buf, class_name, StringInfoData::data, ereport, errmsg(), i, initStringInfo(), LOG, selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_avc_check_perms_label(), and sepgsql_check_perms().

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 }
#define SEPG_CLASS_MAX
Definition: sepgsql.h:54
const char * av_name
Definition: selinux.c:36
#define LOG
Definition: elog.h:26
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
static char * buf
Definition: pg_test_fsync.c:66
static struct @18 selinux_catalog[]
#define ereport(elevel, rest)
Definition: elog.h:122
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define Assert(condition)
Definition: c.h:676
const char * class_name
Definition: selinux.c:32
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
bool sepgsql_check_perms ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
uint32  required,
const char *  audit_name,
bool  abort_on_violation 
)

Definition at line 902 of file selinux.c.

References ereport, errcode(), errmsg(), ERROR, result, sepgsql_audit_log(), sepgsql_compute_avd(), sepgsql_get_debug_audit(), sepgsql_getenforce(), sepgsql_mode, and SEPGSQL_MODE_INTERNAL.

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 SEPGSQL_MODE_INTERNAL
Definition: sepgsql.h:30
static int sepgsql_mode
Definition: selinux.c:607
void sepgsql_compute_avd(const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
Definition: selinux.c:732
int errcode(int sqlerrcode)
Definition: elog.c:575
bool sepgsql_getenforce(void)
Definition: selinux.c:648
return result
Definition: formatting.c:1633
#define ERROR
Definition: elog.h:43
void sepgsql_audit_log(bool denied, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
Definition: selinux.c:677
bool sepgsql_get_debug_audit(void)
Definition: hooks.c:76
unsigned int uint32
Definition: c.h:268
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
void sepgsql_compute_avd ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
struct av_decision *  avd 
)

Definition at line 732 of file selinux.c.

References Assert, av_code, av_name, class_code, ereport, errcode(), errmsg(), ERROR, i, selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_avc_compute(), and sepgsql_check_perms().

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 }
#define SEPG_CLASS_MAX
Definition: sepgsql.h:54
const char * av_name
Definition: selinux.c:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
uint32 av_code
Definition: selinux.c:37
static struct @18 selinux_catalog[]
unsigned int uint32
Definition: c.h:268
#define ereport(elevel, rest)
Definition: elog.h:122
uint16 class_code
Definition: selinux.c:33
#define Assert(condition)
Definition: c.h:676
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
char* sepgsql_compute_create ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
const char *  objname 
)

Definition at line 837 of file selinux.c.

References Assert, ereport, errcode(), errmsg(), ERROR, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pstrdup(), result, selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_attribute_post_create(), sepgsql_avc_compute(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_relation_post_create(), and sepgsql_schema_post_create().

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 }
#define SEPG_CLASS_MAX
Definition: sepgsql.h:54
char * pstrdup(const char *in)
Definition: mcxt.c:1077
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
#define ERROR
Definition: elog.h:43
static struct @18 selinux_catalog[]
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_CATCH()
Definition: elog.h:293
#define Assert(condition)
Definition: c.h:676
#define PG_RE_THROW()
Definition: elog.h:314
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
int sepgsql_get_mode ( void  )

Definition at line 622 of file selinux.c.

References sepgsql_mode.

Referenced by sepgsql_avc_check_perms_label().

623 {
624  return sepgsql_mode;
625 }
static int sepgsql_mode
Definition: selinux.c:607
bool sepgsql_getenforce ( void  )

Definition at line 648 of file selinux.c.

References sepgsql_mode, and SEPGSQL_MODE_DEFAULT.

Referenced by check_relation_privileges(), sepgsql_avc_check_perms_label(), sepgsql_check_perms(), and sepgsql_utility_command().

649 {
651  selinux_status_getenforce() > 0)
652  return true;
653 
654  return false;
655 }
static int sepgsql_mode
Definition: selinux.c:607
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
bool sepgsql_is_enabled ( void  )

Definition at line 613 of file selinux.c.

References sepgsql_mode, and SEPGSQL_MODE_DISABLED.

Referenced by sepgsql_getcon(), sepgsql_mcstrans_in(), sepgsql_mcstrans_out(), and sepgsql_restorecon().

614 {
615  return (sepgsql_mode != SEPGSQL_MODE_DISABLED ? true : false);
616 }
static int sepgsql_mode
Definition: selinux.c:607
#define SEPGSQL_MODE_DISABLED
Definition: sepgsql.h:31
int sepgsql_set_mode ( int  new_mode)

Definition at line 631 of file selinux.c.

References sepgsql_mode.

Referenced by _PG_init(), and sepgsql_client_auth().

632 {
633  int old_mode = sepgsql_mode;
634 
635  sepgsql_mode = new_mode;
636 
637  return old_mode;
638 }
static int sepgsql_mode
Definition: selinux.c:607

Variable Documentation

uint32 av_code

Definition at line 37 of file selinux.c.

Referenced by sepgsql_compute_avd().

const char* av_name

Definition at line 36 of file selinux.c.

Referenced by sepgsql_audit_log(), and sepgsql_compute_avd().

uint16 class_code

Definition at line 33 of file selinux.c.

Referenced by sepgsql_compute_avd().

const char* class_name

Definition at line 32 of file selinux.c.

Referenced by sepgsql_audit_log(), and to_regclass().

struct { ... } selinux_catalog[]