Add security_validatetrans support
It seems validatetrans support was never added to libselinux, despite being added to selinuxfs in kernel version 4.5 There is a utility to test, however the targeted policy has no validatetrans rules so some must be added: $ cat validatetrans.cil (mlsvalidatetrans db_table (and (or (or (or (eq l1 l2) (and (eq t3 unconfined_t) (domby l1 l2))) (and (eq t3 unconfined_t) (dom l1 l2))) (and (eq t3 unconfined_t) (incomp l1 l2))) (or (or (or (eq l1 h2) (and (eq t3 unconfined_t) (domby h1 h2))) (and (eq t3 unconfined_t) (dom h1 h2))) (and (eq t3 unconfined_t) (incomp h1 h2))))) $ sudo semodule -i validatetrans.cil $ ./validatetrans system_u:system_r:kernel_t:s0 system_u:system_r:init_t:s0:c0 db_table system_u:system_r: # invalid context here opening /sys/fs/selinux/validatetrans security_validatetrans returned -1 errno: Invalid argument $ ./validatetrans system_u:system_r:kernel_t:s0 system_u:system_r:init_t:s0:c0 db_table system_u:system_r:init_t:s0 opening /sys/fs/selinux/validatetrans security_validatetrans returned -1 errno: Operation not permitted $ ./validatetrans system_u:system_r:kernel_t:s0 system_u:system_r:init_t:s0:c0 db_table system_u:system_r:unconfined_t:s0 opening /sys/fs/selinux/validatetrans security_validatetrans returned 0 errno: Success Signed-off-by: Joshua Brindle <joshua.brindle@crunchydata.com>
This commit is contained in:
parent
42f73af507
commit
25ce102907
8 changed files with 154 additions and 1 deletions
|
@ -255,6 +255,19 @@ extern int security_compute_user_raw(const char * scon,
|
|||
const char *username,
|
||||
char *** con);
|
||||
|
||||
/* Validate a transition. This determines whether a transition from scon to newcon
|
||||
using tcon as the target for object class tclass is valid in the loaded policy.
|
||||
This checks against the mlsvalidatetrans and validatetrans constraints in the loaded policy.
|
||||
Returns 0 if allowed and -1 if an error occured with errno set */
|
||||
extern int security_validatetrans(const char *scon,
|
||||
const char *tcon,
|
||||
security_class_t tclass,
|
||||
const char *newcon);
|
||||
extern int security_validatetrans_raw(const char *scon,
|
||||
const char *tcon,
|
||||
security_class_t tclass,
|
||||
const char *newcon);
|
||||
|
||||
/* Load a policy configuration. */
|
||||
extern int security_load_policy(void *data, size_t len);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.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_create_name, security_compute_relabel,
|
||||
security_compute_member, security_compute_user, security_get_initial_context \- query
|
||||
security_compute_member, security_compute_user, security_validatetrans, security_get_initial_context \- query
|
||||
the SELinux policy database in the kernel
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
|
@ -35,6 +35,10 @@ the SELinux policy database in the kernel
|
|||
.sp
|
||||
.BI "int security_compute_user_raw(char *" scon ", const char *" username ", char ***" con );
|
||||
.sp
|
||||
.BI "int security_validatetrans(char *" scon ", const char *" tcon ", security_class_t "tclass ", char *" newcon );
|
||||
.sp
|
||||
.BI "int security_validatetrans_raw(char *" scon ", const char *" tcon ", security_class_t "tclass ", char *" newcon );
|
||||
.sp
|
||||
.BI "int security_get_initial_context(const char *" name ", char **" con );
|
||||
.sp
|
||||
.BI "int security_get_initial_context_raw(const char *" name ", char **" con );
|
||||
|
@ -100,6 +104,12 @@ is used to determine the set of user contexts that can be reached from a
|
|||
source context. It is mainly used by
|
||||
.BR get_ordered_context_list ().
|
||||
|
||||
.BR security_validatetrans ()
|
||||
is used to determine if a transition from scon to newcon using tcon as the object
|
||||
is valid for object class tclass. This checks against the mlsvalidatetrans and
|
||||
validatetrans constraints in the loaded policy. Returns 0 if allowed, and -1
|
||||
if an error occured with errno set.
|
||||
|
||||
.BR security_get_initial_context ()
|
||||
is used to get the context of a kernel initial security identifier specified by
|
||||
.I name
|
||||
|
@ -111,6 +121,7 @@ is used to get the context of a kernel initial security identifier specified by
|
|||
.BR \%security_compute_relabel_raw (),
|
||||
.BR \%security_compute_member_raw (),
|
||||
.BR \%security_compute_user_raw ()
|
||||
.BR \%security_validatetrans_raw ()
|
||||
and
|
||||
.BR \%security_get_initial_context_raw ()
|
||||
behave identically to their non-raw counterparts but do not perform context
|
||||
|
|
1
libselinux/man/man3/security_validatetrans.c
Normal file
1
libselinux/man/man3/security_validatetrans.c
Normal file
|
@ -0,0 +1 @@
|
|||
.so man3/security_compute_av.3
|
1
libselinux/man/man3/security_validatetrans_raw.c
Normal file
1
libselinux/man/man3/security_validatetrans_raw.c
Normal file
|
@ -0,0 +1 @@
|
|||
.so man3/security_compute_av.3
|
|
@ -29,6 +29,8 @@ hidden_proto(selinux_mkload_policy)
|
|||
hidden_proto(security_compute_create_name_raw)
|
||||
hidden_proto(security_compute_member_raw)
|
||||
hidden_proto(security_compute_relabel_raw)
|
||||
hidden_proto(security_validatetrans)
|
||||
hidden_proto(security_validatetrans_raw)
|
||||
hidden_proto(is_selinux_enabled)
|
||||
hidden_proto(is_selinux_mls_enabled)
|
||||
hidden_proto(freecon)
|
||||
|
|
94
libselinux/src/validatetrans.c
Normal file
94
libselinux/src/validatetrans.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "selinux_internal.h"
|
||||
#include "policy.h"
|
||||
#include "mapping.h"
|
||||
|
||||
int security_validatetrans_raw(const char *scon,
|
||||
const char *tcon,
|
||||
security_class_t tclass,
|
||||
const char *newcon)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char *buf = NULL;
|
||||
int size, bufsz;
|
||||
int fd, ret = -1;
|
||||
errno = ENOENT;
|
||||
|
||||
if (!selinux_mnt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof path, "%s/validatetrans", selinux_mnt);
|
||||
fd = open(path, O_WRONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
errno = EINVAL;
|
||||
size = selinux_page_size;
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
bufsz = snprintf(buf, size, "%s %s %hu %s", scon, tcon, unmap_class(tclass), newcon);
|
||||
if (bufsz >= size || bufsz < 0) {
|
||||
// It got truncated or there was an encoding error
|
||||
goto out;
|
||||
}
|
||||
|
||||
// clear errno for write()
|
||||
errno = 0;
|
||||
ret = write(fd, buf, strlen(buf));
|
||||
if (ret > 0) {
|
||||
// The kernel returns the bytes written on success, not 0 as noted in the commit message
|
||||
ret = 0;
|
||||
}
|
||||
out:
|
||||
free(buf);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_validatetrans_raw)
|
||||
|
||||
int security_validatetrans(const char *scon,
|
||||
const char *tcon,
|
||||
security_class_t tclass,
|
||||
const char *newcon)
|
||||
{
|
||||
int ret = -1;
|
||||
char *rscon = NULL;
|
||||
char *rtcon = NULL;
|
||||
char *rnewcon = NULL;
|
||||
|
||||
if (selinux_trans_to_raw_context(scon, &rscon)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (selinux_trans_to_raw_context(tcon, &rtcon)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (selinux_trans_to_raw_context(newcon, &rnewcon)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = security_validatetrans_raw(rscon, rtcon, tclass, rnewcon);
|
||||
|
||||
out:
|
||||
freecon(rnewcon);
|
||||
freecon(rtcon);
|
||||
freecon(rscon);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
hidden_def(security_validatetrans)
|
1
libselinux/utils/.gitignore
vendored
1
libselinux/utils/.gitignore
vendored
|
@ -25,3 +25,4 @@ setenforce
|
|||
setfilecon
|
||||
togglesebool
|
||||
selinux_check_access
|
||||
validatetrans
|
||||
|
|
30
libselinux/utils/validatetrans.c
Normal file
30
libselinux/utils/validatetrans.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
security_class_t tclass;
|
||||
int ret;
|
||||
|
||||
if (argc != 5) {
|
||||
fprintf(stderr, "usage: %s scontext tcontext tclass newcontext\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tclass = string_to_security_class(argv[3]);
|
||||
if (!tclass) {
|
||||
fprintf(stderr, "%s: invalid class '%s'\n", argv[0], argv[3]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
ret = security_validatetrans(argv[1], argv[2], tclass, argv[4]);
|
||||
printf("security_validatetrans returned %d errno: %s\n", ret, strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in a new issue