]>
Commit | Line | Data |
---|---|---|
81611586 RS |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | /*** | |
4 | This file is part of systemd. | |
5 | ||
6 | Copyright 2010 Lennart Poettering | |
7 | Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy | |
8 | TORSEC group -- http://security.polito.it | |
9 | ||
10 | systemd is free software; you can redistribute it and/or modify it | |
5430f7f2 LP |
11 | under the terms of the GNU Lesser General Public License as published by |
12 | the Free Software Foundation; either version 2.1 of the License, or | |
81611586 RS |
13 | (at your option) any later version. |
14 | ||
15 | systemd is distributed in the hope that it will be useful, but | |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
5430f7f2 | 18 | Lesser General Public License for more details. |
81611586 | 19 | |
5430f7f2 | 20 | You should have received a copy of the GNU Lesser General Public License |
81611586 RS |
21 | along with systemd; If not, see <http://www.gnu.org/licenses/>. |
22 | ***/ | |
23 | ||
24 | #include <unistd.h> | |
25 | #include <stdio.h> | |
26 | #include <errno.h> | |
27 | #include <string.h> | |
28 | #include <stdlib.h> | |
29 | #include <fcntl.h> | |
30 | #include <sys/stat.h> | |
31 | #include <sys/mman.h> | |
32 | ||
33 | #include "ima-setup.h" | |
34 | #include "mount-setup.h" | |
35 | #include "macro.h" | |
36 | #include "util.h" | |
37 | #include "log.h" | |
38 | #include "label.h" | |
39 | ||
40 | #define IMA_SECFS_DIR "/sys/kernel/security/ima" | |
41 | #define IMA_SECFS_POLICY IMA_SECFS_DIR "/policy" | |
42 | #define IMA_POLICY_PATH "/etc/ima/ima-policy" | |
43 | ||
44 | int ima_setup(void) { | |
45 | ||
46 | #ifdef HAVE_IMA | |
47 | struct stat st; | |
48 | ssize_t policy_size = 0, written = 0; | |
49 | char *policy; | |
50 | int policyfd = -1, imafd = -1; | |
51 | int result = 0; | |
52 | ||
53 | #ifndef HAVE_SELINUX | |
54 | /* Mount the securityfs filesystem */ | |
55 | mount_setup_early(); | |
56 | #endif | |
57 | ||
58 | if (stat(IMA_POLICY_PATH, &st) < 0) | |
59 | return 0; | |
60 | ||
61 | policy_size = st.st_size; | |
62 | if (stat(IMA_SECFS_DIR, &st) < 0) { | |
63 | log_debug("IMA support is disabled in the kernel, ignoring."); | |
64 | return 0; | |
65 | } | |
66 | ||
67 | if (stat(IMA_SECFS_POLICY, &st) < 0) { | |
68 | log_error("Another IMA custom policy has already been loaded, " | |
69 | "ignoring."); | |
70 | return 0; | |
71 | } | |
72 | ||
73 | policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC); | |
74 | if (policyfd < 0) { | |
75 | log_error("Failed to open the IMA custom policy file %s (%m), " | |
76 | "ignoring.", IMA_POLICY_PATH); | |
77 | return 0; | |
78 | } | |
79 | ||
80 | imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC); | |
81 | if (imafd < 0) { | |
82 | log_error("Failed to open the IMA kernel interface %s (%m), " | |
83 | "ignoring.", IMA_SECFS_POLICY); | |
84 | goto out; | |
85 | } | |
86 | ||
87 | policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0); | |
88 | if (policy == MAP_FAILED) { | |
89 | log_error("mmap() failed (%m), freezing"); | |
90 | result = -errno; | |
91 | goto out; | |
92 | } | |
93 | ||
94 | written = loop_write(imafd, policy, (size_t)policy_size, false); | |
95 | if (written != policy_size) { | |
96 | log_error("Failed to load the IMA custom policy file %s (%m), " | |
97 | "ignoring.", IMA_POLICY_PATH); | |
98 | goto out_mmap; | |
99 | } | |
100 | ||
101 | log_info("Successfully loaded the IMA custom policy %s.", | |
102 | IMA_POLICY_PATH); | |
103 | out_mmap: | |
104 | munmap(policy, policy_size); | |
105 | out: | |
106 | if (policyfd >= 0) | |
107 | close_nointr_nofail(policyfd); | |
108 | if (imafd >= 0) | |
109 | close_nointr_nofail(imafd); | |
110 | if (result) | |
111 | return result; | |
112 | #endif /* HAVE_IMA */ | |
113 | ||
114 | return 0; | |
115 | } |