20 |
"disabled", "enabled" |
"disabled", "enabled" |
21 |
}; |
}; |
22 |
|
|
23 |
static const char *ccs_keyword_mode[4] = { |
static const char *ccs_mode_4[4] = { |
24 |
"MAC_MODE_DISABLED", "MAC_MODE_LEARNING", |
"disabled", "learning", "permissive", "enforcing" |
|
"MAC_MODE_PERMISSIVE", "MAC_MODE_ENFORCING" |
|
25 |
}; |
}; |
26 |
|
|
27 |
static const char *ccs_keyword_audit[2] = { |
static bool ccs_mac_keywords_used[CCS_MAX_MAC_INDEX + |
28 |
"NO_AUDIT_GRANT_LOG", "NO_AUDIT_REJECT_LOG" |
CCS_MAX_CAPABILITY_INDEX]; |
|
}; |
|
29 |
|
|
30 |
static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX + |
static const char *ccs_mac_keywords[CCS_MAX_MAC_INDEX + |
31 |
CCS_MAX_CAPABILITY_INDEX] = { |
CCS_MAX_CAPABILITY_INDEX] = { |
204 |
return ptr; |
return ptr; |
205 |
} |
} |
206 |
|
|
|
static int ccs_find_match(char *str) |
|
|
{ |
|
|
int i; |
|
|
if (ccs_str_starts(&str, CCS_KEYWORD_CAPABILITY)) |
|
|
for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) { |
|
|
if (strcmp(str, |
|
|
ccs_mac_keywords[CCS_MAX_MAC_INDEX + i])) |
|
|
continue; |
|
|
return CCS_MAX_MAC_INDEX + i; |
|
|
} |
|
|
else |
|
|
for (i = 0; i < CCS_MAX_MAC_INDEX; i++) { |
|
|
if (strcmp(str, ccs_mac_keywords[i])) |
|
|
continue; |
|
|
return i; |
|
|
} |
|
|
return -1; |
|
|
} |
|
|
|
|
207 |
/** |
/** |
208 |
* ccs_write_profile - Write profile table. |
* ccs_write_profile - Write profile table. |
209 |
* |
* |
216 |
char *data = head->write_buf; |
char *data = head->write_buf; |
217 |
unsigned int i; |
unsigned int i; |
218 |
unsigned int value; |
unsigned int value; |
219 |
|
int index = -1; |
220 |
int mode; |
int mode; |
221 |
char *cp; |
char *cp; |
222 |
struct ccs_profile *ccs_profile; |
struct ccs_profile *ccs_profile; |
232 |
cp = strchr(data, '='); |
cp = strchr(data, '='); |
233 |
if (!cp) |
if (!cp) |
234 |
return -EINVAL; |
return -EINVAL; |
235 |
*cp = '\0'; |
*cp++ = '\0'; |
236 |
if (!strcmp(data, "COMMENT")) { |
if (!strcmp(data, "COMMENT")) { |
237 |
const struct ccs_path_info *new_comment |
const struct ccs_path_info *new_comment = ccs_get_name(cp); |
|
= ccs_get_name(cp + 1); |
|
238 |
const struct ccs_path_info *old_comment; |
const struct ccs_path_info *old_comment; |
239 |
/* Protect reader from ccs_put_name(). */ |
/* Protect reader from ccs_put_name(). */ |
240 |
/***** CRITICAL SECTION START *****/ |
/***** CRITICAL SECTION START *****/ |
246 |
ccs_put_name(old_comment); |
ccs_put_name(old_comment); |
247 |
return 0; |
return 0; |
248 |
} |
} |
249 |
for (mode = 0; mode < 4; mode++) { |
if (!ccs_str_starts(&data, "MAC::")) |
250 |
if (strcmp(data, ccs_keyword_mode[mode])) |
goto not_mac; |
251 |
continue; |
if (ccs_str_starts(&data, CCS_KEYWORD_CAPABILITY)) |
252 |
cp++; |
for (i = 0; i < CCS_MAX_CAPABILITY_INDEX; i++) { |
253 |
while (1) { |
if (strcmp(data, |
254 |
int index; |
ccs_mac_keywords[CCS_MAX_MAC_INDEX + i])) |
255 |
char *cp2 = strchr(cp, ' '); |
continue; |
256 |
if (cp2) |
index = CCS_MAX_MAC_INDEX + i; |
257 |
*cp2 = '\0'; |
break; |
|
index = ccs_find_match(cp); |
|
|
if (index >= 0) |
|
|
ccs_profile->mac_mode[index] = mode; |
|
|
if (!cp2) |
|
|
break; |
|
|
cp = cp2 + 1; |
|
258 |
} |
} |
259 |
return 0; |
else |
260 |
} |
for (i = 0; i < CCS_MAX_MAC_INDEX; i++) { |
261 |
for (mode = 0; mode < 2; mode++) { |
if (strcmp(data, ccs_mac_keywords[i])) |
262 |
if (strcmp(data, ccs_keyword_audit[mode])) |
continue; |
263 |
continue; |
index = i; |
264 |
memset(ccs_profile->dont_audit[mode], 0, |
break; |
|
sizeof(ccs_profile->dont_audit[mode])); |
|
|
cp++; |
|
|
while (1) { |
|
|
int index; |
|
|
char *cp2 = strchr(cp, ' '); |
|
|
if (cp2) |
|
|
*cp2 = '\0'; |
|
|
index = ccs_find_match(cp); |
|
|
if (index >= 0) |
|
|
ccs_profile->dont_audit[mode][index] = true; |
|
|
if (!cp2) |
|
|
break; |
|
|
cp = cp2 + 1; |
|
265 |
} |
} |
266 |
return 0; |
if (index < 0) |
267 |
} |
return -EINVAL; |
268 |
|
ccs_mac_keywords_used[index] = 1; |
269 |
|
ccs_profile->no_grant_log[index] = !!strstr(cp, "no_grant_log"); |
270 |
|
ccs_profile->no_reject_log[index] = !!strstr(cp, "no_reject_log"); |
271 |
|
for (mode = 0; mode < 4; mode++) |
272 |
|
if (strstr(cp, ccs_mode_4[mode])) |
273 |
|
ccs_profile->mac_mode[index] = mode; |
274 |
|
return 0; |
275 |
|
not_mac: |
276 |
for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) { |
for (i = 0; i < CCS_MAX_CONTROL_INDEX; i++) { |
277 |
if (strcmp(data, ccs_control_array[i].keyword)) |
if (strcmp(data, ccs_control_array[i].keyword)) |
278 |
continue; |
continue; |
279 |
if (sscanf(cp + 1, "%u", &value) != 1) { |
if (sscanf(cp, "%u", &value) != 1) { |
280 |
int j; |
int j; |
281 |
for (j = 0; j < 2; j++) { |
for (j = 0; j < 2; j++) { |
282 |
if (strcmp(cp + 1, ccs_mode_2[j])) |
if (strcmp(cp, ccs_mode_2[j])) |
283 |
continue; |
continue; |
284 |
value = j; |
value = j; |
285 |
break; |
break; |
286 |
} |
} |
287 |
if (j == 4) |
if (j == 2) |
288 |
return -EINVAL; |
return -EINVAL; |
289 |
} else if (value > ccs_control_array[i].max_value) { |
} else if (value > ccs_control_array[i].max_value) { |
290 |
value = ccs_control_array[i].max_value; |
value = ccs_control_array[i].max_value; |
299 |
{ |
{ |
300 |
const int pos = head->read_avail; |
const int pos = head->read_avail; |
301 |
int i; |
int i; |
|
int mode; |
|
|
const struct ccs_profile *ccs_profile = ccs_profile_ptr[index]; |
|
|
for (mode = 0; mode < 4; mode++) { |
|
|
if (!ccs_io_printf(head, "%u-%s={", index, |
|
|
ccs_keyword_mode[mode])) |
|
|
goto out; |
|
|
for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX; |
|
|
i++) { |
|
|
if (ccs_profile->mac_mode[i] != mode) |
|
|
continue; |
|
|
if (!ccs_io_printf(head, " %s%s", |
|
|
i >= CCS_MAX_MAC_INDEX ? |
|
|
CCS_KEYWORD_CAPABILITY : "", |
|
|
ccs_mac_keywords[i])) |
|
|
goto out; |
|
|
} |
|
|
if (!ccs_io_printf(head, " }\n")) |
|
|
goto out; |
|
|
} |
|
|
return true; |
|
|
out: |
|
|
head->read_avail = pos; |
|
|
return false; |
|
|
} |
|
|
|
|
|
static bool ccs_print_audit_mode(struct ccs_io_buffer *head, u8 index) |
|
|
{ |
|
|
const int pos = head->read_avail; |
|
|
int i; |
|
|
int mode; |
|
302 |
const struct ccs_profile *ccs_profile = ccs_profile_ptr[index]; |
const struct ccs_profile *ccs_profile = ccs_profile_ptr[index]; |
303 |
for (mode = 0; mode < 2; mode++) { |
for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX; i++) { |
304 |
if (!ccs_io_printf(head, "%u-%s={", index, |
if (!ccs_mac_keywords_used[index]) |
305 |
ccs_keyword_audit[mode])) |
continue; |
306 |
goto out; |
if (!ccs_io_printf(head, "%u-MAC::%s%s=%s %s %s\n", index, |
307 |
for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_CAPABILITY_INDEX; |
i >= CCS_MAX_MAC_INDEX ? |
308 |
i++) { |
CCS_KEYWORD_CAPABILITY : "", |
309 |
if (!ccs_profile->dont_audit[mode][i]) |
ccs_mac_keywords[i], |
310 |
continue; |
ccs_mode_4[ccs_profile->mac_mode[i]], |
311 |
if (!ccs_io_printf(head, " %s%s", |
ccs_profile->no_grant_log[i] ? |
312 |
i >= CCS_MAX_MAC_INDEX ? |
"no_grant_log" : "", |
313 |
CCS_KEYWORD_CAPABILITY : "", |
ccs_profile->no_reject_log[i] ? |
314 |
ccs_mac_keywords[i])) |
"no_reject_log" : "")) |
|
goto out; |
|
|
} |
|
|
if (!ccs_io_printf(head, " }\n")) |
|
315 |
goto out; |
goto out; |
316 |
} |
} |
317 |
return true; |
return true; |
357 |
if (!ccs_print_mac_mode(head, index)) |
if (!ccs_print_mac_mode(head, index)) |
358 |
break; |
break; |
359 |
continue; |
continue; |
|
} else if (type == 2) { |
|
|
if (!ccs_print_audit_mode(head, index)) |
|
|
break; |
|
|
continue; |
|
360 |
} |
} |
361 |
type -= 3; |
type -= 2; |
362 |
{ |
{ |
363 |
const unsigned int value = ccs_profile->value[type]; |
const unsigned int value = ccs_profile->value[type]; |
364 |
const char *keyword = ccs_control_array[type].keyword; |
const char *keyword = ccs_control_array[type].keyword; |