libselinux: security_compute_create_name(3)

I'd like to use this interface to implement special case handling
for the default labeling behavior on temporary database objects.  Allow
userspace to use the filename_trans rules added to policy.

Signed-off-by: KaiGai Kohei <kohei.kaigai@emea.nec.com>
Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
Kohei KaiGai 2012-03-25 22:05:17 +02:00 committed by Eric Paris
parent 72ea5dec7c
commit 2b5a0530e7
5 changed files with 105 additions and 13 deletions

View File

@ -211,6 +211,16 @@ extern int security_compute_create_raw(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
security_context_t * newcon);
extern int security_compute_create_name(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
const char *objname,
security_context_t * newcon);
extern int security_compute_create_name_raw(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
const char *objname,
security_context_t * newcon);
/* Compute a relabeling decision and set *newcon to refer to it.
Caller must free via freecon. */

View File

@ -1,6 +1,6 @@
.TH "security_compute_av" "3" "1 January 2004" "russell@coker.com.au" "SELinux API documentation"
.SH "NAME"
security_compute_av, security_compute_av_flags, security_compute_create, security_compute_relabel,
security_compute_av, security_compute_av_flags, security_compute_create, security_compute_create_name, security_compute_relabel,
security_compute_member, security_compute_user, security_get_initial_context \- query
the SELinux policy database in the kernel.
@ -15,6 +15,8 @@ the SELinux policy database in the kernel.
.sp
.BI "int security_compute_create(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", security_context_t *" newcon );
.sp
.BI "int security_compute_create_name(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", const char *"objname ", security_context_t *" newcon );
.sp
.BI "int security_compute_relabel(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", security_context_t *" newcon );
.sp
.BI "int security_compute_member(security_context_t "scon ", security_context_t "tcon ", security_class_t "tclass ", security_context_t *" newcon );
@ -58,6 +60,19 @@ which indicates the decision is computed on a permissive domain.
is used to compute a context to use for labeling a new object in a particular
class based on a SID pair.
.B security_compute_create_name
is identical to
.B security_compute_create
but also takes name of the new object in creation as an argument.
When
.BR TYPE_TRANSITION
rule on the given class and a SID pair has object name extension,
we shall be able to obtain a correct
.BR newcon
according to the security policy. Note that this interface is only
supported on the linux 2.6.40 or later.
In the older kernel, the object name will be simply ignored.
.B security_compute_relabel
is used to compute the new context to use when relabeling an object, it is used
in the pam_selinux.so source and the newrole source to determine the correct

View File

@ -0,0 +1 @@
.so man3/security_compute_av.3

View File

@ -6,19 +6,58 @@
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include "selinux_internal.h"
#include "policy.h"
#include "mapping.h"
int security_compute_create_raw(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
security_context_t * newcon)
static int object_name_encode(const char *objname, char *buffer, size_t buflen)
{
int code;
size_t offset = 0;
if (buflen - offset < 1)
return -1;
buffer[offset++] = ' ';
do {
code = *objname++;
if (isalnum(code) || code == '\0' || code == '-' ||
code == '.' || code == '_' || code == '~') {
if (buflen - offset < 1)
return -1;
buffer[offset++] = code;
} else if (code == ' ') {
if (buflen - offset < 1)
return -1;
buffer[offset++] = '+';
} else {
static const char *table = "0123456789ABCDEF";
int l = (code & 0x0f);
int h = (code & 0xf0) >> 4;
if (buflen - offset < 3)
return -1;
buffer[offset++] = '%';
buffer[offset++] = table[h];
buffer[offset++] = table[l];
}
} while (code != '\0');
return 0;
}
int security_compute_create_name_raw(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
const char *objname,
security_context_t * newcon)
{
char path[PATH_MAX];
char *buf;
size_t size;
int fd, ret;
int fd, ret, len;
if (!selinux_mnt) {
errno = ENOENT;
@ -36,7 +75,14 @@ int security_compute_create_raw(const security_context_t scon,
ret = -1;
goto out;
}
snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
len = snprintf(buf, size, "%s %s %hu",
scon, tcon, unmap_class(tclass));
if (objname &&
object_name_encode(objname, buf + len, size - len) < 0) {
errno = ENAMETOOLONG;
ret = -1;
goto out2;
}
ret = write(fd, buf, strlen(buf));
if (ret < 0)
@ -59,13 +105,23 @@ int security_compute_create_raw(const security_context_t scon,
close(fd);
return ret;
}
hidden_def(security_compute_create_name_raw)
int security_compute_create_raw(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
security_context_t * newcon)
{
return security_compute_create_name_raw(scon, tcon, tclass,
NULL, newcon);
}
hidden_def(security_compute_create_raw)
int security_compute_create(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
security_context_t * newcon)
int security_compute_create_name(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
const char *objname,
security_context_t * newcon)
{
int ret;
security_context_t rscon;
@ -79,8 +135,8 @@ int security_compute_create(const security_context_t scon,
return -1;
}
ret = security_compute_create_raw(rscon, rtcon, tclass, &rnewcon);
ret = security_compute_create_name_raw(rscon, rtcon, tclass,
objname, &rnewcon);
freecon(rscon);
freecon(rtcon);
if (!ret) {
@ -90,5 +146,13 @@ int security_compute_create(const security_context_t scon,
return ret;
}
hidden_def(security_compute_create_name)
int security_compute_create(const security_context_t scon,
const security_context_t tcon,
security_class_t tclass,
security_context_t * newcon)
{
return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
}
hidden_def(security_compute_create)

View File

@ -25,6 +25,8 @@ hidden_proto(selinux_mkload_policy)
hidden_proto(security_compute_user_raw)
hidden_proto(security_compute_create)
hidden_proto(security_compute_create_raw)
hidden_proto(security_compute_create_name)
hidden_proto(security_compute_create_name_raw)
hidden_proto(security_compute_member_raw)
hidden_proto(security_compute_relabel_raw)
hidden_proto(is_selinux_enabled)