1*2d543d20SAndroid Build Coastguard Worker /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
3*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
5*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
6*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
7*2d543d20SAndroid Build Coastguard Worker #include <selinux/avc.h>
8*2d543d20SAndroid Build Coastguard Worker #include "avc_internal.h"
9*2d543d20SAndroid Build Coastguard Worker
10*2d543d20SAndroid Build Coastguard Worker static pthread_once_t once = PTHREAD_ONCE_INIT;
11*2d543d20SAndroid Build Coastguard Worker static int selinux_enabled;
12*2d543d20SAndroid Build Coastguard Worker
avc_init_once(void)13*2d543d20SAndroid Build Coastguard Worker static void avc_init_once(void)
14*2d543d20SAndroid Build Coastguard Worker {
15*2d543d20SAndroid Build Coastguard Worker selinux_enabled = is_selinux_enabled();
16*2d543d20SAndroid Build Coastguard Worker if (selinux_enabled == 1) {
17*2d543d20SAndroid Build Coastguard Worker if (avc_open(NULL, 0))
18*2d543d20SAndroid Build Coastguard Worker return;
19*2d543d20SAndroid Build Coastguard Worker }
20*2d543d20SAndroid Build Coastguard Worker }
21*2d543d20SAndroid Build Coastguard Worker
selinux_check_access(const char * scon,const char * tcon,const char * class,const char * perm,void * aux)22*2d543d20SAndroid Build Coastguard Worker int selinux_check_access(const char *scon, const char *tcon, const char *class, const char *perm, void *aux) {
23*2d543d20SAndroid Build Coastguard Worker int rc;
24*2d543d20SAndroid Build Coastguard Worker security_id_t scon_id;
25*2d543d20SAndroid Build Coastguard Worker security_id_t tcon_id;
26*2d543d20SAndroid Build Coastguard Worker security_class_t sclass;
27*2d543d20SAndroid Build Coastguard Worker access_vector_t av;
28*2d543d20SAndroid Build Coastguard Worker
29*2d543d20SAndroid Build Coastguard Worker __selinux_once(once, avc_init_once);
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker if (selinux_enabled != 1)
32*2d543d20SAndroid Build Coastguard Worker return 0;
33*2d543d20SAndroid Build Coastguard Worker
34*2d543d20SAndroid Build Coastguard Worker rc = avc_context_to_sid(scon, &scon_id);
35*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
36*2d543d20SAndroid Build Coastguard Worker return rc;
37*2d543d20SAndroid Build Coastguard Worker
38*2d543d20SAndroid Build Coastguard Worker rc = avc_context_to_sid(tcon, &tcon_id);
39*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
40*2d543d20SAndroid Build Coastguard Worker return rc;
41*2d543d20SAndroid Build Coastguard Worker
42*2d543d20SAndroid Build Coastguard Worker (void) selinux_status_updated();
43*2d543d20SAndroid Build Coastguard Worker
44*2d543d20SAndroid Build Coastguard Worker sclass = string_to_security_class(class);
45*2d543d20SAndroid Build Coastguard Worker if (sclass == 0) {
46*2d543d20SAndroid Build Coastguard Worker rc = errno;
47*2d543d20SAndroid Build Coastguard Worker avc_log(SELINUX_ERROR, "Unknown class %s", class);
48*2d543d20SAndroid Build Coastguard Worker if (security_deny_unknown() == 0)
49*2d543d20SAndroid Build Coastguard Worker return 0;
50*2d543d20SAndroid Build Coastguard Worker errno = rc;
51*2d543d20SAndroid Build Coastguard Worker return -1;
52*2d543d20SAndroid Build Coastguard Worker }
53*2d543d20SAndroid Build Coastguard Worker
54*2d543d20SAndroid Build Coastguard Worker av = string_to_av_perm(sclass, perm);
55*2d543d20SAndroid Build Coastguard Worker if (av == 0) {
56*2d543d20SAndroid Build Coastguard Worker rc = errno;
57*2d543d20SAndroid Build Coastguard Worker avc_log(SELINUX_ERROR, "Unknown permission %s for class %s", perm, class);
58*2d543d20SAndroid Build Coastguard Worker if (security_deny_unknown() == 0)
59*2d543d20SAndroid Build Coastguard Worker return 0;
60*2d543d20SAndroid Build Coastguard Worker errno = rc;
61*2d543d20SAndroid Build Coastguard Worker return -1;
62*2d543d20SAndroid Build Coastguard Worker }
63*2d543d20SAndroid Build Coastguard Worker
64*2d543d20SAndroid Build Coastguard Worker return avc_has_perm (scon_id, tcon_id, sclass, av, NULL, aux);
65*2d543d20SAndroid Build Coastguard Worker }
66*2d543d20SAndroid Build Coastguard Worker
selinux_check_passwd_access_internal(access_vector_t requested)67*2d543d20SAndroid Build Coastguard Worker static int selinux_check_passwd_access_internal(access_vector_t requested)
68*2d543d20SAndroid Build Coastguard Worker {
69*2d543d20SAndroid Build Coastguard Worker int status = -1;
70*2d543d20SAndroid Build Coastguard Worker char *user_context;
71*2d543d20SAndroid Build Coastguard Worker if (is_selinux_enabled() == 0)
72*2d543d20SAndroid Build Coastguard Worker return 0;
73*2d543d20SAndroid Build Coastguard Worker if (getprevcon_raw(&user_context) == 0) {
74*2d543d20SAndroid Build Coastguard Worker security_class_t passwd_class;
75*2d543d20SAndroid Build Coastguard Worker struct av_decision avd;
76*2d543d20SAndroid Build Coastguard Worker int retval;
77*2d543d20SAndroid Build Coastguard Worker
78*2d543d20SAndroid Build Coastguard Worker passwd_class = string_to_security_class("passwd");
79*2d543d20SAndroid Build Coastguard Worker if (passwd_class == 0) {
80*2d543d20SAndroid Build Coastguard Worker freecon(user_context);
81*2d543d20SAndroid Build Coastguard Worker if (security_deny_unknown() == 0)
82*2d543d20SAndroid Build Coastguard Worker return 0;
83*2d543d20SAndroid Build Coastguard Worker return -1;
84*2d543d20SAndroid Build Coastguard Worker }
85*2d543d20SAndroid Build Coastguard Worker
86*2d543d20SAndroid Build Coastguard Worker retval = security_compute_av_raw(user_context,
87*2d543d20SAndroid Build Coastguard Worker user_context,
88*2d543d20SAndroid Build Coastguard Worker passwd_class,
89*2d543d20SAndroid Build Coastguard Worker requested,
90*2d543d20SAndroid Build Coastguard Worker &avd);
91*2d543d20SAndroid Build Coastguard Worker
92*2d543d20SAndroid Build Coastguard Worker if ((retval == 0) && ((requested & avd.allowed) == requested)) {
93*2d543d20SAndroid Build Coastguard Worker status = 0;
94*2d543d20SAndroid Build Coastguard Worker }
95*2d543d20SAndroid Build Coastguard Worker freecon(user_context);
96*2d543d20SAndroid Build Coastguard Worker }
97*2d543d20SAndroid Build Coastguard Worker
98*2d543d20SAndroid Build Coastguard Worker if (status != 0 && security_getenforce() == 0)
99*2d543d20SAndroid Build Coastguard Worker status = 0;
100*2d543d20SAndroid Build Coastguard Worker
101*2d543d20SAndroid Build Coastguard Worker return status;
102*2d543d20SAndroid Build Coastguard Worker }
103*2d543d20SAndroid Build Coastguard Worker
selinux_check_passwd_access(access_vector_t requested)104*2d543d20SAndroid Build Coastguard Worker int selinux_check_passwd_access(access_vector_t requested) {
105*2d543d20SAndroid Build Coastguard Worker return selinux_check_passwd_access_internal(requested);
106*2d543d20SAndroid Build Coastguard Worker }
107*2d543d20SAndroid Build Coastguard Worker
checkPasswdAccess(access_vector_t requested)108*2d543d20SAndroid Build Coastguard Worker int checkPasswdAccess(access_vector_t requested)
109*2d543d20SAndroid Build Coastguard Worker {
110*2d543d20SAndroid Build Coastguard Worker return selinux_check_passwd_access_internal(requested);
111*2d543d20SAndroid Build Coastguard Worker }
112