On Thu, 2009-03-05 at 11:25 -0500, Mimi Zohar wrote: > This patch adds testcases for the Integrity Measurement Architecture(IMA). > > Signed-off-by: Mimi Zohar <[email protected]>
Hi Mimi, Thanks for these test cases. I will get back to you for any clarification shortly and after i have executed them. Regards-- Subrata > > Index: ltp-full-20090228/testcases/kernel/security/integrity/ima/README > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/README > @@ -0,0 +1,40 @@ > +These testcases test the Integrity Measurement Architecture(IMA). > + > +Requirements > +------------ > +In order for all of the tests in the testsuite to complete successfully: > + - A kernel with Linux Integrity Module(LIM), IMA, CRYPTO, SYSFS, > + SECURITYFS, TPM support and TPM driver builtin is required. > + - The testsuite must be executed with root priveleges so that it > + can access securityfs files, such as: security/ima/policy and > + security/ima/ascii_runtime_measurement. > + - Both sysfs and securityfs if not mounted, will be mounted. > + - To verify the IMA measurement list, openssl must be installed. > + If it is not installed, these tests will not be compiled or executed. > + - To test that on the next read after a file changes, the file will > + be re-measured, the $TMP directory must be mounted with i_version > + support(Bugzilla 471593). If $TMP is on any partition other than > + root, add 'iversion' option in /etc/fstab: "defaults,iversion". > + If $TMP is on the root partition, 'iversion' must be added in > + /etc/rc.sysinit: > + > + # Remount the root filesystem read-write. > + update_boot_stage RCmountfs > + if remount_needed ; then > + action $"Remounting root filesystem in read-write mode: " mount -n -o > remount,rw,iversion / > + fi > + > + > +Dependency > +---------- > +The testsuite is dependent on the default policy being enabled, which > +measures all executables, all files mmapped for execute and all files > +open for read by root. If the default policy has been replaced, loading > +another measurement policy will fail, as the policy may only be replaced > +once per boot. Some of the policy dependency tests might also fail as well. > + > +System State after running the Testsuite > +---------------------------------------- > +After running the testsuite, the default measurement policy was replaced > +with an identical policy. If you want to install a different one, such > +as an LSM specific one, a reboot would be required. > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/measure.policy > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/measure.policy > @@ -0,0 +1,16 @@ > +# > +# Integrity measure policy > +# > +# PROC_SUPER_MAGIC > +dont_measure fsmagic=0x9fa0 > +# SYSFS_MAGIC > +dont_measure fsmagic=0x62656572 > +# DEBUGFS_MAGIC > +dont_measure fsmagic=0x64626720 > +# TMPFS_MAGIC > +dont_measure fsmagic=0x01021994 > +# SECURITYFS_MAGIC > +dont_measure fsmagic=0x73636673 > +measure func=FILE_MMAP mask=MAY_EXEC > +measure func=BPRM_CHECK mask=MAY_EXEC > +measure func=PATH_CHECK mask=MAY_READ uid=0 > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/measure.policy-invalid > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/measure.policy-invalid > @@ -0,0 +1,16 @@ > +# > +# Integrity measure policy > +# > +# PROC_SUPER_MAGIC > +dont_measure fsmagic=0x9fa0 > +# SYSFS_MAGIC > +dont_measure fsmagic=0x62656572 > +# DEBUGFS_MAGIC > +dont_measure fsmagic=0x64626720 > +# TMPFS_MAGIC > +dont_measure fsmagic=0x01021994 > +# SECURITYFS_MAGIC > +dnt_measure fsmagic=0x73636673 > +measure func=FILE_MMAP mask=MAY_EXEC > +measure func=BPRM_CHECK mask=MAY_EXEC > +measure func=PATH_CHECK mask=MAY_READ uid=0 > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh > @@ -0,0 +1,186 @@ > +#!/bin/sh > + > +################################################################################ > +## > ## > +## Copyright (C) 2009 IBM Corporation > ## > +## > ## > +## 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; either version 2 of the License, or > ## > +## (at your option) any later version. > ## > +## > ## > +## This program is distributed in the hope that it will be useful, but > ## > +## WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY ## > +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > ## > +## for more details. > ## > +## > ## > +## You should have received a copy of the GNU General Public License > ## > +## along with this program; if not, write to the Free Software > ## > +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > ## > +## > ## > +################################################################################ > +# > +# File : ima_measurements.sh > +# > +# Description: This file verifies measurements are added to the measurement > +# list based on policy. > +# > +# Author: Mimi Zohar, [email protected] > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +################################################################################ > +init() > +{ > + export TST_TOTAL=3 > + export TCID="init" > + export TST_COUNT=0 > + > + # check that sha1sum is installed > + which sha1sum &> /dev/null || RC=$? > + if [ $RC -ne 0 ]; then > + tst_brkm TBROK NULL "$TCID: sha1sum not found" > + return $RC > + fi > + > + # verify using default policy > + if [ ! -f $IMA_DIR/policy ]; then > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: not using default policy" > + fi > + return $RC > +} > + > +# Function: test01 > +# Description - Verify reading a file causes a new measurement to > +# be added to the IMA measurement list. > +test01() > +{ > + TCID="test01" > + TST_COUNT=1 > + RC=0 > + > + # Create file test.txt > + cat > $LTPIMA/test.txt <<-EOF || RC=$? > + `date` - this is a test file > + EOF > + if [ $RC -ne 0 ]; then > + tst_brkm TBROK $LTPTMP/imalog.$$\ > + "$TCID: Unable to create test file" > + return $RC > + fi > + > + # Calculating the sha1sum of $LTPTMP/test.txt should add > + # the measurement to the measurement list. > + # (Assumes SHA1 IMA measurements.) > + hash=`cat $LTPIMA/test.txt | sha1sum | sed 's/ -//'` > + > + # Check if the file is measured > + # (i.e. contained in the ascii measurement list.) > + cat /sys/kernel/security/ima/ascii_runtime_measurements > \ > + $LTPIMA/measurements > + sleep 1 > + `grep $hash $LTPIMA/measurements > /dev/null` || RC=$? > + if [ $RC -ne 0 ]; then > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: TPM ascii measurement list does not contain sha1sum" > + return $RC > + else > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: TPM ascii measurement list contains sha1sum" > + fi > + return $RC > +} > + > +# Function: test02 > +# Description - Verify modifying, then reading, a file causes a new > +# measurement to be added to the IMA measurement list. > +test02() > +{ > + TCID="test02" > + TST_COUNT=2 > + RC=0 > + > + # Modify test.txt > + echo `$date` - file modified >> $LTPIMA/test.txt || RC=$? > + > + # Calculating the sha1sum of $LTPTMP/test.txt should add > + # the new measurement to the measurement list > + hash=`cat $LTPIMA/test.txt | sha1sum | sed 's/ -//'` > + > + # Check if the new measurement exists > + cat /sys/kernel/security/ima/ascii_runtime_measurements > \ > + $LTPIMA/measurements > + `grep $hash $LTPIMA/measurements > /dev/null` || RC=$? > + > + if [ $RC -ne 0 ]; then > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: Modified file not measured" > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: iversion not supported; or not mounted with iversion" > + return $RC > + else > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: Modified file measured" > + fi > + return $RC > +} > + > +# Function: test03 > +# Description - Verify files are measured based on policy > +# (Default policy does not measure user files.) > +test03() > +{ > + TCID="test03" > + TST_COUNT=3 > + RC=0 > + > + # create file user-test.txt > + mkdir -m 0700 $LTPIMA/user > + chown 99.99 $LTPIMA/user > + cd $LTPIMA/user > + hash=0 > + > + # As user 99, create and cat the new file > + sudo -u \#99 sh -c "echo `date` - create test.txt > ./test.txt; > + cat ./test.txt > /dev/null" > + > + # Calculating the hash will add the measurement to the measurement > + # list, so only calc the hash value after getting the measurement > + # list. > + cat /sys/kernel/security/ima/ascii_runtime_measurements > \ > + $LTPIMA/measurements > + hash=`cat ./test.txt | sha1sum | sed 's/ -//'` > + cd - >/dev/null > + > + # Check if the file is measured > + grep $hash $LTPIMA/measurements > /dev/null || RC=$? > + if [ $RC -ne 0 ]; then > + RC=0 > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: user file test.txt not measured" > + else > + RC=1 > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: user file test.txt measured" > + fi > + return $RC > +} > + > +# Function: main > +# > +# Description: - Execute all tests, exit with test status. > +# > +# Exit: - zero on success > +# - non-zero on failure. > +# > +RC=0 > +EXIT_VAL=0 > +source `dirname $0`\/ima_setup.sh > +setup || exit $RC > + > +init > +test01 || EXIT_VAL=$RC > +test02 || EXIT_VAL=$RC > +test03 || EXIT_VAL=$RC > +exit $EXIT_VAL > Index: ltp-full-20090228/testcases/kernel/security/Makefile > =================================================================== > --- ltp-full-20090228.orig/testcases/kernel/security/Makefile > +++ ltp-full-20090228/testcases/kernel/security/Makefile > @@ -1,4 +1,4 @@ > -SUBDIRS = mmc_security filecaps > +SUBDIRS = mmc_security filecaps integrity > > all: > @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/Makefile > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/Makefile > @@ -0,0 +1,6 @@ > +all: > +install: > + chmod 755 *.sh; cp *.sh ../../../../../bin/ > + > +clean: > + > Index: ltp-full-20090228/runtest/ima > =================================================================== > --- /dev/null > +++ ltp-full-20090228/runtest/ima > @@ -0,0 +1,5 @@ > +#DESCRIPTION:Integrity Measurement Architecture (IMA) > +ima01 ima_measurements.sh > +ima02 ima_policy.sh > +ima03 ima_tpm.sh > +ima04 ima_violations.sh > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_boot_aggregate.c > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_boot_aggregate.c > @@ -0,0 +1,110 @@ > +/* > +* Copyright (c) International Business Machines Corp., 2009 > +* > +* Authors: > +* Mimi Zohar <[email protected]> > +* > +* 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_boot_aggregate.c > +* > +* Calculate a SHA1 boot aggregate value based on the TPM > +* binary_bios_measurements. > +* > +* Requires openssl; compile with -lcrypto option > +*/ > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <string.h> > +#include <unistd.h> > +#include <openssl/sha.h> > + > +#define MAX_EVENT_SIZE 500 > +#define EVENT_HEADER_SIZE 32 > +#define MAX_EVENT_DATA_SIZE (MAX_EVENT_SIZE - EVENT_HEADER_SIZE) > +#define NUM_PCRS 8 /* PCR registers 0-7 in boot aggregate */ > + > +static void *display_sha1_digest(char *pcr) > +{ > + int i; > + > + for (i = 0; i < 20; i++) > + printf("%02x", *(pcr + i) & 0xff); > + printf("\n"); > +} > + > +int main(int argc, char *argv[]) > +{ > + unsigned char boot_aggregate[SHA_DIGEST_LENGTH]; > + struct { > + struct { > + u_int32_t pcr; > + int type; > + unsigned char digest[SHA_DIGEST_LENGTH]; > + u_int16_t len; > + } header; > + unsigned char data[MAX_EVENT_DATA_SIZE]; > + } event; > + struct { > + unsigned char digest[SHA_DIGEST_LENGTH]; > + } pcr[NUM_PCRS]; > + FILE *fp; > + int i; > + int debug = 0; > + SHA_CTX c; > + > + if (argc != 2) { > + printf("format: %s binary_bios_measurement file\n", argv[0]); > + return 1; > + } > + fp = fopen(argv[1], "r"); > + if (!fp) { > + perror("unable to open pcr file\n"); > + return 1; > + } > + > + /* Initialize psuedo PCR registers 0 - 7 */ > + for ( i = 0; i < NUM_PCRS; i++) > + memset(&pcr[i].digest, 0, SHA_DIGEST_LENGTH); > + > + /* Extend the pseudo PCRs with the event digest */ > + while (fread(&event, sizeof event.header, 1, fp)) { > + if (debug) { > + printf("%03u ", event.header.pcr); > + display_sha1_digest(event.header.digest); > + } > + SHA1_Init(&c); > + SHA1_Update(&c, pcr[event.header.pcr].digest, 20); > + SHA1_Update(&c, event.header.digest, 20); > + SHA1_Final(pcr[event.header.pcr].digest, &c); > + if (event.header.len > MAX_EVENT_DATA_SIZE) { > + printf("Error event too long"); > + break; > + } > + fread(event.data, event.header.len, 1, fp); > + } > + fclose(fp); > + > + /* Extend the boot aggregate with the pseudo PCR digest values */ > + memset(&boot_aggregate, 0, SHA_DIGEST_LENGTH); > + SHA1_Init(&c); > + for (i = 0; i < NUM_PCRS; i++) { > + if (debug) { > + printf("PCR-%2.2x: ", i); > + display_sha1_digest(pcr[i].digest); > + } > + SHA1_Update(&c, pcr[i].digest, 20); > + } > + SHA1_Final(boot_aggregate, &c); > + > + printf("boot_aggregate:"); > + display_sha1_digest(boot_aggregate); > + > + return 0; > +} > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_measure.c > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_measure.c > @@ -0,0 +1,202 @@ > +/* > + * Copyright (c) International Business Machines Corp., 2008 > + * > + * Authors: > + * Reiner Sailer <[email protected]> > + * Mimi Zohar <[email protected]> > + * > + * 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_measure.c > + * > + * Calculate the SHA1 aggregate-pcr value based on the IMA runtime > + * binary measurements. > + */ > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <string.h> > +#include <unistd.h> > +#include <openssl/sha.h> > + > +#define TCG_EVENT_NAME_LEN_MAX 255 > + > +static int verbose = 0; > +static int validate = 0; > +static int verify = 0; > + > +#define print_info(format, arg...) \ > + if (verbose) \ > + printf(format, ##arg) > + > +static u_int8_t zero[SHA_DIGEST_LENGTH]; > +static u_int8_t fox[SHA_DIGEST_LENGTH]; > + > +struct event { > + struct { > + u_int32_t pcr; > + u_int8_t digest[SHA_DIGEST_LENGTH]; > + u_int32_t name_len; > + } header; > + char name[TCG_EVENT_NAME_LEN_MAX + 1]; > + struct { > + u_int8_t digest[SHA_DIGEST_LENGTH]; > + char filename[TCG_EVENT_NAME_LEN_MAX + 1]; > + } ima_data; > + int filename_len; > +}; > + > +static void display_sha1_digest(u_int8_t *digest) > +{ > + int i; > + > + for (i = 0; i < 20; i++) > + print_info("%02x", (*(digest + i) & 0xff)); > +} > + > +/* > + * Calculate the sha1 hash of data > + */ > +static void calc_digest(u_int8_t *digest, int len, void *data ) > +{ > + SHA_CTX c; > + > + /* Calc template hash for an ima entry */ > + memset(digest, 0, sizeof *digest); > + SHA1_Init(&c); > + SHA1_Update(&c, data, len); > + SHA1_Final(digest, &c); > +} > + > +static int verify_template_hash(struct event *template) > +{ > + int rc; > + > + rc = memcmp(fox, template->header.digest, sizeof fox); > + if (rc != 0) { > + u_int8_t digest[SHA_DIGEST_LENGTH]; > + > + memset(digest, 0, sizeof digest); > + calc_digest(digest, sizeof template->ima_data, > + &template->ima_data); > + rc = memcmp(digest, template->header.digest, sizeof digest); > + return rc != 0 ? 1 : 0; > + } > + return 0; > +} > + > +/* > + * ima_measurements.c - calculate the SHA1 aggregate-pcr value based > + * on the IMA runtime binary measurements. > + * > + * format: ima_measurement [--validate] [--verify] [--verbose] > + * > + * --validate: forces validation of the aggregrate pcr value > + * for an invalidated PCR. Replace all entries in the > + * runtime binary measurement list with 0x00 hash values, > + * which indicate the PCR was invalidated, either for > + * "a time of measure, time of use"(ToMToU) error, or a > + * file open for read was already open for write, with > + * 0xFF's hash value, when calculating the aggregate > + * pcr value. > + * > + * --verify: for all IMA template entries in the runtime binary > + * measurement list, calculate the template hash value > + * and compare it with the actual template hash value. > + * Return the number of incorrect hash measurements. > + * > + * --verbose: For all entries in the runtime binary measurement > + * list, display the template information. > + * > + * template info: list #, PCR-register #, template hash, template name > + * IMA info: IMA hash, filename hint > + * > + * Ouput: displays the aggregate-pcr value > + * Return code: if verification enabled, returns number of verification > + * errors. > + */ > +int main(int argc, char *argv[]) > +{ > + FILE *fp; > + struct event template; > + u_int8_t pcr[SHA_DIGEST_LENGTH]; > + int i, count = 0, len; > + int failed_count = 0; /* number of template verifications failed */ > + > + if (argc < 2) { > + printf("format: %s binary_runtime_measurements" \ > + " [--validate] [--verbose] [--verify]\n", argv[0]); > + return 1; > + } > + > + for (i = 2; i < argc; i++) { > + if (strncmp(argv[i], "--validate", 8) == 0) > + validate = 1; > + if (strncmp(argv[i], "--verbose", 7) == 0) > + verbose = 1; > + if (strncmp(argv[i], "--verify", 6) == 0) > + verify = 1; > + } > + > + fp = fopen(argv[1], "r"); > + if (!fp) { > + perror("Unable to open file\n"); > + return 1; > + } > + memset(pcr, 0, SHA_DIGEST_LENGTH); /* initial PCR content 0..0 */ > + memset(zero, 0, SHA_DIGEST_LENGTH); > + memset(fox, 0xff, SHA_DIGEST_LENGTH); > + > + print_info( "### PCR HASH " \ > + "TEMPLATE-NAME\n"); > + while (fread(&template.header, sizeof template.header, 1, fp)) { > + SHA_CTX c; > + > + /* Extend simulated PCR with new template digest */ > + SHA1_Init(&c); > + SHA1_Update(&c, pcr, SHA_DIGEST_LENGTH); > + if (validate) { > + if (memcmp(template.header.digest, zero, 20) == 0) > + memset(template.header.digest, 0xFF, 20); > + } > + SHA1_Update(&c, template.header.digest, 20); > + SHA1_Final(pcr, &c); > + > + > + print_info("%3d %03u ", count++, template.header.pcr); > + display_sha1_digest(template.header.digest); > + if (template.header.name_len > TCG_EVENT_NAME_LEN_MAX) { > + printf("%d ERROR: event name too long!\n", > + template.header.name_len); > + exit(1); > + } > + memset(template.name, 0, sizeof template.name); > + fread(template.name, template.header.name_len, 1, fp); > + print_info(" %s ", template.name); > + > + memset(&template.ima_data, 0, sizeof template.ima_data); > + fread(&template.ima_data.digest, > + sizeof template.ima_data.digest, 1, fp); > + display_sha1_digest(template.ima_data.digest); > + > + fread(&template.filename_len, > + sizeof template.filename_len, 1, fp); > + fread(template.ima_data.filename, template.filename_len, 1, fp); > + print_info(" %s\n", template.ima_data.filename); > + > + if (verify) > + failed_count += verify_template_hash(&template); > + } > + fclose(fp); > + > + verbose=1; > + print_info("PCRAggr (re-calculated):"); > + display_sha1_digest(pcr); > + printf("\nreturn failed_count: %d\n", failed_count); > + return failed_count; > +} > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_mmap.c > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/src/ima_mmap.c > @@ -0,0 +1,52 @@ > +/* > + * Copyright (c) International Business Machines Corp., 2009 > + * > + * Authors: > + * Mimi Zohar <[email protected]> > + * > + * 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_mmap.c > + * > + * Open and mmap a file and sleep. Another process will open the > + * mmapped file in read mode, resulting in a open_writer violation. > + */ > +#include <stdio.h> > +#include <stdio.h> > +#include <string.h> > +#include <sys/stat.h> > +#include <sys/mman.h> > +#include <fcntl.h> > + > +int main(int argc, char *argv[]) > +{ > + int fd; > + void *file; > + char *filename; > + int rc; > + > + if (argc != 2) > + printf("%s: filename\n", argv[1]); > + filename = argv[1]; > + > + fd = open(filename, O_CREAT | O_RDWR, S_IRWXU); > + if (fd < 0) { > + perror("open"); > + return(-1); > + } > + > + file = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); > + if (file == (void *) -1) { > + perror("mmap"); > + return(-1); > + } > + close(fd); > + sleep(30); > + if (munmap(file, 1024) < 0) { > + perror("unmap"); > + return(-1); > + } > +} > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_policy.sh > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_policy.sh > @@ -0,0 +1,174 @@ > +#!/bin/sh > +################################################################################ > +## > ## > +## Copyright (C) 2009 IBM Corporation > ## > +## > ## > +## 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; either version 2 of the License, or > ## > +## (at your option) any later version. > ## > +## > ## > +## This program is distributed in the hope that it will be useful, but > ## > +## WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY ## > +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > ## > +## for more details. > ## > +## > ## > +## You should have received a copy of the GNU General Public License > ## > +## along with this program; if not, write to the Free Software > ## > +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > ## > +## > ## > +################################################################################ > +# > +# File : ima_policy.sh > +# > +# Description: This file tests replacing the default integrity measurement > +# policy. > +# > +# Author: Mimi Zohar, [email protected] > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +################################################################################ > +init() > +{ > + export TST_TOTAL=3 > + export TCID="init" > + export TST_COUNT=0 > + RC=0 > + > + # verify using default policy > + IMA_POLICY=$IMA_DIR/policy > + if [ ! -f $IMA_POLICY ]; then > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: default policy already replaced" > + RC=1 > + fi > + > + VALID_POLICY=`dirname $0`\/..\/policy/measure.policy > + if [ ! -f $VALID_POLICY ]; then > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: missing $VALID_POLICY" > + RC=1 > + fi > + > + INVALID_POLICY=`dirname $0`\/..\/policy/measure.policy-invalid > + if [ ! -f $INVALID_POLICY ]; then > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: missing $INVALID_POLICY" > + RC=1 > + fi > + return $RC > +} > + > +load_policy() > +{ > + exec 2>/dev/null 4>$IMA_POLICY > + if [ $? -ne 0 ]; then > + exit 1 > + fi > + > + cat $1 | > + while read line ; do > + { > + if [ "${line:0:1}" != "#" ] ; then > + echo $line >&4 2> /dev/null > + if [ $? -ne 0 ]; then > + exec 4>&- > + RC=1 > + return $RC > + fi > + fi > + } > + done > +} > + > + > +# Function: test01 > +# Description - Verify invalid policy doesn't replace default policy. > +test01() > +{ > + TCID="test01" > + TST_COUNT=1 > + RC=0 > + > + load_policy $INVALID_POLICY & p1=$! > + wait "$p1"; RC=$? > + if [ $RC -ne 0 ]; then > + RC=0 > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: didn't load invalid policy" > + else > + RC=1 > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: loaded invalid policy" > + fi > + return $RC > +} > + > +# Function: test02 > +# Description - Verify policy file is opened sequentially, not > concurrently > +# and install new policy > +test02() > +{ > + TCID="test02" > + TST_COUNT=2 > + RC=0 > + > + load_policy $VALID_POLICY & p1=$! # forked process 1 > + load_policy $VALID_POLICY & p2=$! # forked process 2 > + wait "$p1"; RC1=$? > + wait "$p2"; RC2=$? > + RC=$((`expr $RC1 + $RC2`)) > + if [ $RC -eq 1 ]; then > + RC=0 > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: replaced default measurement policy" > + elif [ $RC -eq 0 ]; then > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: measurement policy opened concurrently" > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: problems opening measurement policy" > + fi > + return 0 > +} > + > +# Function: test03 > +# Description - Verify can't load another measurement policy. > +test03() > +{ > + TCID="test03" > + TST_COUNT=3 > + RC=0 > + > + load_policy $INVALID_POLICY & p1=$! > + wait "$p1"; RC=$? > + if [ $RC -ne 0 ]; then > + RC=0 > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: didn't replace valid policy" > + else > + RC=1 > + tst_res TFAIL $LTPTMP/imalog.$$ "$TCID: replaced valid policy" > + fi > + return $RC > +} > + > +# Function: main > +# > +# Description: - Execute all tests, exit with test status. > +# > +# Exit: - zero on success > +# - non-zero on failure. > +# > +RC=0 # Return value from setup, init, and test functions. > +EXIT_VAL=0 > + > +source `dirname $0`\/ima_setup.sh > +setup || exit $RC > + > +init || exit $RC > +test01 || EXIT_VAL=$RC > +test02 || EXIT_VAL=$RC > +test03 || EXIT_VAL=$RC > +exit $EXIT_VAL > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_setup.sh > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_setup.sh > @@ -0,0 +1,138 @@ > +#!/bin/sh > +################################################################################ > +## > ## > +## Copyright (C) 2009 IBM Corporation > ## > +## > ## > +## 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; either version 2 of the License, or > ## > +## (at your option) any later version. > ## > +## > ## > +## This program is distributed in the hope that it will be useful, but > ## > +## WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY ## > +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > ## > +## for more details. > ## > +## > ## > +## You should have received a copy of the GNU General Public License > ## > +## along with this program; if not, write to the Free Software > ## > +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > ## > +## > ## > +################################################################################ > +# > +# File : ima_setup.sh > +# > +# Description: setup/cleanup routines for the integrity tests. > +# > +# Author: Mimi Zohar, [email protected] > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +################################################################################ > +mount_sysfs() > +{ > + SYSFS=`mount | grep sysfs` || RC=$? > + if [ $RC -eq 1 ]; then > + SYSFS=/sys > + mkdir -p $SYSFS > + `mount -t sysfs sysfs $SYSFS` > + RC=$? > + return $RC > + else > + SYSFS=`echo $SYSFS | sed 's/sysfs on //' | sed 's/ type .*//'` > + fi > + return 0 > +} > + > +mount_securityfs() > +{ > + SECURITYFS=`mount | grep securityfs` || RC=$? > + if [ $RC == 1 ]; then > + SECURITYFS=$SYSFS/kernel/security > + `mkdir -p $SECURITYFS` > + `mount -t securityfs securityfs $SECURITYFS` > + RC=$? > + return $RC > + else > + SECURITYFS=`echo $SECURITYFS | sed 's/securityfs on //' \ > + | sed 's/ type .*//'` > + fi > + return 0 > +} > + > +setup() > +{ > + export TST_TOTAL=1 > + export TCID="setup" > + export TST_COUNT=0 > + > + trap "cleanup" 0 > + if [ -z $TMP ]; then > + LTPTMP=/tmp > + else > + LTPTMP=${TMP} > + fi > + if [ -z $LTPBIN ]; then > + LTPBIN=../../../../../bin > + fi > + > + # Must be root > + if [ $UID -ne 0 ]; then > + tst_brkm TBROK $LTPTMP/imalog.$$ \ > + "$TCID: Must be root to execute test" > + return 1 > + fi > + > + if [ -z $TMP ]; then > + LTPTMP=/tmp > + else > + LTPTMP=${TMP} > + fi > + > + # create the temporary directory used by this testcase > + LTPIMA=$LTPTMP/ima > + umask 077 > + mkdir $LTPIMA &>/dev/null || RC=$? > + if [ $RC -ne 0 ]; then > + tst_brk TBROK "$TCID: Unable to create temporary directory" > + return $RC > + fi > + > + # mount sysfs if it is not already mounted > + mount_sysfs || RC=$? > + if [ $RC -ne 0 ]; then > + tst_brkm TBROK $LTPTMP/imalog.$$ "$TCID: cannot mount sysfs" > + return $RC > + fi > + > + # mount securityfs if it is not already mounted > + mount_securityfs || RC=$? > + if [ $RC -ne 0 ]; then > + tst_brkm TBROK $LTPTMP/imalog.$$ "$TCID: cannot mount > securityfs" > + return $RC > + fi > + > + SECURITYFS=`echo $SECURITYFS | sed 's/securityfs on //' \ > + | sed 's/ type .*//'` > + > + # IMA must be configured in the kernel > + IMA_DIR=$SECURITYFS/ima > + if [ ! -d $IMA_DIR ]; then > + tst_brkm TBROK $LTPTMP/imalog.$$\ > + "INIT: IMA not enabled in kernel" > + RC=1 > + fi > + return $RC > +} > + > +# Function: cleanup > +# > +# Description - remove temporary files and directories. > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +cleanup() > +{ > + tst_resm TINFO "CLEAN: removing $LTPIMA" > + rm -rf $LTPIMA || RC $? > + return $RC > +} > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_tpm.sh > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_tpm.sh > @@ -0,0 +1,164 @@ > +#!/bin/sh > + > +################################################################################ > +## > ## > +## Copyright (C) 2009 IBM Corporation > ## > +## > ## > +## 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; either version 2 of the License, or > ## > +## (at your option) any later version. > ## > +## > ## > +## This program is distributed in the hope that it will be useful, but > ## > +## WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY ## > +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > ## > +## for more details. > ## > +## > ## > +## You should have received a copy of the GNU General Public License > ## > +## along with this program; if not, write to the Free Software > ## > +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > ## > +## > ## > +################################################################################ > +# > +# File : ima_tpm.sh > +# > +# Description: This file verifies the boot and PCR aggregates > +# > +# Author: Mimi Zohar, [email protected] > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +################################################################################ > +init() > +{ > + export TST_TOTAL=3 > + export TCID="init" > + export TST_COUNT=0 > + RC=0 > +} > + > +# Function: test01 > +# Description - Verify boot aggregate value is correct > +test01() > +{ > + TCID="test01" > + TST_COUNT=1 > + RC=0 > + > + # IMA boot aggregate > + ima_measurements=$SECURITYFS/ima/ascii_runtime_measurements > + read line < $ima_measurements > + > + # verify TPM is available and enabled. > + tpm_bios=$SECURITYFS/tpm0/binary_bios_measurements > + if [ ! -f $tpm_bios ]; then > + tst_res TINFO $LTPTMP/imalog.$$\ > + "$TCID: no TPM, TPM not builtin kernel, or TPM not enabled" > + > + [ "${line:49:40}" -eq 0 ] || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: bios boot aggregate is 0." > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: bios boot aggregate is not 0." > + fi > + else > + boot_aggregate=`ima_boot_aggregate $tpm_bios` > + > + [ "${line:48:40}" == "${boot_aggregate:15:40}" ] || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: bios aggregate matches IMA boot aggregate." > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: bios aggregate does not match IMA boot " \ > + "aggregate." > + fi > + fi > + return $RC > +} > + > +# Probably cleaner to programmatically read the PCR values directly > +# from the TPM, but that would require a TPM library. For now, use > +# the PCR values from /sys/devices. > +validate_pcr() > +{ > + aggregate_pcr=`ima_measure --validate` > + dev_pcrs=$1 > + while read line ; do > + if [ "${line:0:6}" == "PCR-10" ]; then > + [ "${line:8:40}" == "${aggregate_pcr:0:40}" ] > + RC=$? > + fi > + done < $dev_pcrs > + return $RC > +} > + > +# Function: test02 > +# Description - Verify ima calculated aggregate PCR values matches > +# actual PCR value. > +test02() > +{ > + TCID="test02" > + TST_COUNT=2 > + RC=0 > + > +# Would be nice to know where the PCRs are located. Is this safe? > + PCRS_PATH=`find /$SYSFS/devices/ | grep pcrs` || RC=$? > + if [ $RC -eq 0 ]; then > + validate_pcr $PCRS_PATH || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: aggregate PCR value matches real PCR value." > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: aggregate PCR value does not match" \ > + " real PCR value." > + fi > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: TPM not enabled, no PCR value to validate" > + fi > + return $RC > +} > + > +# Function: test03 > +# Description - Verify template hash value for IMA entry is correct. > +test03() > +{ > + TCID="test03" > + TST_COUNT=3 > + RC=0 > + > + aggregate_pcr=`ima_measure --verify --validate` > /dev/null > + RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: verified IMA template hash values." > + else > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: error verifing IMA template hash values." > + fi > + return $RC > +} > + > +# Function: main > +# > +# Description: - Execute all tests, exit with test status. > +# > +# Exit: - zero on success > +# - non-zero on failure. > +# > +RC=0 # Return value from setup, and test functions. > +EXIT_VAL=0 > + > +# set the testcases/bin directory > +source `dirname $0`\/ima_setup.sh > +setup || exit $RC > + > +init || EXIT_VAL=$RC > +test01 || EXIT_VAL=$RC > +test02 || EXIT_VAL=$RC > +test03 || EXIT_VAL=$RC > +exit $EXIT_VAL > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_violations.sh > =================================================================== > --- /dev/null > +++ > ltp-full-20090228/testcases/kernel/security/integrity/ima/tests/ima_violations.sh > @@ -0,0 +1,182 @@ > +#!/bin/sh > +################################################################################ > +## > ## > +## Copyright (C) 2009 IBM Corporation > ## > +## > ## > +## 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; either version 2 of the License, or > ## > +## (at your option) any later version. > ## > +## > ## > +## This program is distributed in the hope that it will be useful, but > ## > +## WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY ## > +## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > ## > +## for more details. > ## > +## > ## > +## You should have received a copy of the GNU General Public License > ## > +## along with this program; if not, write to the Free Software > ## > +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > ## > +## > ## > +################################################################################ > +# > +# File : ima_violations.sh > +# > +# Description: This file tests ToMToU and open_writer violations invalidate > +# the PCR and are logged. > +# > +# Author: Mimi Zohar, [email protected] > +# > +# Return - zero on success > +# - non zero on failure. return value from commands ($RC) > +################################################################################ > + > +open_file_read() > +{ > + exec 3< $1 > + if [ $? -ne 0 ]; then > + exit 1 > + fi > +} > + > +close_file_read() > +{ > + exec 3>&- > +} > + > +open_file_write() > +{ > + exec 4> $1 > + if [ $? -ne 0 ]; then > + exit 1 > + echo 'testing, testing, ' >&4 > + fi > +} > + > +close_file_write() > +{ > + exec 4>&- > +} > + > +init() > +{ > + export TST_TOTAL=3 > + export TCID="init" > + export TST_COUNT=0 > + RC=0 > +} > + > +# Function: test01 > +# Description - Verify ToMToU violation > +test01() > +{ > + TCID="test01" > + TST_COUNT=1 > + RC=0 > + > + ima_violations=$SECURITYFS/ima/violations > + read num_violations < $ima_violations > + > + TMPFN=$LTPIMA/test.txt-$$ > + open_file_write $TMPFN > + open_file_read $TMPFN > + close_file_read > + close_file_write > + read num_violations_new < $ima_violations > + num=$((`expr $num_violations_new - $num_violations`)) > + if [ $num -gt 0 ]; then > + tail /var/log/audit/audit.log | grep test.txt-$$ | \ > + grep 1>/dev/null 'open_writers' || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: open_writers violation added" > + return $RC > + fi > + fi > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: open_writers violation not added" > + return $RC > +} > + > +# Function: test02 > +# Description - Verify open writers violation > +test02() > +{ > + TCID="test02" > + TST_COUNT=2 > + RC=0 > + > + ima_violations=$SECURITYFS/ima/violations > + read num_violations < $ima_violations > + > + TMPFN=$LTPIMA/test.txt-$$ > + open_file_read $TMPFN > + open_file_write $TMPFN > + close_file_write > + close_file_read > + read num_violations_new < $ima_violations > + num=$((`expr $num_violations_new - $num_violations`)) > + if [ $num -gt 0 ]; then > + tail /var/log/audit/audit.log | grep test.txt-$$ | \ > + grep 'ToMToU' 1>/dev/null || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: ToMToU violation added" > + return $RC > + fi > + fi > + tst_res TFAIL $LTPTMP/imalog.$$ "$TCID: ToMToU violation not added" > + return $RC > +} > + > +# Function: test03 > +# Description - verify open_writers using mmapped files > +test03() > +{ > + TCID="test03" > + TST_COUNT=3 > + RC=0 > + > + ima_violations=$SECURITYFS/ima/violations > + read num_violations < $ima_violations > + > + TMPFN=$LTPIMA/test.txtb-$$ > + mkdir -p $LTPIMA > + echo 'testing testing ' > $TMPFN > + ima_mmap $TMPFN & p1=$! > + sleep 1 # got to wait for ima_mmap to mmap the file > + open_file_read $TMPFN > + read num_violations_new < $ima_violations > + num=$((`expr $num_violations_new - $num_violations`)) > + if [ $num -gt 0 ]; then > + tail /var/log/audit/audit.log | grep test.txtb-$$ | \ > + grep 1>/dev/null 'open_writers' || RC=$? > + if [ $RC -eq 0 ]; then > + tst_res TPASS $LTPTMP/imalog.$$\ > + "$TCID: mmapped open_writers violation added" > + return $RC > + fi > + fi > + tst_res TFAIL $LTPTMP/imalog.$$\ > + "$TCID: mmapped open_writers violation not added" > + close_file_read > + return $RC > +} > + > +# Function: main > +# > +# Description: - Execute all tests, exit with test status. > +# > +# Exit: - zero on success > +# - non-zero on failure. > +# > +RC=0 # Return value from setup, init, and test functions. > +EXIT_VAL=0 > + > +source `dirname $0`\/ima_setup.sh > +setup || exit $RC > + > +init || exit $RC > +test01 || EXIT_VAL=$RC > +test02 || EXIT_VAL=$RC > +test03 || EXIT_VAL=$RC > +exit $EXIT_VAL > Index: > ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/Makefile > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/policy/Makefile > @@ -0,0 +1,6 @@ > +all: > +install: > + mkdir -p ../../../../../policy; cp measure* ../../../../../policy/ > + > +clean: > + > Index: ltp-full-20090228/testcases/kernel/security/integrity/ima/src/Makefile > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/src/Makefile > @@ -0,0 +1,14 @@ > +ifeq ($(shell openssl version > /dev/null 2>&1 || echo yes),yes) > +TARGETS=ima_mmap > +else > +TARGETS=ima_measure ima_boot_aggregate ima_mmap > +LDLIBS += -lcrypto > +endif > + > +all: $(TARGETS) > + > +install: > + @set -e; for i in $(TARGETS); do ln -f $$i ../../../../../bin/$$i; done > + > +clean: > + rm -f $(TARGETS) > Index: ltp-full-20090228/testcases/kernel/security/integrity/ima/Makefile > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/ima/Makefile > @@ -0,0 +1,11 @@ > +SUBDIRS = src tests policy > + > +all: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done > + > +install: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i install ; done > + > +clean: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean ; done > + > Index: ltp-full-20090228/testcases/kernel/security/integrity/Makefile > =================================================================== > --- /dev/null > +++ ltp-full-20090228/testcases/kernel/security/integrity/Makefile > @@ -0,0 +1,11 @@ > +SUBDIRS = ima > + > +all: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done > + > +install: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i install ; done > + > +clean: > + @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i clean ; done > + > > ------------------------------------------------------------------------------ Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
