diff mbox series

[3/3] ima: Add overlay test

Message ID 20190327161638.7407-4-pvorel@suse.cz (mailing list archive)
State New, archived
Headers show
Series LTP reproducer on broken IMA on overlayfs | expand

Commit Message

Petr Vorel March 27, 2019, 4:16 p.m. UTC
Based on reproducer made by Ignaz Forster <iforster@suse.de>
used for his not upstreamed patchset [1] and previous report [2].

NOTE: backup variables are needed because ima_setup.sh calling
tst_mount as well when TMPDIR is on tmpfs device.

[1] https://www.spinics.net/lists/linux-integrity/msg05926.html
[2] https://www.spinics.net/lists/linux-integrity/msg03593.html

Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
Cc: Ignaz Forster <iforster@suse.de>
Cc: Fabian Vogt <FVogt@suse.com>
Cc: Weihua Du <WHDu@suse.com>
Cc: linux-integrity@vger.kernel.org
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 runtest/ima                                   |  1 +
 .../integrity/ima/tests/ima_overlay.sh        | 65 +++++++++++++++++++
 .../security/integrity/ima/tests/ima_setup.sh |  4 +-
 3 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100755 testcases/kernel/security/integrity/ima/tests/ima_overlay.sh

Comments

Ignaz Forster March 28, 2019, 5:27 p.m. UTC | #1
Hi Petr,

thanks a lot for the LTP integration!

Am 27.03.19 um 17:16 Uhr schrieb Petr Vorel:
> Based on reproducer made by Ignaz Forster <iforster@suse.de>
> used for his not upstreamed patchset [1] and previous report [2].

Just for clarification, as the test is only referring to IMA: With IMA 
everything should be working already, the problem during copy_up 
operations was fixed by Mimi and Goldwyn in 
https://patchwork.kernel.org/patch/10776231/.
As expected the test passes on my IMA-only setup.

My outstanding patchset is only necessary when combining IMA with EVM - 
in this case the test will still fail. I hope I'll be able to resume my 
work in the next few weeks.

The test itself is looking good and working as expected.

> NOTE: backup variables are needed because ima_setup.sh calling
> tst_mount as well when TMPDIR is on tmpfs device.
> 
> [1] https://www.spinics.net/lists/linux-integrity/msg05926.html
> [2] https://www.spinics.net/lists/linux-integrity/msg03593.html
> 
> Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
> Cc: Ignaz Forster <iforster@suse.de>
> Cc: Fabian Vogt <FVogt@suse.com>
> Cc: Weihua Du <WHDu@suse.com>
> Cc: linux-integrity@vger.kernel.org
> Signed-off-by: Petr Vorel <pvorel@suse.cz>

Tested-by: Ignaz Forster <iforster@suse.de>

