On 2011-07-21 11:29, Kohei Kaigai wrote:
The attached patch is revised userspace-avc patch.
List of updates:
- The GUC of sepgsql.avc_threshold was removed.
- "char *ucontext" of avc_cache was replaced by "bool tcontext_is_valid".
- Comments added onto static variables
- Comments of sepgsql_avc_unlabeled() was revised.
- Comments of sepgsql_avc_compute() was simplified.
- Comments of sepgsql_avc_check_perms_label() also mention about
permissive domain, that performs similar to system's permissive mode.
- selinux_status_close() become invoked on on_proc_exit() hook.
Thank you for the update, I'm looking at it right now and with a new
look have some more questions. I took the liberty to supply a patch to
be applied after your v5 uavc patch.
1) At a few call sites of sepgsql_avc_lookup, a null tcontext is
detected, and then replaced by "unlabeled". I moved this to
sepgsql_avc_lookup itself.
2) Also I thought if it could work to not remember tcontext is valid,
but instead remember the consequence, which is that it is replaced by
"unlabeled". It makes the avc_cache struct shorter and the code somewhat
simpler.
regards,
--
Yeb Havinga
http://www.mgrid.net/
Mastering Medical Data
diff --git a/contrib/sepgsql/uavc.c b/contrib/sepgsql/uavc.c
new file mode 100644
index 57a5197..2bcfedf
*** a/contrib/sepgsql/uavc.c
--- b/contrib/sepgsql/uavc.c
*************** typedef struct
*** 41,48 ****
bool permissive; /* true, if permissive rule */
bool hot_cache; /* true, if recently referenced */
- bool tcontext_is_valid;
- /* true, if tcontext is valid */
char *ncontext; /* temporary scontext on execution of trusted
* procedure, or NULL elsewhere */
} avc_cache;
--- 41,46 ----
*************** sepgsql_avc_reset(void)
*** 88,94 ****
/*
* Reclaim caches recently unreferenced
! */
static void
sepgsql_avc_reclaim(void)
{
--- 86,92 ----
/*
* Reclaim caches recently unreferenced
! */
static void
sepgsql_avc_reclaim(void)
{
*************** sepgsql_avc_check_valid(void)
*** 153,159 ****
/*
* sepgsql_avc_unlabeled
*
! * It returns an alternative label to be applied when no label or invalid
* label would be assigned on objects.
*/
static char *
--- 151,157 ----
/*
* sepgsql_avc_unlabeled
*
! * It returns an alternative label to be applied when no label or invalid
* label would be assigned on objects.
*/
static char *
*************** sepgsql_avc_unlabeled(void)
*** 184,198 ****
}
/*
! * sepgsql_avc_compute
*
* A fallback path, when cache mishit. It asks SELinux its access control
* decision for the supplied pair of security context and object class.
*/
static avc_cache *
! sepgsql_avc_compute(const char *scontext, const char *tcontext, uint16 tclass)
{
- char *ucontext = NULL;
char *ncontext = NULL;
MemoryContext oldctx;
avc_cache *cache;
--- 182,195 ----
}
/*
! * sepgsql_avc_compute
*
* A fallback path, when cache mishit. It asks SELinux its access control
* decision for the supplied pair of security context and object class.
*/
static avc_cache *
! sepgsql_avc_compute(const char *scontext, char *tcontext, uint16 tclass)
{
char *ncontext = NULL;
MemoryContext oldctx;
avc_cache *cache;
*************** sepgsql_avc_compute(const char *scontext
*** 207,224 ****
* Validation check of the supplied security context.
* Because it always invoke system-call, frequent check should be avoided.
* Unless security policy is reloaded, validation status shall be kept, so
! * we also cache whether the supplied security context was valid, or not.
*/
if (security_check_context_raw((security_context_t)tcontext) != 0)
! ucontext = sepgsql_avc_unlabeled();
! /*
! * Ask SELinux its access control decision
! */
! if (!ucontext)
! sepgsql_compute_avd(scontext, tcontext, tclass, &avd);
! else
! sepgsql_compute_avd(scontext, ucontext, tclass, &avd);
/*
* To boost up trusted procedure checks on db_procedure object
--- 204,216 ----
* Validation check of the supplied security context.
* Because it always invoke system-call, frequent check should be avoided.
* Unless security policy is reloaded, validation status shall be kept, so
! * we also cache the invalid tcontext replaced by the unlabeled context.
*/
if (security_check_context_raw((security_context_t)tcontext) != 0)
! tcontext = sepgsql_avc_unlabeled();
! /* Ask SELinux its access control decision */
! sepgsql_compute_avd(scontext, tcontext, tclass, &avd);
/*
* To boost up trusted procedure checks on db_procedure object
*************** sepgsql_avc_compute(const char *scontext
*** 227,238 ****
*/
if (tclass == SEPG_CLASS_DB_PROCEDURE)
{
! if (!ucontext)
! ncontext = sepgsql_compute_create(scontext, tcontext,
! SEPG_CLASS_PROCESS);
! else
! ncontext = sepgsql_compute_create(scontext, ucontext,
! SEPG_CLASS_PROCESS);
if (strcmp(scontext, ncontext) == 0)
{
pfree(ncontext);
--- 219,227 ----
*/
if (tclass == SEPG_CLASS_DB_PROCEDURE)
{
! ncontext = sepgsql_compute_create(scontext, tcontext,
! SEPG_CLASS_PROCESS);
!
if (strcmp(scontext, ncontext) == 0)
{
pfree(ncontext);
*************** sepgsql_avc_compute(const char *scontext
*** 258,267 ****
cache->hot_cache = true;
if (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE)
cache->permissive = true;
! if (!ucontext)
! cache->tcontext_is_valid = true;
! if (ncontext)
! cache->ncontext = pstrdup(ncontext);
avc_num_caches++;
--- 247,253 ----
cache->hot_cache = true;
if (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE)
cache->permissive = true;
! cache->ncontext = ncontext;
avc_num_caches++;
*************** sepgsql_avc_compute(const char *scontext
*** 283,295 ****
* a new cache entry.
*/
static avc_cache *
! sepgsql_avc_lookup(const char *scontext, const char *tcontext, uint16 tclass)
{
avc_cache *cache;
ListCell *cell;
uint32 hash;
int index;
hash = sepgsql_avc_hash(scontext, tcontext, tclass);
index = hash % AVC_NUM_SLOTS;
--- 269,288 ----
* a new cache entry.
*/
static avc_cache *
! sepgsql_avc_lookup(const char *scontext, char *tcontext, uint16 tclass)
{
avc_cache *cache;
ListCell *cell;
uint32 hash;
int index;
+ /*
+ * If target object is not labeled, we assume it has
+ * system 'unlabeled' security context instead.
+ */
+ if (!tcontext)
+ tcontext = sepgsql_avc_unlabeled();
+
hash = sepgsql_avc_hash(scontext, tcontext, tclass);
index = hash % AVC_NUM_SLOTS;
*************** sepgsql_avc_lookup(const char *scontext,
*** 303,313 ****
strcmp(cache->scontext, scontext) == 0)
{
cache->hot_cache = true;
return cache;
}
}
/* not found, so insert a new cache */
! return sepgsql_avc_compute(scontext, tcontext, tclass);
}
/*
--- 296,307 ----
strcmp(cache->scontext, scontext) == 0)
{
cache->hot_cache = true;
+
return cache;
}
}
/* not found, so insert a new cache */
! return sepgsql_avc_compute(scontext, (char *) tcontext, tclass);
}
/*
*************** sepgsql_avc_check_perms_label(const char
*** 337,357 ****
do {
result = true;
! /*
! * If target object is unlabeled, we assume it has
! * system 'unlabeled' security context instead.
! */
! if (tcontext)
! cache = sepgsql_avc_lookup(scontext, tcontext, tclass);
! else
! cache = sepgsql_avc_lookup(scontext,
! sepgsql_avc_unlabeled(), tclass);
denied = required & ~cache->allowed;
! /*
! * Compute permissions to be audited
! */
if (sepgsql_get_debug_audit())
audited = (denied ? (denied & ~0) : (required & ~0));
else
--- 331,341 ----
do {
result = true;
! cache = sepgsql_avc_lookup(scontext, (char *) tcontext, tclass);
denied = required & ~cache->allowed;
! /* Compute permissions to be audited */
if (sepgsql_get_debug_audit())
audited = (denied ? (denied & ~0) : (required & ~0));
else
*************** sepgsql_avc_check_perms_label(const char
*** 387,394 ****
{
sepgsql_audit_log(!!denied,
cache->scontext,
! cache->tcontext_is_valid ?
! cache->tcontext : sepgsql_avc_unlabeled(),
cache->tclass,
audited,
audit_name);
--- 371,377 ----
{
sepgsql_audit_log(!!denied,
cache->scontext,
! cache->tcontext,
cache->tclass,
audited,
audit_name);
*************** sepgsql_avc_trusted_proc(Oid functionId)
*** 441,451 ****
sepgsql_avc_check_valid();
do {
! if (tcontext)
! cache = sepgsql_avc_lookup(scontext, tcontext,
! SEPG_CLASS_DB_PROCEDURE);
! else
! cache = sepgsql_avc_lookup(scontext, sepgsql_avc_unlabeled(),
SEPG_CLASS_DB_PROCEDURE);
} while (!sepgsql_avc_check_valid());
--- 424,430 ----
sepgsql_avc_check_valid();
do {
! cache = sepgsql_avc_lookup(scontext, tcontext,
SEPG_CLASS_DB_PROCEDURE);
} while (!sepgsql_avc_check_valid());
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers