This patch adds testcases for the Integrity Measurement Architecture(IMA). Signed-off-by: Mimi Zohar <[email protected]>
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