> ---
>   runtest/ima                                   |  1 +
>   .../integrity/ima/tests/ima_overlay.sh        | 65 +++++++++++++++++++
>   .../security/integrity/ima/tests/ima_setup.sh |  4 +-
>   3 files changed, 68 insertions(+), 2 deletions(-)
>   create mode 100755 testcases/kernel/security/integrity/ima/tests/ima_overlay.sh
> 
> diff --git a/runtest/ima b/runtest/ima
> index bcae16bb7..f96711a7d 100644
> --- a/runtest/ima
> +++ b/runtest/ima
> @@ -3,3 +3,4 @@ ima_measurements ima_measurements.sh
>   ima_policy ima_policy.sh
>   ima_tpm ima_tpm.sh
>   ima_violations ima_violations.sh
> +ima_overlay ima_overlay.sh
> diff --git a/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh b/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh
> new file mode 100755
> index 000000000..eedcd3753
> --- /dev/null
> +++ b/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh
> @@ -0,0 +1,65 @@
> +#!/bin/sh
> +# Copyright (c) 2019 Petr Vorel <pvorel@suse.cz>
> +# Based on reproducer made by Ignaz Forster <iforster@suse.de>
> +
> +TST_SETUP="setup"
> +TST_CLEANUP="cleanup"
> +. ima_setup.sh
> +TST_TESTFUNC="do_test"
> +
> +setup()
> +{
> +	lower="$TST_MNTPOINT/lower"
> +	upper="$TST_MNTPOINT/upper"
> +	work="$TST_MNTPOINT/work"
> +	merged="$TST_MNTPOINT/merged"
> +	mkdir -p $lower $upper $work $merged
> +
> +	device_backup="$TST_DEVICE"
> +	TST_DEVICE="overlay"
> +
> +	fs_type_backup="$TST_FS_TYPE"
> +	TST_FS_TYPE="overlay"
> +
> +	mntpoint_backup="$TST_MNTPOINT"
> +	TST_MNTPOINT="$merged"
> +
> +	params_backup="$TST_MNT_PARAMS"
> +	TST_MNT_PARAMS="-o lowerdir=$lower,upperdir=$upper,workdir=$work"
> +
> +	grep -q ima_appraise_tcb /proc/cmdline || \
> +		tst_brk TCONF "Test requires ima_appraise_tcb kernel parameter"
> +}
> +
> +do_test()
> +{
> +	local file="foo.txt"
> +	local f
> +
> +	tst_mount
> +	mounted=1
> +
> +	ROD echo lower \> $lower/$file
> +	if ! echo overlay > $merged/$file 2>/dev/null; then
> +		tst_res TFAIL "Cannot write to merged layer"
> +		return
> +	fi

I can think of two additional tests here:
1. Appending to a file (>> instead of >)
2. Creating a new file in the overlay

These cases are using different code paths and may fail independently, 
so separate tests would be handy.

Ignaz

> +	for f in $(find $TST_MNTPOINT -type f); do
> +		EXPECT_PASS cat $f \> /dev/null 2\> /dev/null
> +	done
> +}
> +
> +cleanup()
> +{
> +	[ -n "$mounted" ] || return 0
> +
> +	tst_umount $TST_DEVICE
> +
> +	TST_DEVICE="$device_backup"
> +	TST_FS_TYPE="$fs_type_backup"
> +	TST_MNTPOINT="$mntpoint_backup"
> +	TST_MNT_PARAMS="$params_backup"
> +}
> +
> +tst_run
> diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
> index da49eb1b2..08aa5300a 100644
> --- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
> +++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
> @@ -64,14 +64,14 @@ print_ima_config()
>   	local config="/boot/config-$(uname -r)"
>   	local i
>   
> -	tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
> -
>   	if [ -r "$config" ]; then
>   		tst_res TINFO "IMA kernel config:"
>   		for i in $(grep ^CONFIG_IMA $config); do
>   			tst_res TINFO "$i"
>   		done
>   	fi
> +
> +	tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
>   }
>   
>   ima_setup()
>
Mimi Zohar March 29, 2019, 10:49 a.m. UTC | #2
Hi Petr,

On Wed, 2019-03-27 at 17:16 +0100, Petr Vorel wrote:

