1f08c3bdfSopenharmony_ci/******************************************************************************/
2f08c3bdfSopenharmony_ci/*                                                                            */
3f08c3bdfSopenharmony_ci/* Copyright (c) Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>, 2009      */
4f08c3bdfSopenharmony_ci/*                                                                            */
5f08c3bdfSopenharmony_ci/* This program is free software;  you can redistribute it and/or modify      */
6f08c3bdfSopenharmony_ci/* it under the terms of the GNU General Public License as published by       */
7f08c3bdfSopenharmony_ci/* the Free Software Foundation; either version 2 of the License, or          */
8f08c3bdfSopenharmony_ci/* (at your option) any later version.                                        */
9f08c3bdfSopenharmony_ci/*                                                                            */
10f08c3bdfSopenharmony_ci/* This program is distributed in the hope that it will be useful,            */
11f08c3bdfSopenharmony_ci/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            */
12f08c3bdfSopenharmony_ci/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  */
13f08c3bdfSopenharmony_ci/* the GNU General Public License for more details.                           */
14f08c3bdfSopenharmony_ci/*                                                                            */
15f08c3bdfSopenharmony_ci/* You should have received a copy of the GNU General Public License          */
16f08c3bdfSopenharmony_ci/* along with this program;  if not, write to the Free Software               */
17f08c3bdfSopenharmony_ci/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA    */
18f08c3bdfSopenharmony_ci/*                                                                            */
19f08c3bdfSopenharmony_ci/******************************************************************************/
20f08c3bdfSopenharmony_ci/*
21f08c3bdfSopenharmony_ci * include.h
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * Common functions for testing TOMOYO Linux's kernel.
24f08c3bdfSopenharmony_ci *
25f08c3bdfSopenharmony_ci * Copyright (C) 2005-2010  NTT DATA CORPORATION
26f08c3bdfSopenharmony_ci */
27f08c3bdfSopenharmony_ci#include <errno.h>
28f08c3bdfSopenharmony_ci#include <fcntl.h>
29f08c3bdfSopenharmony_ci#include <linux/kdev_t.h>
30f08c3bdfSopenharmony_ci#include <linux/unistd.h>
31f08c3bdfSopenharmony_ci#include <pty.h>
32f08c3bdfSopenharmony_ci#include <stdio.h>
33f08c3bdfSopenharmony_ci#include <stdlib.h>
34f08c3bdfSopenharmony_ci#include <string.h>
35f08c3bdfSopenharmony_ci#include <sys/socket.h>
36f08c3bdfSopenharmony_ci#include <sys/stat.h>
37f08c3bdfSopenharmony_ci#include <sys/syscall.h>
38f08c3bdfSopenharmony_ci#include <sys/time.h>
39f08c3bdfSopenharmony_ci#include <sys/timex.h>
40f08c3bdfSopenharmony_ci#include <sys/types.h>
41f08c3bdfSopenharmony_ci#include <sys/un.h>
42f08c3bdfSopenharmony_ci#include <sys/wait.h>
43f08c3bdfSopenharmony_ci#include <time.h>
44f08c3bdfSopenharmony_ci#include <unistd.h>
45f08c3bdfSopenharmony_ci#include <utime.h>
46f08c3bdfSopenharmony_ci#include <sched.h>
47f08c3bdfSopenharmony_ci#include <stdarg.h>
48f08c3bdfSopenharmony_ci#include <sys/mount.h>
49f08c3bdfSopenharmony_ci#include <arpa/inet.h>
50f08c3bdfSopenharmony_ci#include <net/if.h>
51f08c3bdfSopenharmony_ci#include <linux/ip.h>
52f08c3bdfSopenharmony_ci#include <err.h>
53f08c3bdfSopenharmony_ci#include "test.h"
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ci/*
56f08c3bdfSopenharmony_ci * Some architectures like mips n32 don't have __NR_uselib defined in the
57f08c3bdfSopenharmony_ci * system headers.
58f08c3bdfSopenharmony_ci */
59f08c3bdfSopenharmony_ci#ifdef __NR_uselib
60f08c3bdfSopenharmony_cistatic inline int uselib(const char *library)
61f08c3bdfSopenharmony_ci{
62f08c3bdfSopenharmony_ci	return syscall(__NR_uselib, library);
63f08c3bdfSopenharmony_ci}
64f08c3bdfSopenharmony_ci#else
65f08c3bdfSopenharmony_cistatic inline int uselib(const char *library)
66f08c3bdfSopenharmony_ci{
67f08c3bdfSopenharmony_ci	errno = ENOSYS;
68f08c3bdfSopenharmony_ci	return -1;
69f08c3bdfSopenharmony_ci}
70f08c3bdfSopenharmony_ci#endif
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci/* Is there an architecture without __NR_pivot_root defined? */
73f08c3bdfSopenharmony_ci#ifdef __NR_pivot_root
74f08c3bdfSopenharmony_cistatic inline int pivot_root(const char *new_root, const char *put_old)
75f08c3bdfSopenharmony_ci{
76f08c3bdfSopenharmony_ci	return syscall(__NR_pivot_root, new_root, put_old);
77f08c3bdfSopenharmony_ci}
78f08c3bdfSopenharmony_ci#else
79f08c3bdfSopenharmony_cistatic inline int pivot_root(const char *new_root, const char *put_old)
80f08c3bdfSopenharmony_ci{
81f08c3bdfSopenharmony_ci	errno = ENOSYS;
82f08c3bdfSopenharmony_ci	return -1;
83f08c3bdfSopenharmony_ci}
84f08c3bdfSopenharmony_ci#endif
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ci/* The sysctl() wrapper is dead and newer arches omit it now. */
87f08c3bdfSopenharmony_cistatic inline int write_sysctl(const char *path, const char *value)
88f08c3bdfSopenharmony_ci{
89f08c3bdfSopenharmony_ci	FILE *fp = fopen(path, "w");
90f08c3bdfSopenharmony_ci	if (!fp)
91f08c3bdfSopenharmony_ci		return 1;
92f08c3bdfSopenharmony_ci	fputs(value, fp);
93f08c3bdfSopenharmony_ci	fclose(fp);
94f08c3bdfSopenharmony_ci	return 0;
95f08c3bdfSopenharmony_ci}
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_cistatic inline int read_sysctl(const char *path, char *value, int len)
98f08c3bdfSopenharmony_ci{
99f08c3bdfSopenharmony_ci	char scratch[100];
100f08c3bdfSopenharmony_ci	FILE *fp = fopen(path, "r");
101f08c3bdfSopenharmony_ci	if (!fp)
102f08c3bdfSopenharmony_ci		return 1;
103f08c3bdfSopenharmony_ci	if (!value) {
104f08c3bdfSopenharmony_ci		value = scratch;
105f08c3bdfSopenharmony_ci		len = sizeof(scratch);
106f08c3bdfSopenharmony_ci	}
107f08c3bdfSopenharmony_ci	if (fgets(value, len, fp))
108f08c3bdfSopenharmony_ci		/* ignore */;
109f08c3bdfSopenharmony_ci	fclose(fp);
110f08c3bdfSopenharmony_ci	return 0;
111f08c3bdfSopenharmony_ci}
112f08c3bdfSopenharmony_ci
113f08c3bdfSopenharmony_ci/* Should be a fairly benign path to bang on. */
114f08c3bdfSopenharmony_ci#define TEST_SYSCTL_PATH "/proc/sys/net/ipv4/ip_local_port_range"
115f08c3bdfSopenharmony_ci
116f08c3bdfSopenharmony_ci#define proc_policy_dir              "/sys/kernel/security/tomoyo/"
117f08c3bdfSopenharmony_ci#define proc_policy_domain_policy    "/sys/kernel/security/tomoyo/domain_policy"
118f08c3bdfSopenharmony_ci#define proc_policy_exception_policy "/sys/kernel/security/tomoyo/exception_policy"
119f08c3bdfSopenharmony_ci#define proc_policy_profile          "/sys/kernel/security/tomoyo/profile"
120f08c3bdfSopenharmony_ci#define proc_policy_manager          "/sys/kernel/security/tomoyo/manager"
121f08c3bdfSopenharmony_ci#define proc_policy_query            "/sys/kernel/security/tomoyo/query"
122f08c3bdfSopenharmony_ci#define proc_policy_grant_log        "/sys/kernel/security/tomoyo/grant_log"
123f08c3bdfSopenharmony_ci#define proc_policy_reject_log       "/sys/kernel/security/tomoyo/reject_log"
124f08c3bdfSopenharmony_ci#define proc_policy_domain_status    "/sys/kernel/security/tomoyo/.domain_status"
125f08c3bdfSopenharmony_ci#define proc_policy_process_status   "/sys/kernel/security/tomoyo/.process_status"
126f08c3bdfSopenharmony_ci#define proc_policy_self_domain      "/sys/kernel/security/tomoyo/self_domain"
127f08c3bdfSopenharmony_ci
128f08c3bdfSopenharmony_cistatic FILE *profile_fp = NULL;
129f08c3bdfSopenharmony_cistatic FILE *domain_fp = NULL;
130f08c3bdfSopenharmony_cistatic FILE *exception_fp = NULL;
131f08c3bdfSopenharmony_cistatic char self_domain[4096] = "";
132f08c3bdfSopenharmony_cistatic pid_t pid = 0;
133f08c3bdfSopenharmony_ci
134f08c3bdfSopenharmony_cistatic void clear_status(void)
135f08c3bdfSopenharmony_ci{
136f08c3bdfSopenharmony_ci	static const char *keywords[] = {
137f08c3bdfSopenharmony_ci		"file::execute",
138f08c3bdfSopenharmony_ci		"file::open",
139f08c3bdfSopenharmony_ci		"file::create",
140f08c3bdfSopenharmony_ci		"file::unlink",
141f08c3bdfSopenharmony_ci		"file::mkdir",
142f08c3bdfSopenharmony_ci		"file::rmdir",
143f08c3bdfSopenharmony_ci		"file::mkfifo",
144f08c3bdfSopenharmony_ci		"file::mksock",
145f08c3bdfSopenharmony_ci		"file::truncate",
146f08c3bdfSopenharmony_ci		"file::symlink",
147f08c3bdfSopenharmony_ci		"file::rewrite",
148f08c3bdfSopenharmony_ci		"file::mkblock",
149f08c3bdfSopenharmony_ci		"file::mkchar",
150f08c3bdfSopenharmony_ci		"file::link",
151f08c3bdfSopenharmony_ci		"file::rename",
152f08c3bdfSopenharmony_ci		"file::chmod",
153f08c3bdfSopenharmony_ci		"file::chown",
154f08c3bdfSopenharmony_ci		"file::chgrp",
155f08c3bdfSopenharmony_ci		"file::ioctl",
156f08c3bdfSopenharmony_ci		"file::chroot",
157f08c3bdfSopenharmony_ci		"file::mount",
158f08c3bdfSopenharmony_ci		"file::umount",
159f08c3bdfSopenharmony_ci		"file::pivot_root",
160f08c3bdfSopenharmony_ci		NULL
161f08c3bdfSopenharmony_ci	};
162f08c3bdfSopenharmony_ci	int i;
163f08c3bdfSopenharmony_ci	FILE *fp = fopen(proc_policy_profile, "r");
164f08c3bdfSopenharmony_ci	static char buffer[4096];
165f08c3bdfSopenharmony_ci	if (!fp) {
166f08c3bdfSopenharmony_ci		fprintf(stderr, "Can't open %s\n", proc_policy_profile);
167f08c3bdfSopenharmony_ci		exit(1);
168f08c3bdfSopenharmony_ci	}
169f08c3bdfSopenharmony_ci	for (i = 0; keywords[i]; i++)
170f08c3bdfSopenharmony_ci		fprintf(profile_fp,
171f08c3bdfSopenharmony_ci			"255-CONFIG::%s={ mode=disabled }\n",
172f08c3bdfSopenharmony_ci			keywords[i]);
173f08c3bdfSopenharmony_ci	while (memset(buffer, 0, sizeof(buffer)),
174f08c3bdfSopenharmony_ci	       fgets(buffer, sizeof(buffer) - 10, fp)) {
175f08c3bdfSopenharmony_ci		const char *mode;
176f08c3bdfSopenharmony_ci		char *cp = strchr(buffer, '=');
177f08c3bdfSopenharmony_ci		if (!cp)
178f08c3bdfSopenharmony_ci			continue;
179f08c3bdfSopenharmony_ci		*cp = '\0';
180f08c3bdfSopenharmony_ci		mode = cp + 1;
181f08c3bdfSopenharmony_ci		cp = strchr(buffer, '-');
182f08c3bdfSopenharmony_ci		if (!cp)
183f08c3bdfSopenharmony_ci			continue;
184f08c3bdfSopenharmony_ci		*cp++ = '\0';
185f08c3bdfSopenharmony_ci		if (strcmp(buffer, "0"))
186f08c3bdfSopenharmony_ci			continue;
187f08c3bdfSopenharmony_ci		fprintf(profile_fp, "255-%s", cp);
188f08c3bdfSopenharmony_ci		if (!strcmp(cp, "COMMENT"))
189f08c3bdfSopenharmony_ci			mode = "Profile for kernel test\n";
190f08c3bdfSopenharmony_ci		else
191f08c3bdfSopenharmony_ci			mode = "{ mode=disabled verbose=no }\n";
192f08c3bdfSopenharmony_ci		fprintf(profile_fp, "255-%s=%s", cp, mode);
193f08c3bdfSopenharmony_ci	}
194f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-PREFERENCE::learning= verbose=no\n");
195f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-PREFERENCE::enforcing= verbose=no\n");
196f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-PREFERENCE::permissive= verbose=no\n");
197f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-PREFERENCE::disabled= verbose=no\n");
198f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-PREFERENCE::learning= max_entry=2048\n");
199f08c3bdfSopenharmony_ci	fflush(profile_fp);
200f08c3bdfSopenharmony_ci	fclose(fp);
201f08c3bdfSopenharmony_ci}
202f08c3bdfSopenharmony_ci
203f08c3bdfSopenharmony_cistatic void tomoyo_test_init(void)
204f08c3bdfSopenharmony_ci{
205f08c3bdfSopenharmony_ci	pid = getpid();
206f08c3bdfSopenharmony_ci	if (access(proc_policy_dir, F_OK)) {
207f08c3bdfSopenharmony_ci		fprintf(stderr, "You can't use this program for this kernel."
208f08c3bdfSopenharmony_ci			"\n");
209f08c3bdfSopenharmony_ci		exit(1);
210f08c3bdfSopenharmony_ci	}
211f08c3bdfSopenharmony_ci	profile_fp = fopen(proc_policy_profile, "w");
212f08c3bdfSopenharmony_ci	if (!profile_fp) {
213f08c3bdfSopenharmony_ci		fprintf(stderr, "Can't open %s .\n", proc_policy_profile);
214f08c3bdfSopenharmony_ci		exit(1);
215f08c3bdfSopenharmony_ci	}
216f08c3bdfSopenharmony_ci	setlinebuf(profile_fp);
217f08c3bdfSopenharmony_ci	domain_fp = fopen(proc_policy_domain_policy, "w");
218f08c3bdfSopenharmony_ci	if (!domain_fp) {
219f08c3bdfSopenharmony_ci		fprintf(stderr, "Can't open %s .\n",
220f08c3bdfSopenharmony_ci			proc_policy_domain_policy);
221f08c3bdfSopenharmony_ci		exit(1);
222f08c3bdfSopenharmony_ci	}
223f08c3bdfSopenharmony_ci	setlinebuf(domain_fp);
224f08c3bdfSopenharmony_ci	exception_fp = fopen(proc_policy_exception_policy, "w");
225f08c3bdfSopenharmony_ci	if (!exception_fp) {
226f08c3bdfSopenharmony_ci		fprintf(stderr, "Can't open %s .\n",
227f08c3bdfSopenharmony_ci			proc_policy_exception_policy);
228f08c3bdfSopenharmony_ci		exit(1);
229f08c3bdfSopenharmony_ci	}
230f08c3bdfSopenharmony_ci	setlinebuf(exception_fp);
231f08c3bdfSopenharmony_ci	if (fputc('\n', profile_fp) != '\n' || fflush(profile_fp)) {
232f08c3bdfSopenharmony_ci		fprintf(stderr, "You need to register this program to %s to "
233f08c3bdfSopenharmony_ci			"run this program.\n", proc_policy_manager);
234f08c3bdfSopenharmony_ci		exit(1);
235f08c3bdfSopenharmony_ci	}
236f08c3bdfSopenharmony_ci	clear_status();
237f08c3bdfSopenharmony_ci	{
238f08c3bdfSopenharmony_ci		FILE *fp = fopen(proc_policy_self_domain, "r");
239f08c3bdfSopenharmony_ci		memset(self_domain, 0, sizeof(self_domain));
240f08c3bdfSopenharmony_ci		if (!fp || !fgets(self_domain, sizeof(self_domain) - 1, fp) ||
241f08c3bdfSopenharmony_ci		    fclose(fp)) {
242f08c3bdfSopenharmony_ci			fprintf(stderr, "Can't open %s .\n",
243f08c3bdfSopenharmony_ci				proc_policy_self_domain);
244f08c3bdfSopenharmony_ci			exit(1);
245f08c3bdfSopenharmony_ci		}
246f08c3bdfSopenharmony_ci	}
247f08c3bdfSopenharmony_ci	fprintf(domain_fp, "select pid=%u\n", pid);
248f08c3bdfSopenharmony_ci	fprintf(domain_fp, "use_profile 255\n");
249f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/domain_policy\n");
250f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/domain_policy\n");
251f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/exception_policy\n");
252f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/exception_policy\n");
253f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_read/write /sys/kernel/security/tomoyo/profile\n");
254f08c3bdfSopenharmony_ci	fprintf(domain_fp, "allow_truncate /sys/kernel/security/tomoyo/profile\n");
255f08c3bdfSopenharmony_ci}
256f08c3bdfSopenharmony_ci
257f08c3bdfSopenharmony_cistatic void BUG(const char *fmt, ...)
258f08c3bdfSopenharmony_ci	__attribute__ ((format(printf, 1, 2)));
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_cistatic void BUG(const char *fmt, ...)
261f08c3bdfSopenharmony_ci{
262f08c3bdfSopenharmony_ci	va_list args;
263f08c3bdfSopenharmony_ci	printf("BUG: ");
264f08c3bdfSopenharmony_ci	va_start(args, fmt);
265f08c3bdfSopenharmony_ci	vprintf(fmt, args);
266f08c3bdfSopenharmony_ci	va_end(args);
267f08c3bdfSopenharmony_ci	putchar('\n');
268f08c3bdfSopenharmony_ci	fflush(stdout);
269f08c3bdfSopenharmony_ci	while (1)
270f08c3bdfSopenharmony_ci		sleep(100);
271f08c3bdfSopenharmony_ci}
272f08c3bdfSopenharmony_ci
273f08c3bdfSopenharmony_ciint write_domain_policy(const char *policy, int is_delete)
274f08c3bdfSopenharmony_ci{
275f08c3bdfSopenharmony_ci	FILE *fp = fopen(proc_policy_domain_policy, "r");
276f08c3bdfSopenharmony_ci	char buffer[8192];
277f08c3bdfSopenharmony_ci	int domain_found = 0;
278f08c3bdfSopenharmony_ci	int policy_found = 0;
279f08c3bdfSopenharmony_ci	memset(buffer, 0, sizeof(buffer));
280f08c3bdfSopenharmony_ci	if (!fp) {
281f08c3bdfSopenharmony_ci		BUG("Can't read %s", proc_policy_domain_policy);
282f08c3bdfSopenharmony_ci		return 0;
283f08c3bdfSopenharmony_ci	}
284f08c3bdfSopenharmony_ci	if (is_delete)
285f08c3bdfSopenharmony_ci		fprintf(domain_fp, "delete ");
286f08c3bdfSopenharmony_ci	fprintf(domain_fp, "%s\n", policy);
287f08c3bdfSopenharmony_ci	while (fgets(buffer, sizeof(buffer) - 1, fp)) {
288f08c3bdfSopenharmony_ci		char *cp = strchr(buffer, '\n');
289f08c3bdfSopenharmony_ci		if (cp)
290f08c3bdfSopenharmony_ci			*cp = '\0';
291f08c3bdfSopenharmony_ci		if (!strncmp(buffer, "<kernel>", 8))
292f08c3bdfSopenharmony_ci			domain_found = !strcmp(self_domain, buffer);
293f08c3bdfSopenharmony_ci		if (!domain_found)
294f08c3bdfSopenharmony_ci			continue;
295f08c3bdfSopenharmony_ci		/* printf("<%s>\n", buffer); */
296f08c3bdfSopenharmony_ci		if (strcmp(buffer, policy))
297f08c3bdfSopenharmony_ci			continue;
298f08c3bdfSopenharmony_ci		policy_found = 1;
299f08c3bdfSopenharmony_ci		break;
300f08c3bdfSopenharmony_ci	}
301f08c3bdfSopenharmony_ci	fclose(fp);
302f08c3bdfSopenharmony_ci	if (policy_found == is_delete) {
303f08c3bdfSopenharmony_ci		BUG("Can't %s %s", is_delete ? "delete" : "append",
304f08c3bdfSopenharmony_ci		    policy);
305f08c3bdfSopenharmony_ci		return 0;
306f08c3bdfSopenharmony_ci	}
307f08c3bdfSopenharmony_ci	errno = 0;
308f08c3bdfSopenharmony_ci	return 1;
309f08c3bdfSopenharmony_ci
310f08c3bdfSopenharmony_ci}
311f08c3bdfSopenharmony_ci
312f08c3bdfSopenharmony_ciint write_exception_policy(const char *policy, int is_delete)
313f08c3bdfSopenharmony_ci{
314f08c3bdfSopenharmony_ci	FILE *fp = fopen(proc_policy_exception_policy, "r");
315f08c3bdfSopenharmony_ci	char buffer[8192];
316f08c3bdfSopenharmony_ci	int policy_found = 0;
317f08c3bdfSopenharmony_ci	memset(buffer, 0, sizeof(buffer));
318f08c3bdfSopenharmony_ci	if (!fp) {
319f08c3bdfSopenharmony_ci		BUG("Can't read %s", proc_policy_exception_policy);
320f08c3bdfSopenharmony_ci		return 0;
321f08c3bdfSopenharmony_ci	}
322f08c3bdfSopenharmony_ci	if (is_delete)
323f08c3bdfSopenharmony_ci		fprintf(exception_fp, "delete ");
324f08c3bdfSopenharmony_ci	fprintf(exception_fp, "%s\n", policy);
325f08c3bdfSopenharmony_ci	while (fgets(buffer, sizeof(buffer) - 1, fp)) {
326f08c3bdfSopenharmony_ci		char *cp = strchr(buffer, '\n');
327f08c3bdfSopenharmony_ci		if (cp)
328f08c3bdfSopenharmony_ci			*cp = '\0';
329f08c3bdfSopenharmony_ci		if (strcmp(buffer, policy))
330f08c3bdfSopenharmony_ci			continue;
331f08c3bdfSopenharmony_ci		policy_found = 1;
332f08c3bdfSopenharmony_ci		break;
333f08c3bdfSopenharmony_ci	}
334f08c3bdfSopenharmony_ci	fclose(fp);
335f08c3bdfSopenharmony_ci	if (policy_found == is_delete) {
336f08c3bdfSopenharmony_ci		BUG("Can't %s %s", is_delete ? "delete" : "append",
337f08c3bdfSopenharmony_ci		    policy);
338f08c3bdfSopenharmony_ci		return 0;
339f08c3bdfSopenharmony_ci	}
340f08c3bdfSopenharmony_ci	errno = 0;
341f08c3bdfSopenharmony_ci	return 1;
342f08c3bdfSopenharmony_ci
343f08c3bdfSopenharmony_ci}
344f08c3bdfSopenharmony_ci
345f08c3bdfSopenharmony_ciint set_profile(const int mode, const char *name)
346f08c3bdfSopenharmony_ci{
347f08c3bdfSopenharmony_ci	static const char *modes[4] = { "disabled", "learning", "permissive",
348f08c3bdfSopenharmony_ci					"enforcing" };
349f08c3bdfSopenharmony_ci	FILE *fp = fopen(proc_policy_profile, "r");
350f08c3bdfSopenharmony_ci	char buffer[8192];
351f08c3bdfSopenharmony_ci	int policy_found = 0;
352f08c3bdfSopenharmony_ci	const int len = strlen(name);
353f08c3bdfSopenharmony_ci	if (!fp) {
354f08c3bdfSopenharmony_ci		BUG("Can't read %s", proc_policy_profile);
355f08c3bdfSopenharmony_ci		return 0;
356f08c3bdfSopenharmony_ci	}
357f08c3bdfSopenharmony_ci	fprintf(profile_fp, "255-CONFIG::%s=%s\n", name, modes[mode]);
358f08c3bdfSopenharmony_ci	while (memset(buffer, 0, sizeof(buffer)),
359f08c3bdfSopenharmony_ci	       fgets(buffer, sizeof(buffer) - 1, fp)) {
360f08c3bdfSopenharmony_ci		char *cp = strchr(buffer, '\n');
361f08c3bdfSopenharmony_ci		if (cp)
362f08c3bdfSopenharmony_ci			*cp = '\0';
363f08c3bdfSopenharmony_ci		if (strncmp(buffer, "255-CONFIG::", 12) ||
364f08c3bdfSopenharmony_ci		    strncmp(buffer + 12, name, len) ||
365f08c3bdfSopenharmony_ci		    buffer[12 + len] != '=')
366f08c3bdfSopenharmony_ci			continue;
367f08c3bdfSopenharmony_ci		if (strstr(buffer + 13 + len, modes[mode]))
368f08c3bdfSopenharmony_ci			policy_found = 1;
369f08c3bdfSopenharmony_ci		break;
370f08c3bdfSopenharmony_ci	}
371f08c3bdfSopenharmony_ci	fclose(fp);
372f08c3bdfSopenharmony_ci	if (!policy_found) {
373f08c3bdfSopenharmony_ci		BUG("Can't change profile to 255-CONFIG::%s=%s",
374f08c3bdfSopenharmony_ci		    name, modes[mode]);
375f08c3bdfSopenharmony_ci		return 0;
376f08c3bdfSopenharmony_ci	}
377f08c3bdfSopenharmony_ci	errno = 0;
378f08c3bdfSopenharmony_ci	return 1;
379f08c3bdfSopenharmony_ci}
380