xref: /aosp_15_r20/external/selinux/libselinux/src/avc_internal.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker  * Callbacks for user-supplied memory allocation, supplemental
3*2d543d20SAndroid Build Coastguard Worker  * auditing, and locking routines.
4*2d543d20SAndroid Build Coastguard Worker  *
5*2d543d20SAndroid Build Coastguard Worker  * Author : Eamon Walsh <[email protected]>
6*2d543d20SAndroid Build Coastguard Worker  *
7*2d543d20SAndroid Build Coastguard Worker  * Netlink code derived in part from sample code by
8*2d543d20SAndroid Build Coastguard Worker  * James Morris <[email protected]>.
9*2d543d20SAndroid Build Coastguard Worker  */
10*2d543d20SAndroid Build Coastguard Worker 
11*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
12*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
13*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
14*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
15*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
16*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
17*2d543d20SAndroid Build Coastguard Worker #include <string.h>
18*2d543d20SAndroid Build Coastguard Worker #include <poll.h>
19*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
20*2d543d20SAndroid Build Coastguard Worker #include <sys/socket.h>
21*2d543d20SAndroid Build Coastguard Worker #include <linux/types.h>
22*2d543d20SAndroid Build Coastguard Worker #include <linux/netlink.h>
23*2d543d20SAndroid Build Coastguard Worker #include "callbacks.h"
24*2d543d20SAndroid Build Coastguard Worker #include "selinux_netlink.h"
25*2d543d20SAndroid Build Coastguard Worker #include "avc_internal.h"
26*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
27*2d543d20SAndroid Build Coastguard Worker 
28*2d543d20SAndroid Build Coastguard Worker #ifndef NETLINK_SELINUX
29*2d543d20SAndroid Build Coastguard Worker #define NETLINK_SELINUX 7
30*2d543d20SAndroid Build Coastguard Worker #endif
31*2d543d20SAndroid Build Coastguard Worker 
32*2d543d20SAndroid Build Coastguard Worker /* callback pointers */
33*2d543d20SAndroid Build Coastguard Worker void *(*avc_func_malloc) (size_t) = NULL;
34*2d543d20SAndroid Build Coastguard Worker void (*avc_func_free) (void *) = NULL;
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker void (*avc_func_log) (const char *, ...) = NULL;
37*2d543d20SAndroid Build Coastguard Worker void (*avc_func_audit) (void *, security_class_t, char *, size_t) = NULL;
38*2d543d20SAndroid Build Coastguard Worker 
39*2d543d20SAndroid Build Coastguard Worker int avc_using_threads = 0;
40*2d543d20SAndroid Build Coastguard Worker int avc_app_main_loop = 0;
41*2d543d20SAndroid Build Coastguard Worker void *(*avc_func_create_thread) (void (*)(void)) = NULL;
42*2d543d20SAndroid Build Coastguard Worker void (*avc_func_stop_thread) (void *) = NULL;
43*2d543d20SAndroid Build Coastguard Worker 
44*2d543d20SAndroid Build Coastguard Worker void *(*avc_func_alloc_lock) (void) = NULL;
45*2d543d20SAndroid Build Coastguard Worker void (*avc_func_get_lock) (void *) = NULL;
46*2d543d20SAndroid Build Coastguard Worker void (*avc_func_release_lock) (void *) = NULL;
47*2d543d20SAndroid Build Coastguard Worker void (*avc_func_free_lock) (void *) = NULL;
48*2d543d20SAndroid Build Coastguard Worker 
49*2d543d20SAndroid Build Coastguard Worker /* message prefix string and avc enforcing mode */
50*2d543d20SAndroid Build Coastguard Worker char avc_prefix[AVC_PREFIX_SIZE] = "uavc";
51*2d543d20SAndroid Build Coastguard Worker int avc_running = 0;
52*2d543d20SAndroid Build Coastguard Worker int avc_enforcing = 1;
53*2d543d20SAndroid Build Coastguard Worker int avc_setenforce = 0;
54*2d543d20SAndroid Build Coastguard Worker 
55*2d543d20SAndroid Build Coastguard Worker /* process setenforce events for netlink and sestatus */
avc_process_setenforce(int enforcing)56*2d543d20SAndroid Build Coastguard Worker int avc_process_setenforce(int enforcing)
57*2d543d20SAndroid Build Coastguard Worker {
58*2d543d20SAndroid Build Coastguard Worker 	int rc = 0;
59*2d543d20SAndroid Build Coastguard Worker 
60*2d543d20SAndroid Build Coastguard Worker 	avc_log(SELINUX_SETENFORCE,
61*2d543d20SAndroid Build Coastguard Worker 		"%s:  op=setenforce lsm=selinux enforcing=%d res=1",
62*2d543d20SAndroid Build Coastguard Worker 		avc_prefix, enforcing);
63*2d543d20SAndroid Build Coastguard Worker 	if (avc_setenforce)
64*2d543d20SAndroid Build Coastguard Worker 		goto out;
65*2d543d20SAndroid Build Coastguard Worker 	avc_enforcing = enforcing;
66*2d543d20SAndroid Build Coastguard Worker 	if (avc_enforcing && (rc = avc_ss_reset(0)) < 0) {
67*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_ERROR,
68*2d543d20SAndroid Build Coastguard Worker 			"%s:  cache reset returned %d (errno %d)\n",
69*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, rc, errno);
70*2d543d20SAndroid Build Coastguard Worker 		return rc;
71*2d543d20SAndroid Build Coastguard Worker 	}
72*2d543d20SAndroid Build Coastguard Worker 
73*2d543d20SAndroid Build Coastguard Worker out:
74*2d543d20SAndroid Build Coastguard Worker 	return selinux_netlink_setenforce(enforcing);
75*2d543d20SAndroid Build Coastguard Worker }
76*2d543d20SAndroid Build Coastguard Worker 
77*2d543d20SAndroid Build Coastguard Worker /* process policyload events for netlink and sestatus */
avc_process_policyload(uint32_t seqno)78*2d543d20SAndroid Build Coastguard Worker int avc_process_policyload(uint32_t seqno)
79*2d543d20SAndroid Build Coastguard Worker {
80*2d543d20SAndroid Build Coastguard Worker 	int rc = 0;
81*2d543d20SAndroid Build Coastguard Worker 
82*2d543d20SAndroid Build Coastguard Worker 	avc_log(SELINUX_POLICYLOAD,
83*2d543d20SAndroid Build Coastguard Worker 		"%s:  op=load_policy lsm=selinux seqno=%u res=1",
84*2d543d20SAndroid Build Coastguard Worker 		avc_prefix, seqno);
85*2d543d20SAndroid Build Coastguard Worker 	rc = avc_ss_reset(seqno);
86*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0) {
87*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_ERROR,
88*2d543d20SAndroid Build Coastguard Worker 			"%s:  cache reset returned %d (errno %d)\n",
89*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, rc, errno);
90*2d543d20SAndroid Build Coastguard Worker 		return rc;
91*2d543d20SAndroid Build Coastguard Worker 	}
92*2d543d20SAndroid Build Coastguard Worker 
93*2d543d20SAndroid Build Coastguard Worker 	selinux_flush_class_cache();
94*2d543d20SAndroid Build Coastguard Worker 
95*2d543d20SAndroid Build Coastguard Worker 	return selinux_netlink_policyload(seqno);
96*2d543d20SAndroid Build Coastguard Worker }
97*2d543d20SAndroid Build Coastguard Worker 
98*2d543d20SAndroid Build Coastguard Worker /* netlink socket code */
99*2d543d20SAndroid Build Coastguard Worker static int fd = -1;
100*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_open(int blocking)101*2d543d20SAndroid Build Coastguard Worker int avc_netlink_open(int blocking)
102*2d543d20SAndroid Build Coastguard Worker {
103*2d543d20SAndroid Build Coastguard Worker 	int len, rc = 0;
104*2d543d20SAndroid Build Coastguard Worker 	struct sockaddr_nl addr;
105*2d543d20SAndroid Build Coastguard Worker 
106*2d543d20SAndroid Build Coastguard Worker 	fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_SELINUX);
107*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0) {
108*2d543d20SAndroid Build Coastguard Worker 		rc = fd;
109*2d543d20SAndroid Build Coastguard Worker 		goto out;
110*2d543d20SAndroid Build Coastguard Worker 	}
111*2d543d20SAndroid Build Coastguard Worker 
112*2d543d20SAndroid Build Coastguard Worker 	if (!blocking && fcntl(fd, F_SETFL, O_NONBLOCK)) {
113*2d543d20SAndroid Build Coastguard Worker 		close(fd);
114*2d543d20SAndroid Build Coastguard Worker 		fd = -1;
115*2d543d20SAndroid Build Coastguard Worker 		rc = -1;
116*2d543d20SAndroid Build Coastguard Worker 		goto out;
117*2d543d20SAndroid Build Coastguard Worker 	}
118*2d543d20SAndroid Build Coastguard Worker 
119*2d543d20SAndroid Build Coastguard Worker 	len = sizeof(addr);
120*2d543d20SAndroid Build Coastguard Worker 
121*2d543d20SAndroid Build Coastguard Worker 	memset(&addr, 0, len);
122*2d543d20SAndroid Build Coastguard Worker 	addr.nl_family = AF_NETLINK;
123*2d543d20SAndroid Build Coastguard Worker 	addr.nl_groups = SELNL_GRP_AVC;
124*2d543d20SAndroid Build Coastguard Worker 
125*2d543d20SAndroid Build Coastguard Worker 	if (bind(fd, (struct sockaddr *)&addr, len) < 0) {
126*2d543d20SAndroid Build Coastguard Worker 		close(fd);
127*2d543d20SAndroid Build Coastguard Worker 		fd = -1;
128*2d543d20SAndroid Build Coastguard Worker 		rc = -1;
129*2d543d20SAndroid Build Coastguard Worker 		goto out;
130*2d543d20SAndroid Build Coastguard Worker 	}
131*2d543d20SAndroid Build Coastguard Worker       out:
132*2d543d20SAndroid Build Coastguard Worker 	return rc;
133*2d543d20SAndroid Build Coastguard Worker }
134*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_close(void)135*2d543d20SAndroid Build Coastguard Worker void avc_netlink_close(void)
136*2d543d20SAndroid Build Coastguard Worker {
137*2d543d20SAndroid Build Coastguard Worker 	if (fd >= 0)
138*2d543d20SAndroid Build Coastguard Worker 		close(fd);
139*2d543d20SAndroid Build Coastguard Worker 	fd = -1;
140*2d543d20SAndroid Build Coastguard Worker }
141*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_receive(void * buf,unsigned buflen,int blocking)142*2d543d20SAndroid Build Coastguard Worker static int avc_netlink_receive(void *buf, unsigned buflen, int blocking)
143*2d543d20SAndroid Build Coastguard Worker {
144*2d543d20SAndroid Build Coastguard Worker 	int rc;
145*2d543d20SAndroid Build Coastguard Worker 	struct pollfd pfd = { fd, POLLIN | POLLPRI, 0 };
146*2d543d20SAndroid Build Coastguard Worker 	struct sockaddr_nl nladdr;
147*2d543d20SAndroid Build Coastguard Worker 	socklen_t nladdrlen = sizeof nladdr;
148*2d543d20SAndroid Build Coastguard Worker 	struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
149*2d543d20SAndroid Build Coastguard Worker 
150*2d543d20SAndroid Build Coastguard Worker 	do {
151*2d543d20SAndroid Build Coastguard Worker 		rc = poll(&pfd, 1, (blocking ? -1 : 0));
152*2d543d20SAndroid Build Coastguard Worker 	} while (rc < 0 && errno == EINTR);
153*2d543d20SAndroid Build Coastguard Worker 
154*2d543d20SAndroid Build Coastguard Worker 	if (rc == 0 && !blocking) {
155*2d543d20SAndroid Build Coastguard Worker 		errno = EWOULDBLOCK;
156*2d543d20SAndroid Build Coastguard Worker 		return -1;
157*2d543d20SAndroid Build Coastguard Worker 	}
158*2d543d20SAndroid Build Coastguard Worker 	else if (rc < 1) {
159*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_ERROR, "%s:  netlink poll: error %d\n",
160*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, errno);
161*2d543d20SAndroid Build Coastguard Worker 		return rc;
162*2d543d20SAndroid Build Coastguard Worker 	}
163*2d543d20SAndroid Build Coastguard Worker 
164*2d543d20SAndroid Build Coastguard Worker 	rc = recvfrom(fd, buf, buflen, 0, (struct sockaddr *)&nladdr,
165*2d543d20SAndroid Build Coastguard Worker 		      &nladdrlen);
166*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0)
167*2d543d20SAndroid Build Coastguard Worker 		return rc;
168*2d543d20SAndroid Build Coastguard Worker 
169*2d543d20SAndroid Build Coastguard Worker 	if (nladdrlen != sizeof nladdr) {
170*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_WARNING,
171*2d543d20SAndroid Build Coastguard Worker 			"%s:  warning: netlink address truncated, len %u?\n",
172*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, nladdrlen);
173*2d543d20SAndroid Build Coastguard Worker 		return -1;
174*2d543d20SAndroid Build Coastguard Worker 	}
175*2d543d20SAndroid Build Coastguard Worker 
176*2d543d20SAndroid Build Coastguard Worker 	if (nladdr.nl_pid) {
177*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_WARNING,
178*2d543d20SAndroid Build Coastguard Worker 			"%s:  warning: received spoofed netlink packet from: %u\n",
179*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, nladdr.nl_pid);
180*2d543d20SAndroid Build Coastguard Worker 		return -1;
181*2d543d20SAndroid Build Coastguard Worker 	}
182*2d543d20SAndroid Build Coastguard Worker 
183*2d543d20SAndroid Build Coastguard Worker 	if (rc == 0) {
184*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_WARNING,
185*2d543d20SAndroid Build Coastguard Worker 			"%s:  warning: received EOF on netlink socket\n",
186*2d543d20SAndroid Build Coastguard Worker 			avc_prefix);
187*2d543d20SAndroid Build Coastguard Worker 		errno = EBADFD;
188*2d543d20SAndroid Build Coastguard Worker 		return -1;
189*2d543d20SAndroid Build Coastguard Worker 	}
190*2d543d20SAndroid Build Coastguard Worker 
191*2d543d20SAndroid Build Coastguard Worker 	if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > (unsigned)rc) {
192*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_WARNING,
193*2d543d20SAndroid Build Coastguard Worker 			"%s:  warning: incomplete netlink message\n",
194*2d543d20SAndroid Build Coastguard Worker 			avc_prefix);
195*2d543d20SAndroid Build Coastguard Worker 		return -1;
196*2d543d20SAndroid Build Coastguard Worker 	}
197*2d543d20SAndroid Build Coastguard Worker 
198*2d543d20SAndroid Build Coastguard Worker 	return 0;
199*2d543d20SAndroid Build Coastguard Worker }
200*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_process(void * buf)201*2d543d20SAndroid Build Coastguard Worker static int avc_netlink_process(void *buf)
202*2d543d20SAndroid Build Coastguard Worker {
203*2d543d20SAndroid Build Coastguard Worker 	int rc;
204*2d543d20SAndroid Build Coastguard Worker 	struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
205*2d543d20SAndroid Build Coastguard Worker 
206*2d543d20SAndroid Build Coastguard Worker 	switch (nlh->nlmsg_type) {
207*2d543d20SAndroid Build Coastguard Worker 	case NLMSG_ERROR:{
208*2d543d20SAndroid Build Coastguard Worker 		struct nlmsgerr *err = NLMSG_DATA(nlh);
209*2d543d20SAndroid Build Coastguard Worker 
210*2d543d20SAndroid Build Coastguard Worker 		/* Netlink ack */
211*2d543d20SAndroid Build Coastguard Worker 		if (err->error == 0)
212*2d543d20SAndroid Build Coastguard Worker 			break;
213*2d543d20SAndroid Build Coastguard Worker 
214*2d543d20SAndroid Build Coastguard Worker 		errno = -err->error;
215*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_ERROR,
216*2d543d20SAndroid Build Coastguard Worker 			"%s:  netlink error: %d\n", avc_prefix, errno);
217*2d543d20SAndroid Build Coastguard Worker 		return -1;
218*2d543d20SAndroid Build Coastguard Worker 	}
219*2d543d20SAndroid Build Coastguard Worker 
220*2d543d20SAndroid Build Coastguard Worker 	case SELNL_MSG_SETENFORCE:{
221*2d543d20SAndroid Build Coastguard Worker 		struct selnl_msg_setenforce *msg = NLMSG_DATA(nlh);
222*2d543d20SAndroid Build Coastguard Worker 		rc = avc_process_setenforce(!!msg->val);
223*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
224*2d543d20SAndroid Build Coastguard Worker 			return rc;
225*2d543d20SAndroid Build Coastguard Worker 		break;
226*2d543d20SAndroid Build Coastguard Worker 	}
227*2d543d20SAndroid Build Coastguard Worker 
228*2d543d20SAndroid Build Coastguard Worker 	case SELNL_MSG_POLICYLOAD:{
229*2d543d20SAndroid Build Coastguard Worker 		struct selnl_msg_policyload *msg = NLMSG_DATA(nlh);
230*2d543d20SAndroid Build Coastguard Worker 		rc = avc_process_policyload(msg->seqno);
231*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
232*2d543d20SAndroid Build Coastguard Worker 			return rc;
233*2d543d20SAndroid Build Coastguard Worker 		break;
234*2d543d20SAndroid Build Coastguard Worker 	}
235*2d543d20SAndroid Build Coastguard Worker 
236*2d543d20SAndroid Build Coastguard Worker 	default:
237*2d543d20SAndroid Build Coastguard Worker 		avc_log(SELINUX_WARNING,
238*2d543d20SAndroid Build Coastguard Worker 			"%s:  warning: unknown netlink message %d\n",
239*2d543d20SAndroid Build Coastguard Worker 			avc_prefix, nlh->nlmsg_type);
240*2d543d20SAndroid Build Coastguard Worker 	}
241*2d543d20SAndroid Build Coastguard Worker 	return 0;
242*2d543d20SAndroid Build Coastguard Worker }
243*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_check_nb(void)244*2d543d20SAndroid Build Coastguard Worker int avc_netlink_check_nb(void)
245*2d543d20SAndroid Build Coastguard Worker {
246*2d543d20SAndroid Build Coastguard Worker 	int rc;
247*2d543d20SAndroid Build Coastguard Worker 	char buf[1024] __attribute__ ((aligned));
248*2d543d20SAndroid Build Coastguard Worker 
249*2d543d20SAndroid Build Coastguard Worker 	while (1) {
250*2d543d20SAndroid Build Coastguard Worker 		errno = 0;
251*2d543d20SAndroid Build Coastguard Worker 		rc = avc_netlink_receive(buf, sizeof(buf), 0);
252*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
253*2d543d20SAndroid Build Coastguard Worker 			if (errno == EWOULDBLOCK)
254*2d543d20SAndroid Build Coastguard Worker 				return 0;
255*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0 || errno == EINTR)
256*2d543d20SAndroid Build Coastguard Worker 				continue;
257*2d543d20SAndroid Build Coastguard Worker 			else {
258*2d543d20SAndroid Build Coastguard Worker 				avc_log(SELINUX_ERROR,
259*2d543d20SAndroid Build Coastguard Worker 					"%s:  netlink recvfrom: error %d\n",
260*2d543d20SAndroid Build Coastguard Worker 					avc_prefix, errno);
261*2d543d20SAndroid Build Coastguard Worker 				return rc;
262*2d543d20SAndroid Build Coastguard Worker 			}
263*2d543d20SAndroid Build Coastguard Worker 		}
264*2d543d20SAndroid Build Coastguard Worker 
265*2d543d20SAndroid Build Coastguard Worker 		(void)avc_netlink_process(buf);
266*2d543d20SAndroid Build Coastguard Worker 	}
267*2d543d20SAndroid Build Coastguard Worker 	return 0;
268*2d543d20SAndroid Build Coastguard Worker }
269*2d543d20SAndroid Build Coastguard Worker 
270*2d543d20SAndroid Build Coastguard Worker /* run routine for the netlink listening thread */
avc_netlink_loop(void)271*2d543d20SAndroid Build Coastguard Worker void avc_netlink_loop(void)
272*2d543d20SAndroid Build Coastguard Worker {
273*2d543d20SAndroid Build Coastguard Worker 	int rc;
274*2d543d20SAndroid Build Coastguard Worker 	char buf[1024] __attribute__ ((aligned));
275*2d543d20SAndroid Build Coastguard Worker 
276*2d543d20SAndroid Build Coastguard Worker 	while (1) {
277*2d543d20SAndroid Build Coastguard Worker 		errno = 0;
278*2d543d20SAndroid Build Coastguard Worker 		rc = avc_netlink_receive(buf, sizeof(buf), 1);
279*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
280*2d543d20SAndroid Build Coastguard Worker 			if (errno == 0 || errno == EINTR)
281*2d543d20SAndroid Build Coastguard Worker 				continue;
282*2d543d20SAndroid Build Coastguard Worker 			else {
283*2d543d20SAndroid Build Coastguard Worker 				avc_log(SELINUX_ERROR,
284*2d543d20SAndroid Build Coastguard Worker 					"%s:  netlink recvfrom: error %d\n",
285*2d543d20SAndroid Build Coastguard Worker 					avc_prefix, errno);
286*2d543d20SAndroid Build Coastguard Worker 				break;
287*2d543d20SAndroid Build Coastguard Worker 			}
288*2d543d20SAndroid Build Coastguard Worker 		}
289*2d543d20SAndroid Build Coastguard Worker 
290*2d543d20SAndroid Build Coastguard Worker 		rc = avc_netlink_process(buf);
291*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0)
292*2d543d20SAndroid Build Coastguard Worker 			break;
293*2d543d20SAndroid Build Coastguard Worker 	}
294*2d543d20SAndroid Build Coastguard Worker 
295*2d543d20SAndroid Build Coastguard Worker 	close(fd);
296*2d543d20SAndroid Build Coastguard Worker 	fd = -1;
297*2d543d20SAndroid Build Coastguard Worker 	avc_log(SELINUX_ERROR,
298*2d543d20SAndroid Build Coastguard Worker 		"%s:  netlink thread: errors encountered, terminating\n",
299*2d543d20SAndroid Build Coastguard Worker 		avc_prefix);
300*2d543d20SAndroid Build Coastguard Worker }
301*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_acquire_fd(void)302*2d543d20SAndroid Build Coastguard Worker int avc_netlink_acquire_fd(void)
303*2d543d20SAndroid Build Coastguard Worker {
304*2d543d20SAndroid Build Coastguard Worker 	if (fd < 0) {
305*2d543d20SAndroid Build Coastguard Worker 		int rc = 0;
306*2d543d20SAndroid Build Coastguard Worker 		rc = avc_netlink_open(0);
307*2d543d20SAndroid Build Coastguard Worker 		if (rc < 0) {
308*2d543d20SAndroid Build Coastguard Worker 			avc_log(SELINUX_ERROR,
309*2d543d20SAndroid Build Coastguard Worker 				"%s: could not open netlink socket: %d (%m)\n",
310*2d543d20SAndroid Build Coastguard Worker 				avc_prefix, errno);
311*2d543d20SAndroid Build Coastguard Worker 			return rc;
312*2d543d20SAndroid Build Coastguard Worker 		}
313*2d543d20SAndroid Build Coastguard Worker 	}
314*2d543d20SAndroid Build Coastguard Worker 
315*2d543d20SAndroid Build Coastguard Worker     avc_app_main_loop = 1;
316*2d543d20SAndroid Build Coastguard Worker 
317*2d543d20SAndroid Build Coastguard Worker     return fd;
318*2d543d20SAndroid Build Coastguard Worker }
319*2d543d20SAndroid Build Coastguard Worker 
avc_netlink_release_fd(void)320*2d543d20SAndroid Build Coastguard Worker void avc_netlink_release_fd(void)
321*2d543d20SAndroid Build Coastguard Worker {
322*2d543d20SAndroid Build Coastguard Worker     avc_app_main_loop = 0;
323*2d543d20SAndroid Build Coastguard Worker }
324