> +setup()
> +{
> +	lower="$TST_MNTPOINT/lower"
> +	upper="$TST_MNTPOINT/upper"
> +	work="$TST_MNTPOINT/work"
> +	merged="$TST_MNTPOINT/merged"
> +	mkdir -p $lower $upper $work $merged
> +
> +	device_backup="$TST_DEVICE"
> +	TST_DEVICE="overlay"
> +
> +	fs_type_backup="$TST_FS_TYPE"
> +	TST_FS_TYPE="overlay"
> +
> +	mntpoint_backup="$TST_MNTPOINT"
> +	TST_MNTPOINT="$merged"
> +
> +	params_backup="$TST_MNT_PARAMS"
> +	TST_MNT_PARAMS="-o lowerdir=$lower,upperdir=$upper,workdir=$work"
> +
> +	grep -q ima_appraise_tcb /proc/cmdline || \
> +		tst_brk TCONF "Test requires ima_appraise_tcb kernel parameter"

Instead of specifying individual policies separately, the newer method
of specifying builtin IMA policies on the boot command line is
"ima_policy=", with a list of policies.  The builtin appraise policy
would be specified as "ima_policy=appraise_tcb".  Refer to
Documentation/admin-guide/kernel-parameters.txt for the list of
builtin policies.

> +}
> +
> +do_test()
> +{
> +	local file="foo.txt"
> +	local f
> +
> +	tst_mount
> +	mounted=1
> +
> +	ROD echo lower \> $lower/$file

For some reason "mntpoint/lower" isn't loopback mounted.  With the
builtin appraise policy, because it is a tmpfs filesystem,
security.ima does not exist.  Writing to the merged directory then
fails.

+ df -T mntpoint/lower
Filesystem     Type  1K-blocks   Used Available Use% Mounted on
tmpfs          tmpfs   4020348 262316   3758032   7% /tmp


+ getfattr -m '^security' --dump mntpoint/lower/foo.txt
# file: mntpoint/lower/foo.txt
security.evm=0sAq8niNi4X7cYntKSAki1Woc+Y5Yq
security.selinux="unconfined_u:object_r:user_tmp_t:s0"

Mimi

> +	if ! echo overlay > $merged/$file 2>/dev/null; then
> +		tst_res TFAIL "Cannot write to merged layer"
> +		return
> +	fi
> +
> +	for f in $(find $TST_MNTPOINT -type f); do
> +		EXPECT_PASS cat $f \> /dev/null 2\> /dev/null
> +	done
> +}
Petr Vorel April 4, 2019, 6:19 p.m. UTC | #3
Hi Mimi,

thanks for your comments!

> > +	grep -q ima_appraise_tcb /proc/cmdline || \
> > +		tst_brk TCONF "Test requires ima_appraise_tcb kernel parameter"

> Instead of specifying individual policies separately, the newer method
> of specifying builtin IMA policies on the boot command line is
> "ima_policy=", with a list of policies.  The builtin appraise policy
> would be specified as "ima_policy=appraise_tcb".  Refer to
> Documentation/admin-guide/kernel-parameters.txt for the list of
> builtin policies.
I guess grep for any policy (ima_policy=) or ima_appraise_tcb shold e enough.
Am I right?

BTW I guess ima_appraise_tcb should be deprecated in kernel-parameters.txt.

