Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/1.6.x/ccs-patch/fs/tomoyo_audit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1014 - (show annotations) (download) (as text)
Tue Mar 4 01:58:08 2008 UTC (16 years, 3 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 7422 byte(s)


1 /*
2 * fs/tomoyo_audit.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.0-pre 2008/03/04
9 *
10 * This file is applicable to both 2.4.30 and 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 *
13 */
14 /***** TOMOYO Linux start. *****/
15
16 #include <linux/ccs_common.h>
17 #include <linux/tomoyo.h>
18 #include <linux/highmem.h>
19 #include <linux/binfmts.h>
20
21 static char *DumpBprm(struct linux_binprm *bprm)
22 {
23 static const int buffer_len = PAGE_SIZE * 2;
24 char *buffer = ccs_alloc(buffer_len);
25 char *cp, *last_start;
26 int len;
27 unsigned long pos = bprm->p;
28 int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;
29 int argv_count = bprm->argc;
30 int envp_count = bprm->envc;
31 bool truncated = false;
32 if (!buffer) return NULL;
33 len = snprintf(buffer, buffer_len - 1, "argc=%d envc=%d argv[]={ ", argv_count, envp_count);
34 cp = buffer + len;
35 if (!argv_count) {
36 memmove(cp, "} envp[]={ ", 11);
37 cp += 11;
38 }
39 if (!envp_count) *cp++ = '}';
40 last_start = cp;
41 while (argv_count || envp_count) {
42 struct page *page;
43 const char *kaddr;
44 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
45 if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) goto out;
46 pos += PAGE_SIZE - offset;
47 #else
48 page = bprm->page[i];
49 #endif
50 /* Map */
51 kaddr = kmap(page);
52 if (!kaddr) { /* Mapping failed. */
53 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
54 put_page(page);
55 #endif
56 goto out;
57 }
58 /* Read. */
59 while (offset < PAGE_SIZE) {
60 const unsigned char c = kaddr[offset++];
61 if (cp == last_start) *cp++ = '"';
62 if (cp >= buffer + buffer_len - 32) {
63 /* Preserve some room for "..." string. */
64 truncated = true;
65 } else if (c == '\\') {
66 *cp++ = '\\';
67 *cp++ = '\\';
68 } else if (c > ' ' && c < 127) {
69 *cp++ = c;
70 } else if (!c) {
71 *cp++ = '"';
72 *cp++ = ' ';
73 last_start = cp;
74 } else {
75 *cp++ = '\\';
76 *cp++ = (c >> 6) + '0';
77 *cp++ = ((c >> 3) & 7) + '0';
78 *cp++ = (c & 7) + '0';
79 }
80 if (c) continue;
81 if (argv_count) {
82 if (--argv_count == 0) {
83 if (truncated) {
84 cp = last_start;
85 memmove(cp, "... ", 4);
86 cp += 4;
87 }
88 memmove(cp, "} envp[]={ ", 11);
89 cp += 11;
90 if (!envp_count) goto no_envp;
91 last_start = cp;
92 }
93 } else if (envp_count) {
94 if (--envp_count == 0) {
95 if (truncated) {
96 cp = last_start;
97 memmove(cp, "... ", 4);
98 cp += 4;
99 }
100 no_envp:
101 *cp++ = '}';
102 *cp++ = '\0';
103 }
104 } else {
105 break;
106 }
107 }
108 /* Unmap. */
109 kunmap(page);
110 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
111 put_page(page);
112 #endif
113 i++;
114 offset = 0;
115 }
116 return buffer;
117 out:
118 snprintf(buffer, buffer_len - 1, "argc=%d envc=%d argv[]={ ... } envp[]= { ... }", argv_count, envp_count);
119 return buffer;
120 }
121
122 /************************* AUDIT FUNCTIONS *************************/
123
124 static DECLARE_WAIT_QUEUE_HEAD(grant_log_wait);
125 static DECLARE_WAIT_QUEUE_HEAD(reject_log_wait);
126
127 static spinlock_t audit_log_lock = SPIN_LOCK_UNLOCKED;
128
129 struct log_entry {
130 struct list_head list;
131 char *log;
132 };
133
134 static LIST_HEAD(grant_log);
135 static LIST_HEAD(reject_log);
136
137 static int grant_log_count = 0, reject_log_count = 0;
138
139 char *InitAuditLog(int *len, const u8 profile, const u8 mode, struct linux_binprm *bprm)
140 {
141 static const char *mode_4[4] = { "disabled", "learning", "permissive", "enforcing" };
142 char *buf;
143 char *bprm_info = "";
144 struct timeval tv;
145 struct task_struct *task = current;
146 u32 tomoyo_flags = task->tomoyo_flags;
147 const char *domainname = current->domain_info->domainname->name;
148 do_gettimeofday(&tv);
149 *len += strlen(domainname) + 256;
150 if (bprm) {
151 bprm_info = DumpBprm(bprm);
152 if (!bprm_info) return NULL;
153 *len += strlen(bprm_info);
154 }
155 if ((buf = ccs_alloc(*len)) != NULL) snprintf(buf, (*len) - 1, "#timestamp=%lu profile=%u mode=%s pid=%d uid=%d gid=%d euid=%d egid=%d suid=%d sgid=%d fsuid=%d fsgid=%d state[0]=%u state[1]=%u state[2]=%u %s\n%s\n", tv.tv_sec, profile, mode_4[mode], task->pid, task->uid, task->gid, task->euid, task->egid, task->suid, task->sgid, task->fsuid, task->fsgid, (u8) (tomoyo_flags >> 24), (u8) (tomoyo_flags >> 16), (u8) (tomoyo_flags >> 8), bprm_info, domainname);
156 if (bprm) ccs_free(bprm_info);
157 return buf;
158 }
159
160 static unsigned int GetMaxGrantLog(void)
161 {
162 return CheckCCSFlags(CCS_TOMOYO_MAX_GRANT_LOG);
163 }
164
165 static unsigned int GetMaxRejectLog(void)
166 {
167 return CheckCCSFlags(CCS_TOMOYO_MAX_REJECT_LOG);
168 }
169
170 /*
171 * Write audit log.
172 * Caller must allocate buf with InitAuditLog().
173 */
174 int WriteAuditLog(char *buf, const bool is_granted)
175 {
176 struct log_entry *new_entry = ccs_alloc(sizeof(*new_entry));
177 if (!new_entry) goto out;
178 INIT_LIST_HEAD(&new_entry->list);
179 new_entry->log = buf;
180 /***** CRITICAL SECTION START *****/
181 spin_lock(&audit_log_lock);
182 if (is_granted) {
183 if (grant_log_count < GetMaxGrantLog()) {
184 list_add_tail(&new_entry->list, &grant_log);
185 grant_log_count++;
186 buf = NULL;
187 UpdateCounter(CCS_UPDATES_COUNTER_GRANT_LOG);
188 }
189 } else {
190 if (reject_log_count < GetMaxRejectLog()) {
191 list_add_tail(&new_entry->list, &reject_log);
192 reject_log_count++;
193 buf = NULL;
194 UpdateCounter(CCS_UPDATES_COUNTER_REJECT_LOG);
195 }
196 }
197 spin_unlock(&audit_log_lock);
198 /***** CRITICAL SECTION END *****/
199 if (is_granted) wake_up(&grant_log_wait);
200 else wake_up(&reject_log_wait);
201 if (!buf) return 0;
202 ccs_free(new_entry);
203 out: ;
204 ccs_free(buf);
205 return -ENOMEM;
206 }
207
208 int CanSaveAuditLog(const bool is_granted)
209 {
210 if (is_granted) {
211 if (grant_log_count < GetMaxGrantLog()) return 0;
212 } else {
213 if (reject_log_count < GetMaxRejectLog()) return 0;
214 }
215 return -ENOMEM;
216 }
217
218 int ReadGrantLog(struct io_buffer *head)
219 {
220 struct log_entry *ptr = NULL;
221 if (head->read_avail) return 0;
222 if (head->read_buf) {
223 ccs_free(head->read_buf); head->read_buf = NULL;
224 head->readbuf_size = 0;
225 }
226 /***** CRITICAL SECTION START *****/
227 spin_lock(&audit_log_lock);
228 if (!list_empty(&grant_log)) {
229 ptr = list_entry(grant_log.next, struct log_entry, list);
230 list_del(&ptr->list);
231 grant_log_count--;
232 }
233 spin_unlock(&audit_log_lock);
234 /***** CRITICAL SECTION END *****/
235 if (ptr) {
236 head->read_buf = ptr->log;
237 head->readbuf_size = head->read_avail = strlen(ptr->log) + 1;
238 ccs_free(ptr);
239 }
240 return 0;
241 }
242
243 int PollGrantLog(struct file *file, poll_table *wait)
244 {
245 if (grant_log_count) return POLLIN | POLLRDNORM;
246 poll_wait(file, &grant_log_wait, wait);
247 if (grant_log_count) return POLLIN | POLLRDNORM;
248 return 0;
249 }
250
251 int ReadRejectLog(struct io_buffer *head)
252 {
253 struct log_entry *ptr = NULL;
254 if (head->read_avail) return 0;
255 if (head->read_buf) {
256 ccs_free(head->read_buf); head->read_buf = NULL;
257 head->readbuf_size = 0;
258 }
259 /***** CRITICAL SECTION START *****/
260 spin_lock(&audit_log_lock);
261 if (!list_empty(&reject_log)) {
262 ptr = list_entry(reject_log.next, struct log_entry, list);
263 list_del(&ptr->list);
264 reject_log_count--;
265 }
266 spin_unlock(&audit_log_lock);
267 /***** CRITICAL SECTION END *****/
268 if (ptr) {
269 head->read_buf = ptr->log;
270 head->readbuf_size = head->read_avail = strlen(ptr->log) + 1;
271 ccs_free(ptr);
272 }
273 return 0;
274 }
275
276 int PollRejectLog(struct file *file, poll_table *wait)
277 {
278 if (reject_log_count) return POLLIN | POLLRDNORM;
279 poll_wait(file, &reject_log_wait, wait);
280 if (reject_log_count) return POLLIN | POLLRDNORM;
281 return 0;
282 }
283
284 /***** TOMOYO Linux end. *****/

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26