-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ima: define template fields library and new helpers
This patch defines a library containing two initial template fields, inode digest (d) and file name (n), the 'ima' template descriptor, whose format is 'd|n', and two helper functions, ima_write_template_field_data() and ima_show_template_field_data(). Changelog: - replace ima_eventname_init() parameter NULL checking with BUG_ON. (suggested by Mimi) - include "new template fields for inode digest (d) and file name (n)" definitions to fix a compiler warning. - Mimi - unnecessary to prefix static function names with 'ima_'. remove prefix to resolve Lindent formatting changes. - Mimi - abbreviated/removed inline comments - Mimi - always send the template field length - Mimi Signed-off-by: Roberto Sassu <roberto.sassu@polito.it> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
- Loading branch information
Roberto Sassu
authored and
Mimi Zohar
committed
Oct 25, 2013
1 parent
adf53a7
commit 3ce1217
Showing
6 changed files
with
242 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* | ||
* Copyright (C) 2013 Politecnico di Torino, Italy | ||
* TORSEC group -- http://security.polito.it | ||
* | ||
* Author: Roberto Sassu <roberto.sassu@polito.it> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation, version 2 of the | ||
* License. | ||
* | ||
* File: ima_template_lib.c | ||
* Library of supported template fields. | ||
*/ | ||
#include "ima_template_lib.h" | ||
|
||
enum data_formats { DATA_FMT_DIGEST = 0, DATA_FMT_EVENT_NAME, DATA_FMT_STRING }; | ||
static int ima_write_template_field_data(const void *data, const u32 datalen, | ||
enum data_formats datafmt, | ||
struct ima_field_data *field_data) | ||
{ | ||
u8 *buf, *buf_ptr; | ||
u32 buflen; | ||
|
||
switch (datafmt) { | ||
case DATA_FMT_EVENT_NAME: | ||
buflen = IMA_EVENT_NAME_LEN_MAX + 1; | ||
break; | ||
case DATA_FMT_STRING: | ||
buflen = datalen + 1; | ||
break; | ||
default: | ||
buflen = datalen; | ||
} | ||
|
||
buf = kzalloc(buflen, GFP_KERNEL); | ||
if (!buf) | ||
return -ENOMEM; | ||
|
||
memcpy(buf, data, datalen); | ||
|
||
/* | ||
* Replace all space characters with underscore for event names and | ||
* strings. This avoid that, during the parsing of a measurements list, | ||
* filenames with spaces or that end with the suffix ' (deleted)' are | ||
* split into multiple template fields (the space is the delimitator | ||
* character for measurements lists in ASCII format). | ||
*/ | ||
if (datafmt == DATA_FMT_EVENT_NAME || datafmt == DATA_FMT_STRING) { | ||
for (buf_ptr = buf; buf_ptr - buf < datalen; buf_ptr++) | ||
if (*buf_ptr == ' ') | ||
*buf_ptr = '_'; | ||
} | ||
|
||
field_data->data = buf; | ||
field_data->len = buflen; | ||
return 0; | ||
} | ||
|
||
static void ima_show_template_data_ascii(struct seq_file *m, | ||
enum ima_show_type show, | ||
enum data_formats datafmt, | ||
struct ima_field_data *field_data) | ||
{ | ||
switch (datafmt) { | ||
case DATA_FMT_DIGEST: | ||
ima_print_digest(m, field_data->data, field_data->len); | ||
break; | ||
case DATA_FMT_STRING: | ||
seq_printf(m, "%s", field_data->data); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
static void ima_show_template_data_binary(struct seq_file *m, | ||
enum ima_show_type show, | ||
enum data_formats datafmt, | ||
struct ima_field_data *field_data) | ||
{ | ||
ima_putc(m, &field_data->len, sizeof(u32)); | ||
if (!field_data->len) | ||
return; | ||
ima_putc(m, field_data->data, field_data->len); | ||
} | ||
|
||
static void ima_show_template_field_data(struct seq_file *m, | ||
enum ima_show_type show, | ||
enum data_formats datafmt, | ||
struct ima_field_data *field_data) | ||
{ | ||
switch (show) { | ||
case IMA_SHOW_ASCII: | ||
ima_show_template_data_ascii(m, show, datafmt, field_data); | ||
break; | ||
case IMA_SHOW_BINARY: | ||
ima_show_template_data_binary(m, show, datafmt, field_data); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, | ||
struct ima_field_data *field_data) | ||
{ | ||
ima_show_template_field_data(m, show, DATA_FMT_DIGEST, field_data); | ||
} | ||
|
||
void ima_show_template_string(struct seq_file *m, enum ima_show_type show, | ||
struct ima_field_data *field_data) | ||
{ | ||
ima_show_template_field_data(m, show, DATA_FMT_STRING, field_data); | ||
} | ||
|
||
/* | ||
* This function writes the digest of an event. | ||
*/ | ||
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | ||
const unsigned char *filename, | ||
struct ima_field_data *field_data) | ||
{ | ||
struct { | ||
struct ima_digest_data hdr; | ||
char digest[IMA_MAX_DIGEST_SIZE]; | ||
} hash; | ||
u8 *cur_digest = hash.hdr.digest; | ||
u32 cur_digestsize = IMA_DIGEST_SIZE; | ||
struct inode *inode; | ||
int result; | ||
|
||
memset(&hash, 0, sizeof(hash)); | ||
|
||
if (!iint) /* recording a violation. */ | ||
goto out; | ||
|
||
if (iint->ima_hash->algo == ima_hash_algo) { | ||
cur_digest = iint->ima_hash->digest; | ||
cur_digestsize = iint->ima_hash->length; | ||
goto out; | ||
} | ||
|
||
if (!file) /* missing info to re-calculate the digest */ | ||
return -EINVAL; | ||
|
||
inode = file_inode(file); | ||
hash.hdr.algo = ima_hash_algo; | ||
result = ima_calc_file_hash(file, &hash.hdr); | ||
if (result) { | ||
integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, | ||
filename, "collect_data", | ||
"failed", result, 0); | ||
return result; | ||
} | ||
out: | ||
return ima_write_template_field_data(cur_digest, cur_digestsize, | ||
DATA_FMT_DIGEST, field_data); | ||
} | ||
|
||
/* | ||
* This function writes the name of an event. | ||
*/ | ||
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | ||
const unsigned char *filename, | ||
struct ima_field_data *field_data) | ||
{ | ||
const char *cur_filename = NULL; | ||
u32 cur_filename_len = 0; | ||
|
||
BUG_ON(filename == NULL && file == NULL); | ||
|
||
if (filename) { | ||
cur_filename = filename; | ||
cur_filename_len = strlen(filename); | ||
|
||
if (cur_filename_len <= IMA_EVENT_NAME_LEN_MAX) | ||
goto out; | ||
} | ||
|
||
if (file) { | ||
cur_filename = file->f_dentry->d_name.name; | ||
cur_filename_len = strlen(cur_filename); | ||
} else | ||
/* | ||
* Truncate filename if the latter is too long and | ||
* the file descriptor is not available. | ||
*/ | ||
cur_filename_len = IMA_EVENT_NAME_LEN_MAX; | ||
out: | ||
return ima_write_template_field_data(cur_filename, cur_filename_len, | ||
DATA_FMT_EVENT_NAME, field_data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright (C) 2013 Politecnico di Torino, Italy | ||
* TORSEC group -- http://security.polito.it | ||
* | ||
* Author: Roberto Sassu <roberto.sassu@polito.it> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation, version 2 of the | ||
* License. | ||
* | ||
* File: ima_template_lib.h | ||
* Header for the library of supported template fields. | ||
*/ | ||
#ifndef __LINUX_IMA_TEMPLATE_LIB_H | ||
#define __LINUX_IMA_TEMPLATE_LIB_H | ||
|
||
#include <linux/seq_file.h> | ||
#include "ima.h" | ||
|
||
void ima_show_template_digest(struct seq_file *m, enum ima_show_type show, | ||
struct ima_field_data *field_data); | ||
void ima_show_template_string(struct seq_file *m, enum ima_show_type show, | ||
struct ima_field_data *field_data); | ||
int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, | ||
const unsigned char *filename, | ||
struct ima_field_data *field_data); | ||
int ima_eventname_init(struct integrity_iint_cache *iint, struct file *file, | ||
const unsigned char *filename, | ||
struct ima_field_data *field_data); | ||
#endif /* __LINUX_IMA_TEMPLATE_LIB_H */ |