> > +}
> > +
> > +do_test()
> > +{
> > +	local file="foo.txt"
> > +	local f
> > +
> > +	tst_mount
> > +	mounted=1
> > +
> > +	ROD echo lower \> $lower/$file

> For some reason "mntpoint/lower" isn't loopback mounted.  With the
> builtin appraise policy, because it is a tmpfs filesystem,
> security.ima does not exist.  Writing to the merged directory then
> fails.

> + df -T mntpoint/lower
> Filesystem     Type  1K-blocks   Used Available Use% Mounted on
> tmpfs          tmpfs   4020348 262316   3758032   7% /tmp
My bad, I forged to add TST_NEEDS_DEVICE=1 to ima_overlay.sh (I'll add it into
v2). That was the missing piece to enable loop device (in the end of ima_setup.sh)


> + getfattr -m '^security' --dump mntpoint/lower/foo.txt
> # file: mntpoint/lower/foo.txt
> security.evm=0sAq8niNi4X7cYntKSAki1Woc+Y5Yq
> security.selinux="unconfined_u:object_r:user_tmp_t:s0"

> Mimi


Kind regards,
Petr
Mimi Zohar April 4, 2019, 7:19 p.m. UTC | #4
On Thu, 2019-04-04 at 20:19 +0200, Petr Vorel wrote:
> Hi Mimi,
> 
> thanks for your comments!
> 
> > > +	grep -q ima_appraise_tcb /proc/cmdline || \
> > > +		tst_brk TCONF "Test requires ima_appraise_tcb kernel parameter"
> 
> > Instead of specifying individual policies separately, the newer method
> > of specifying builtin IMA policies on the boot command line is
> > "ima_policy=", with a list of policies.  The builtin appraise policy
> > would be specified as "ima_policy=appraise_tcb".  Refer to
> > Documentation/admin-guide/kernel-parameters.txt for the list of
> > builtin policies.
> I guess grep for any policy (ima_policy=) or ima_appraise_tcb shold e enough.
> Am I right?

Yes

> 
> BTW I guess ima_appraise_tcb should be deprecated in kernel-parameters.txt.

and yes

> 
> > > +}
> > > +
> > > +do_test()
> > > +{
> > > +	local file="foo.txt"
> > > +	local f
> > > +
> > > +	tst_mount
> > > +	mounted=1
> > > +
> > > +	ROD echo lower \> $lower/$file
> 
> > For some reason "mntpoint/lower" isn't loopback mounted.  With the
> > builtin appraise policy, because it is a tmpfs filesystem,
> > security.ima does not exist.  Writing to the merged directory then
> > fails.
> 
> > + df -T mntpoint/lower
> > Filesystem     Type  1K-blocks   Used Available Use% Mounted on
> > tmpfs          tmpfs   4020348 262316   3758032   7% /tmp
> My bad, I forged to add TST_NEEDS_DEVICE=1 to ima_overlay.sh (I'll add it into
> v2). That was the missing piece to enable loop device (in the end of ima_setup.sh)

thanks!
> 
> 
> > + getfattr -m '^security' --dump mntpoint/lower/foo.txt
> > # file: mntpoint/lower/foo.txt
> > security.evm=0sAq8niNi4X7cYntKSAki1Woc+Y5Yq
> > security.selinux="unconfined_u:object_r:user_tmp_t:s0"
> 
> 
> Kind regards,
> Petr
>
Petr Vorel April 4, 2019, 10:37 p.m. UTC | #5
Hi Ignaz,

> thanks a lot for the LTP integration!
thanks for testing and your comments!

> Am 27.03.19 um 17:16 Uhr schrieb Petr Vorel:
> > Based on reproducer made by Ignaz Forster <iforster@suse.de>
> > used for his not upstreamed patchset [1] and previous report [2].

> Just for clarification, as the test is only referring to IMA: With IMA
> everything should be working already, the problem during copy_up operations
> was fixed by Mimi and Goldwyn in
> https://patchwork.kernel.org/patch/10776231/.
> As expected the test passes on my IMA-only setup.

> My outstanding patchset is only necessary when combining IMA with EVM - in
> this case the test will still fail. I hope I'll be able to resume my work in
> the next few weeks.
I'll rename it to evm_overlay.sh.
BTW I got (with TST_NEEDS_DEVICE=1 in ima_overlay.sh) failure with ima_appraise_tcb kernel parameter:
[  741.070585] audit: type=1800 audit(1554415774.087:46): pid=1491 uid=0 auid=0 ses=3 op="appraise_data" cause="invalid-hash" comm="ima_overlay.sh" name="/tmp/LTP_ima_overlay.eZxnT8LMZ7/mntpoint/merged/foo.txt" dev="vda2" ino=3496 res=0

which looked to me as good error.
I didn't get any ima error with ima_policy=appraise_tcb, which is supposed to be
according to docs the same (and setup code in ima_policy.c looks to me like it:
both just set ima_use_appraise_tcb). I wonder, what is wrong in my setup.

BTW can you share your setup? ima_policy=appraise_tcb kernel parameter and
loading IMA and EVM keys over dracut-ima scripts? (IMA appraisal and EVM using
digital signatures? I guess using hashes for IMA appraisal would work as well)

> > +do_test()
> > +{
> > +	local file="foo.txt"
> > +	local f
> > +
> > +	tst_mount
> > +	mounted=1
> > +
> > +	ROD echo lower \> $lower/$file
> > +	if ! echo overlay > $merged/$file 2>/dev/null; then
> > +		tst_res TFAIL "Cannot write to merged layer"
> > +		return
> > +	fi

> I can think of two additional tests here:
> 1. Appending to a file (>> instead of >)
> 2. Creating a new file in the overlay

> These cases are using different code paths and may fail independently, so
> separate tests would be handy.

I'll add them into v2.

> Ignaz

Kind regards,
Petr
diff mbox series

Patch

diff --git a/runtest/ima b/runtest/ima
index bcae16bb7..f96711a7d 100644
--- a/runtest/ima
+++ b/runtest/ima
@@ -3,3 +3,4 @@  ima_measurements ima_measurements.sh
 ima_policy ima_policy.sh
 ima_tpm ima_tpm.sh
 ima_violations ima_violations.sh
+ima_overlay ima_overlay.sh
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh b/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh
new file mode 100755
index 000000000..eedcd3753
--- /dev/null
+++ b/testcases/kernel/security/integrity/ima/tests/ima_overlay.sh
@@ -0,0 +1,65 @@ 
+#!/bin/sh
+# Copyright (c) 2019 Petr Vorel <pvorel@suse.cz>
+# Based on reproducer made by Ignaz Forster <iforster@suse.de>
+
+TST_SETUP="setup"
+TST_CLEANUP="cleanup"
+. ima_setup.sh
+TST_TESTFUNC="do_test"
+
+setup()
+{
+	lower="$TST_MNTPOINT/lower"
+	upper="$TST_MNTPOINT/upper"
+	work="$TST_MNTPOINT/work"
+	merged="$TST_MNTPOINT/merged"
+	mkdir -p $lower $upper $work $merged
+
+	device_backup="$TST_DEVICE"
+	TST_DEVICE="overlay"
+
+	fs_type_backup="$TST_FS_TYPE"
+	TST_FS_TYPE="overlay"
+
+	mntpoint_backup="$TST_MNTPOINT"
+	TST_MNTPOINT="$merged"
+
+	params_backup="$TST_MNT_PARAMS"
+	TST_MNT_PARAMS="-o lowerdir=$lower,upperdir=$upper,workdir=$work"
+
+	grep -q ima_appraise_tcb /proc/cmdline || \
+		tst_brk TCONF "Test requires ima_appraise_tcb kernel parameter"
+}
+
+do_test()
+{
+	local file="foo.txt"
+	local f
+
+	tst_mount
+	mounted=1
+
+	ROD echo lower \> $lower/$file
+	if ! echo overlay > $merged/$file 2>/dev/null; then
+		tst_res TFAIL "Cannot write to merged layer"
+		return
+	fi
+
+	for f in $(find $TST_MNTPOINT -type f); do
+		EXPECT_PASS cat $f \> /dev/null 2\> /dev/null
+	done
+}
+
+cleanup()
+{
+	[ -n "$mounted" ] || return 0
+
+	tst_umount $TST_DEVICE
+
+	TST_DEVICE="$device_backup"
+	TST_FS_TYPE="$fs_type_backup"
+	TST_MNTPOINT="$mntpoint_backup"
+	TST_MNT_PARAMS="$params_backup"
+}
+
+tst_run
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
index da49eb1b2..08aa5300a 100644
--- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
@@ -64,14 +64,14 @@  print_ima_config()
 	local config="/boot/config-$(uname -r)"
 	local i
 
-	tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
-
 	if [ -r "$config" ]; then
 		tst_res TINFO "IMA kernel config:"
 		for i in $(grep ^CONFIG_IMA $config); do
 			tst_res TINFO "$i"
 		done
 	fi
+
+	tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
 }
 
 ima_setup()