All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] Introduce partial kernel_read_file() support
@ 2020-07-22 19:30 Kees Cook
  2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
                   ` (17 more replies)
  0 siblings, 18 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

v2:
- fix issues in firmware test suite
- add firmware partial read patches
- various bug fixes/cleanups
v1: https://lore.kernel.org/lkml/20200717174309.1164575-1-keescook@chromium.org/

Hi,

Here's my tree for adding partial read support in kernel_read_file(),
which fixes a number of issues along the way. It's now got Scott's
firmware patches ported and everything tests clean for me.

I think the intention is for this to go via Greg's tree since Scott's
driver code will depend on it?

Thanks, and let me know what you think,

-Kees


Kees Cook (15):
  test_firmware: Test platform fw loading on non-EFI systems
  selftest/firmware: Add selftest timeout in settings
  firmware_loader: EFI firmware loader must handle pre-allocated buffer
  fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum
  fs/kernel_read_file: Remove FIRMWARE_EFI_EMBEDDED enum
  fs/kernel_read_file: Split into separate source file
  fs/kernel_read_file: Remove redundant size argument
  fs/kernel_read_file: Switch buffer size arg to size_t
  fs/kernel_read_file: Add file_size output argument
  LSM: Introduce kernel_post_load_data() hook
  firmware_loader: Use security_post_load_data()
  module: Call security_kernel_post_load_data()
  LSM: Add "contents" flag to kernel_read_file hook
  fs/kernel_file_read: Add "offset" arg for partial reads
  firmware: Store opt_flags in fw_priv

Scott Branden (3):
  fs/kernel_read_file: Split into separate include file
  firmware: Add request_partial_firmware_into_buf()
  test_firmware: Test partial read support

 drivers/base/firmware_loader/fallback.c       |  19 +-
 drivers/base/firmware_loader/fallback.h       |   5 +-
 .../base/firmware_loader/fallback_platform.c  |  16 +-
 drivers/base/firmware_loader/firmware.h       |   7 +-
 drivers/base/firmware_loader/main.c           | 143 ++++++++++---
 drivers/firmware/efi/embedded-firmware.c      |  21 +-
 drivers/firmware/efi/embedded-firmware.h      |  19 ++
 fs/Makefile                                   |   3 +-
 fs/exec.c                                     | 132 +-----------
 fs/kernel_read_file.c                         | 189 ++++++++++++++++++
 include/linux/efi_embedded_fw.h               |  13 --
 include/linux/firmware.h                      |  12 ++
 include/linux/fs.h                            |  39 ----
 include/linux/ima.h                           |  19 +-
 include/linux/kernel_read_file.h              |  55 +++++
 include/linux/lsm_hook_defs.h                 |   6 +-
 include/linux/lsm_hooks.h                     |  12 ++
 include/linux/security.h                      |  19 +-
 kernel/kexec.c                                |   2 +-
 kernel/kexec_file.c                           |  19 +-
 kernel/module.c                               |  24 ++-
 lib/test_firmware.c                           | 159 +++++++++++++--
 security/integrity/digsig.c                   |   8 +-
 security/integrity/ima/ima_fs.c               |  10 +-
 security/integrity/ima/ima_main.c             |  58 ++++--
 security/integrity/ima/ima_policy.c           |   1 +
 security/loadpin/loadpin.c                    |  17 +-
 security/security.c                           |  26 ++-
 security/selinux/hooks.c                      |   8 +-
 .../selftests/firmware/fw_filesystem.sh       |  91 +++++++++
 tools/testing/selftests/firmware/settings     |   8 +
 tools/testing/selftests/kselftest/runner.sh   |   6 +-
 32 files changed, 849 insertions(+), 317 deletions(-)
 create mode 100644 drivers/firmware/efi/embedded-firmware.h
 create mode 100644 fs/kernel_read_file.c
 create mode 100644 include/linux/kernel_read_file.h
 create mode 100644 tools/testing/selftests/firmware/settings

-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23 17:32   ` Scott Branden
  2020-07-29  0:48   ` Luis Chamberlain
  2020-07-22 19:30 ` [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings Kees Cook
                   ` (16 subsequent siblings)
  17 siblings, 2 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On non-EFI systems, it wasn't possible to test the platform firmware
loader because it will have never set "checked_fw" during __init.
Instead, allow the test code to override this check. Additionally split
the declarations into a private header file so it there is greater
enforcement of the symbol visibility.

Fixes: 548193cba2a7 ("test_firmware: add support for firmware_request_platform")
Cc: stable@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/firmware/efi/embedded-firmware.c | 21 ++++++++++++++++-----
 drivers/firmware/efi/embedded-firmware.h | 19 +++++++++++++++++++
 include/linux/efi_embedded_fw.h          | 13 -------------
 lib/test_firmware.c                      |  5 +++++
 4 files changed, 40 insertions(+), 18 deletions(-)
 create mode 100644 drivers/firmware/efi/embedded-firmware.h

diff --git a/drivers/firmware/efi/embedded-firmware.c b/drivers/firmware/efi/embedded-firmware.c
index a1b199de9006..0fb03cd0a5a2 100644
--- a/drivers/firmware/efi/embedded-firmware.c
+++ b/drivers/firmware/efi/embedded-firmware.c
@@ -14,11 +14,22 @@
 #include <linux/vmalloc.h>
 #include <crypto/sha.h>
 
+#include "embedded-firmware.h"
+
+#ifdef CONFIG_TEST_FIRMWARE
+# define EFI_EMBEDDED_FW_VISIBILITY
+#else
+# define EFI_EMBEDDED_FW_VISIBILITY static
+#endif
+
+EFI_EMBEDDED_FW_VISIBILITY LIST_HEAD(efi_embedded_fw_list);
+EFI_EMBEDDED_FW_VISIBILITY bool efi_embedded_fw_checked;
+
 /* Exported for use by lib/test_firmware.c only */
-LIST_HEAD(efi_embedded_fw_list);
+#ifdef CONFIG_TEST_FIRMWARE
 EXPORT_SYMBOL_GPL(efi_embedded_fw_list);
-
-static bool checked_for_fw;
+EXPORT_SYMBOL_GPL(efi_embedded_fw_checked);
+#endif
 
 static const struct dmi_system_id * const embedded_fw_table[] = {
 #ifdef CONFIG_TOUCHSCREEN_DMI
@@ -119,14 +130,14 @@ void __init efi_check_for_embedded_firmwares(void)
 		}
 	}
 
-	checked_for_fw = true;
+	efi_embedded_fw_checked = true;
 }
 
 int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size)
 {
 	struct efi_embedded_fw *iter, *fw = NULL;
 
-	if (!checked_for_fw) {
+	if (!efi_embedded_fw_checked) {
 		pr_warn("Warning %s called while we did not check for embedded fw\n",
 			__func__);
 		return -ENOENT;
diff --git a/drivers/firmware/efi/embedded-firmware.h b/drivers/firmware/efi/embedded-firmware.h
new file mode 100644
index 000000000000..34113316d068
--- /dev/null
+++ b/drivers/firmware/efi/embedded-firmware.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _EFI_EMBEDDED_FW_INTERNAL_H_
+#define _EFI_EMBEDDED_FW_INTERNAL_H_
+
+/*
+ * This struct and efi_embedded_fw_list are private to the efi-embedded fw
+ * implementation they only in separate header for use by lib/test_firmware.c.
+ */
+struct efi_embedded_fw {
+	struct list_head list;
+	const char *name;
+	const u8 *data;
+	size_t length;
+};
+
+extern struct list_head efi_embedded_fw_list;
+extern bool efi_embedded_fw_checked;
+
+#endif /* _EFI_EMBEDDED_FW_INTERNAL_H_ */
diff --git a/include/linux/efi_embedded_fw.h b/include/linux/efi_embedded_fw.h
index 57eac5241303..4ad5db9f5312 100644
--- a/include/linux/efi_embedded_fw.h
+++ b/include/linux/efi_embedded_fw.h
@@ -7,19 +7,6 @@
 
 #define EFI_EMBEDDED_FW_PREFIX_LEN		8
 
-/*
- * This struct and efi_embedded_fw_list are private to the efi-embedded fw
- * implementation they are in this header for use by lib/test_firmware.c only!
- */
-struct efi_embedded_fw {
-	struct list_head list;
-	const char *name;
-	const u8 *data;
-	size_t length;
-};
-
-extern struct list_head efi_embedded_fw_list;
-
 /**
  * struct efi_embedded_fw_desc - This struct is used by the EFI embedded-fw
  *                               code to search for embedded firmwares.
diff --git a/lib/test_firmware.c b/lib/test_firmware.c
index 9fee2b93a8d1..62af792e151c 100644
--- a/lib/test_firmware.c
+++ b/lib/test_firmware.c
@@ -489,6 +489,7 @@ static ssize_t trigger_request_store(struct device *dev,
 static DEVICE_ATTR_WO(trigger_request);
 
 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
+#include "../drivers/firmware/efi/embedded-firmware.h"
 static ssize_t trigger_request_platform_store(struct device *dev,
 					      struct device_attribute *attr,
 					      const char *buf, size_t count)
@@ -501,6 +502,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
 	};
 	struct efi_embedded_fw efi_embedded_fw;
 	const struct firmware *firmware = NULL;
+	bool saved_efi_embedded_fw_checked;
 	char *name;
 	int rc;
 
@@ -513,6 +515,8 @@ static ssize_t trigger_request_platform_store(struct device *dev,
 	efi_embedded_fw.data = (void *)test_data;
 	efi_embedded_fw.length = sizeof(test_data);
 	list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
+	saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
+	efi_embedded_fw_checked = true;
 
 	pr_info("loading '%s'\n", name);
 	rc = firmware_request_platform(&firmware, name, dev);
@@ -530,6 +534,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
 	rc = count;
 
 out:
+	efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
 	release_firmware(firmware);
 	list_del(&efi_embedded_fw.list);
 	kfree(name);
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
  2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23  6:38   ` SeongJae Park
  2020-07-23 17:34   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 03/18] firmware_loader: EFI firmware loader must handle pre-allocated buffer Kees Cook
                   ` (15 subsequent siblings)
  17 siblings, 2 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

The firmware tests would always time out for me. Add a correct timeout,
including details on how the value was reached. Additionally allow the
test harness to skip comments in settings files and report how long a
given timeout was.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 tools/testing/selftests/firmware/settings   | 8 ++++++++
 tools/testing/selftests/kselftest/runner.sh | 6 +++++-
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/firmware/settings

diff --git a/tools/testing/selftests/firmware/settings b/tools/testing/selftests/firmware/settings
new file mode 100644
index 000000000000..085e664ee093
--- /dev/null
+++ b/tools/testing/selftests/firmware/settings
@@ -0,0 +1,8 @@
+# The async firmware timeout is set to 1 second (but ends up being effectively
+# 2 seconds). There are 3 test configs, each done with and without firmware
+# present, each with 2 "nowait" functions tested 5 times. Expected time for a
+# normal execution should be 2 * 3 * 2 * 2 * 5 = 120 seconds for those alone.
+# Additionally, fw_fallback may take 5 seconds for internal timeouts in each
+# of the 3 configs, so at least another 15 seconds are needed. Add another
+# 10 seconds for each testing config: 120 + 15 + 30
+timeout=165
diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh
index 676b3a8b114d..cd5ddf979f15 100644
--- a/tools/testing/selftests/kselftest/runner.sh
+++ b/tools/testing/selftests/kselftest/runner.sh
@@ -53,6 +53,10 @@ run_one()
 	settings="$BASE_DIR/$DIR/settings"
 	if [ -r "$settings" ] ; then
 		while read line ; do
+			# Skip comments.
+			if echo "$line" | grep -q '^#'; then
+				continue
+			fi
 			field=$(echo "$line" | cut -d= -f1)
 			value=$(echo "$line" | cut -d= -f2-)
 			eval "kselftest_$field"="$value"
@@ -80,7 +84,7 @@ run_one()
 			echo "not ok $test_num $TEST_HDR_MSG # SKIP"
 		elif [ $rc -eq $timeout_rc ]; then \
 			echo "#"
-			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT"
+			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
 		else
 			echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
 		fi)
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 03/18] firmware_loader: EFI firmware loader must handle pre-allocated buffer
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
  2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
  2020-07-22 19:30 ` [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 04/18] fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum Kees Cook
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

The EFI platform firmware fallback would clobber any pre-allocated
buffers. Instead, correctly refuse to reallocate when too small (as
already done in the sysfs fallback), or perform allocation normally
when needed.

Fixes: e4c2c0ff00ec ("firmware: Add new platform fallback mechanism and firm ware_request_platform()")
Cc: stable@vger.kernel.org
Acked-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
To aid in backporting, this change is made before moving
kernel_read_file() to separate header/source files.
---
 drivers/base/firmware_loader/fallback_platform.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
index cdd2c9a9f38a..685edb7dd05a 100644
--- a/drivers/base/firmware_loader/fallback_platform.c
+++ b/drivers/base/firmware_loader/fallback_platform.c
@@ -25,7 +25,10 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
 	if (rc)
 		return rc; /* rc == -ENOENT when the fw was not found */
 
-	fw_priv->data = vmalloc(size);
+	if (fw_priv->data && size > fw_priv->allocated_size)
+		return -ENOMEM;
+	if (!fw_priv->data)
+		fw_priv->data = vmalloc(size);
 	if (!fw_priv->data)
 		return -ENOMEM;
 
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 04/18] fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (2 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 03/18] firmware_loader: EFI firmware loader must handle pre-allocated buffer Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 05/18] fs/kernel_read_file: Remove FIRMWARE_EFI_EMBEDDED enum Kees Cook
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

FIRMWARE_PREALLOC_BUFFER is a "how", not a "what", and confuses the LSMs
that are interested in filtering between types of things. The "how"
should be an internal detail made uninteresting to the LSMs.

Fixes: a098ecd2fa7d ("firmware: support loading into a pre-allocated buffer")
Fixes: fd90bc559bfb ("ima: based on policy verify firmware signatures (pre-allocated buffer)")
Fixes: 4f0496d8ffa3 ("ima: based on policy warn about loading firmware (pre-allocated buffer)")
Cc: stable@vger.kernel.org
Acked-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
To aid in backporting, this change is made before moving
kernel_read_file() to separate header/source files.
---
 drivers/base/firmware_loader/main.c | 5 ++---
 fs/exec.c                           | 7 ++++---
 include/linux/fs.h                  | 2 +-
 kernel/module.c                     | 2 +-
 security/integrity/digsig.c         | 2 +-
 security/integrity/ima/ima_fs.c     | 2 +-
 security/integrity/ima/ima_main.c   | 6 ++----
 7 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index ca871b13524e..c2f57cedcd6f 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -465,14 +465,12 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 	int i, len;
 	int rc = -ENOENT;
 	char *path;
-	enum kernel_read_file_id id = READING_FIRMWARE;
 	size_t msize = INT_MAX;
 	void *buffer = NULL;
 
 	/* Already populated data member means we're loading into a buffer */
 	if (!decompress && fw_priv->data) {
 		buffer = fw_priv->data;
-		id = READING_FIRMWARE_PREALLOC_BUFFER;
 		msize = fw_priv->allocated_size;
 	}
 
@@ -496,7 +494,8 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 
 		/* load firmware files from the mount namespace of init */
 		rc = kernel_read_file_from_path_initns(path, &buffer,
-						       &size, msize, id);
+						       &size, msize,
+						       READING_FIRMWARE);
 		if (rc) {
 			if (rc != -ENOENT)
 				dev_warn(device, "loading %s failed with error %d\n",
diff --git a/fs/exec.c b/fs/exec.c
index e6e8a9a70327..2bf549757ce7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -927,6 +927,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 {
 	loff_t i_size, pos;
 	ssize_t bytes = 0;
+	void *allocated = NULL;
 	int ret;
 
 	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
@@ -950,8 +951,8 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 		goto out;
 	}
 
-	if (id != READING_FIRMWARE_PREALLOC_BUFFER)
-		*buf = vmalloc(i_size);
+	if (!*buf)
+		*buf = allocated = vmalloc(i_size);
 	if (!*buf) {
 		ret = -ENOMEM;
 		goto out;
@@ -980,7 +981,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 
 out_free:
 	if (ret < 0) {
-		if (id != READING_FIRMWARE_PREALLOC_BUFFER) {
+		if (allocated) {
 			vfree(*buf);
 			*buf = NULL;
 		}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3f881a892ea7..95fc775ed937 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2993,10 +2993,10 @@ static inline void i_readcount_inc(struct inode *inode)
 #endif
 extern int do_pipe_flags(int *, int);
 
+/* This is a list of *what* is being read, not *how*. */
 #define __kernel_read_file_id(id) \
 	id(UNKNOWN, unknown)		\
 	id(FIRMWARE, firmware)		\
-	id(FIRMWARE_PREALLOC_BUFFER, firmware)	\
 	id(FIRMWARE_EFI_EMBEDDED, firmware)	\
 	id(MODULE, kernel-module)		\
 	id(KEXEC_IMAGE, kexec-image)		\
diff --git a/kernel/module.c b/kernel/module.c
index 0c6573b98c36..26105148f4d2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3988,7 +3988,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 {
 	struct load_info info = { };
 	loff_t size;
-	void *hdr;
+	void *hdr = NULL;
 	int err;
 
 	err = may_init_module();
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index e9cbadade74b..ac02b7632353 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -169,7 +169,7 @@ int __init integrity_add_key(const unsigned int id, const void *data,
 
 int __init integrity_load_x509(const unsigned int id, const char *path)
 {
-	void *data;
+	void *data = NULL;
 	loff_t size;
 	int rc;
 	key_perm_t perm;
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index e3fcad871861..15a44c5022f7 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -272,7 +272,7 @@ static const struct file_operations ima_ascii_measurements_ops = {
 
 static ssize_t ima_read_policy(char *path)
 {
-	void *data;
+	void *data = NULL;
 	char *datap;
 	loff_t size;
 	int rc, pathlen = strlen(path);
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index c1583d98c5e5..f80ee4ce4669 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -611,19 +611,17 @@ void ima_post_path_mknod(struct dentry *dentry)
 int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
 {
 	/*
-	 * READING_FIRMWARE_PREALLOC_BUFFER
-	 *
 	 * Do devices using pre-allocated memory run the risk of the
 	 * firmware being accessible to the device prior to the completion
 	 * of IMA's signature verification any more than when using two
-	 * buffers?
+	 * buffers? It may be desirable to include the buffer address
+	 * in this API and walk all the dma_map_single() mappings to check.
 	 */
 	return 0;
 }
 
 const int read_idmap[READING_MAX_ID] = {
 	[READING_FIRMWARE] = FIRMWARE_CHECK,
-	[READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK,
 	[READING_MODULE] = MODULE_CHECK,
 	[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
 	[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 05/18] fs/kernel_read_file: Remove FIRMWARE_EFI_EMBEDDED enum
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (3 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 04/18] fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 06/18] fs/kernel_read_file: Split into separate include file Kees Cook
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

The "FIRMWARE_EFI_EMBEDDED" enum is a "where", not a "what". It
should not be distinguished separately from just "FIRMWARE", as this
confuses the LSMs about what is being loaded. Additionally, there was
no actual validation of the firmware contents happening.

Fixes: e4c2c0ff00ec ("firmware: Add new platform fallback mechanism and firmware_request_platform()")
Cc: stable@vger.kernel.org
Acked-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
To aid in backporting, this change is made before moving
kernel_read_file() to separate header/source files.
---
 drivers/base/firmware_loader/fallback_platform.c | 2 +-
 include/linux/fs.h                               | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
index 685edb7dd05a..6958ab1a8059 100644
--- a/drivers/base/firmware_loader/fallback_platform.c
+++ b/drivers/base/firmware_loader/fallback_platform.c
@@ -17,7 +17,7 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
 	if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
 		return -ENOENT;
 
-	rc = security_kernel_load_data(LOADING_FIRMWARE_EFI_EMBEDDED);
+	rc = security_kernel_load_data(LOADING_FIRMWARE);
 	if (rc)
 		return rc;
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 95fc775ed937..f50a35d54a61 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2993,11 +2993,10 @@ static inline void i_readcount_inc(struct inode *inode)
 #endif
 extern int do_pipe_flags(int *, int);
 
-/* This is a list of *what* is being read, not *how*. */
+/* This is a list of *what* is being read, not *how* nor *where*. */
 #define __kernel_read_file_id(id) \
 	id(UNKNOWN, unknown)		\
 	id(FIRMWARE, firmware)		\
-	id(FIRMWARE_EFI_EMBEDDED, firmware)	\
 	id(MODULE, kernel-module)		\
 	id(KEXEC_IMAGE, kexec-image)		\
 	id(KEXEC_INITRAMFS, kexec-initramfs)	\
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 06/18] fs/kernel_read_file: Split into separate include file
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (4 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 05/18] fs/kernel_read_file: Remove FIRMWARE_EFI_EMBEDDED enum Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 07/18] fs/kernel_read_file: Split into separate source file Kees Cook
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Christoph Hellwig, Thomas Cedeno,
	linux-security-module, Anders Roxell, Paul Moore,
	Mauro Carvalho Chehab, Michael Ellerman, Nayna Jain,
	Matthew Garrett, James Morris, Ard Biesheuvel,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

From: Scott Branden <scott.branden@broadcom.com>

Move kernel_read_file* out of linux/fs.h to its own linux/kernel_read_file.h
include file. That header gets pulled in just about everywhere
and doesn't really need functions not related to the general fs interface.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/20200706232309.12010-2-scott.branden@broadcom.com
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/main.c |  1 +
 fs/exec.c                           |  1 +
 include/linux/fs.h                  | 38 ---------------------
 include/linux/ima.h                 |  1 +
 include/linux/kernel_read_file.h    | 51 +++++++++++++++++++++++++++++
 include/linux/security.h            |  1 +
 kernel/kexec_file.c                 |  1 +
 kernel/module.c                     |  1 +
 security/integrity/digsig.c         |  1 +
 security/integrity/ima/ima_fs.c     |  1 +
 security/integrity/ima/ima_main.c   |  1 +
 security/integrity/ima/ima_policy.c |  1 +
 security/loadpin/loadpin.c          |  1 +
 security/security.c                 |  1 +
 security/selinux/hooks.c            |  1 +
 15 files changed, 64 insertions(+), 38 deletions(-)
 create mode 100644 include/linux/kernel_read_file.h

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index c2f57cedcd6f..d4a413ea48ce 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -12,6 +12,7 @@
 
 #include <linux/capability.h>
 #include <linux/device.h>
+#include <linux/kernel_read_file.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/timer.h>
diff --git a/fs/exec.c b/fs/exec.c
index 2bf549757ce7..07a7fe9ac5be 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -23,6 +23,7 @@
  * formats.
  */
 
+#include <linux/kernel_read_file.h>
 #include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/fdtable.h>
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f50a35d54a61..11dd6cc7de58 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2993,44 +2993,6 @@ static inline void i_readcount_inc(struct inode *inode)
 #endif
 extern int do_pipe_flags(int *, int);
 
-/* This is a list of *what* is being read, not *how* nor *where*. */
-#define __kernel_read_file_id(id) \
-	id(UNKNOWN, unknown)		\
-	id(FIRMWARE, firmware)		\
-	id(MODULE, kernel-module)		\
-	id(KEXEC_IMAGE, kexec-image)		\
-	id(KEXEC_INITRAMFS, kexec-initramfs)	\
-	id(POLICY, security-policy)		\
-	id(X509_CERTIFICATE, x509-certificate)	\
-	id(MAX_ID, )
-
-#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
-#define __fid_stringify(dummy, str) #str,
-
-enum kernel_read_file_id {
-	__kernel_read_file_id(__fid_enumify)
-};
-
-static const char * const kernel_read_file_str[] = {
-	__kernel_read_file_id(__fid_stringify)
-};
-
-static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
-{
-	if ((unsigned)id >= READING_MAX_ID)
-		return kernel_read_file_str[READING_UNKNOWN];
-
-	return kernel_read_file_str[id];
-}
-
-extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
-			    enum kernel_read_file_id);
-extern int kernel_read_file_from_path(const char *, void **, loff_t *, loff_t,
-				      enum kernel_read_file_id);
-extern int kernel_read_file_from_path_initns(const char *, void **, loff_t *, loff_t,
-					     enum kernel_read_file_id);
-extern int kernel_read_file_from_fd(int, void **, loff_t *, loff_t,
-				    enum kernel_read_file_id);
 extern ssize_t kernel_read(struct file *, void *, size_t, loff_t *);
 extern ssize_t kernel_write(struct file *, const void *, size_t, loff_t *);
 extern ssize_t __kernel_write(struct file *, const void *, size_t, loff_t *);
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 9164e1534ec9..148636bfcc8f 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -7,6 +7,7 @@
 #ifndef _LINUX_IMA_H
 #define _LINUX_IMA_H
 
+#include <linux/kernel_read_file.h>
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/kexec.h>
diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
new file mode 100644
index 000000000000..78cf3d7dc835
--- /dev/null
+++ b/include/linux/kernel_read_file.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_KERNEL_READ_FILE_H
+#define _LINUX_KERNEL_READ_FILE_H
+
+#include <linux/file.h>
+#include <linux/types.h>
+
+/* This is a list of *what* is being read, not *how* nor *where*. */
+#define __kernel_read_file_id(id) \
+	id(UNKNOWN, unknown)		\
+	id(FIRMWARE, firmware)		\
+	id(MODULE, kernel-module)		\
+	id(KEXEC_IMAGE, kexec-image)		\
+	id(KEXEC_INITRAMFS, kexec-initramfs)	\
+	id(POLICY, security-policy)		\
+	id(X509_CERTIFICATE, x509-certificate)	\
+	id(MAX_ID, )
+
+#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
+#define __fid_stringify(dummy, str) #str,
+
+enum kernel_read_file_id {
+	__kernel_read_file_id(__fid_enumify)
+};
+
+static const char * const kernel_read_file_str[] = {
+	__kernel_read_file_id(__fid_stringify)
+};
+
+static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
+{
+	if ((unsigned int)id >= READING_MAX_ID)
+		return kernel_read_file_str[READING_UNKNOWN];
+
+	return kernel_read_file_str[id];
+}
+
+int kernel_read_file(struct file *file,
+		     void **buf, loff_t *size, loff_t max_size,
+		     enum kernel_read_file_id id);
+int kernel_read_file_from_path(const char *path,
+			       void **buf, loff_t *size, loff_t max_size,
+			       enum kernel_read_file_id id);
+int kernel_read_file_from_path_initns(const char *path,
+				      void **buf, loff_t *size, loff_t max_size,
+				      enum kernel_read_file_id id);
+int kernel_read_file_from_fd(int fd,
+			     void **buf, loff_t *size, loff_t max_size,
+			     enum kernel_read_file_id id);
+
+#endif /* _LINUX_KERNEL_READ_FILE_H */
diff --git a/include/linux/security.h b/include/linux/security.h
index 0a0a03b36a3b..42df0d9b4c37 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -23,6 +23,7 @@
 #ifndef __LINUX_SECURITY_H
 #define __LINUX_SECURITY_H
 
+#include <linux/kernel_read_file.h>
 #include <linux/key.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 09cc78df53c6..1358069ce9e9 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -24,6 +24,7 @@
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/kernel.h>
+#include <linux/kernel_read_file.h>
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
 #include "kexec_internal.h"
diff --git a/kernel/module.c b/kernel/module.c
index 26105148f4d2..e9765803601b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -18,6 +18,7 @@
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 #include <linux/kernel.h>
+#include <linux/kernel_read_file.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index ac02b7632353..f8869be45d8f 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/cred.h>
+#include <linux/kernel_read_file.h>
 #include <linux/key-type.h>
 #include <linux/digsig.h>
 #include <linux/vmalloc.h>
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 15a44c5022f7..e13ffece3726 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -13,6 +13,7 @@
  */
 
 #include <linux/fcntl.h>
+#include <linux/kernel_read_file.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index f80ee4ce4669..dab4a13221cf 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/file.h>
 #include <linux/binfmts.h>
+#include <linux/kernel_read_file.h>
 #include <linux/mount.h>
 #include <linux/mman.h>
 #include <linux/slab.h>
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e493063a3c34..f8390f6081f0 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -9,6 +9,7 @@
 
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/kernel_read_file.h>
 #include <linux/fs.h>
 #include <linux/security.h>
 #include <linux/magic.h>
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index ee5cb944f4ad..81bc95127f92 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
 #include <linux/mount.h>
 #include <linux/path.h>
diff --git a/security/security.c b/security/security.c
index 0ce3e73edd42..f5920115a325 100644
--- a/security/security.c
+++ b/security/security.c
@@ -16,6 +16,7 @@
 #include <linux/export.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kernel_read_file.h>
 #include <linux/lsm_hooks.h>
 #include <linux/integrity.h>
 #include <linux/ima.h>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index efa6108b1ce9..5de45010fb1a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/kd.h>
 #include <linux/kernel.h>
+#include <linux/kernel_read_file.h>
 #include <linux/tracehook.h>
 #include <linux/errno.h>
 #include <linux/sched/signal.h>
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 07/18] fs/kernel_read_file: Split into separate source file
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (5 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 06/18] fs/kernel_read_file: Split into separate include file Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument Kees Cook
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

These routines are used in places outside of exec(2), so in preparation
for refactoring them, move them into a separate source file,
fs/kernel_read_file.c.

Acked-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/Makefile           |   3 +-
 fs/exec.c             | 132 ----------------------------------------
 fs/kernel_read_file.c | 138 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+), 133 deletions(-)
 create mode 100644 fs/kernel_read_file.c

diff --git a/fs/Makefile b/fs/Makefile
index 2ce5112b02c8..a05fc247b2a7 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -13,7 +13,8 @@ obj-y :=	open.o read_write.o file_table.o super.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o \
 		pnode.o splice.o sync.o utimes.o d_path.o \
 		stack.o fs_struct.o statfs.o fs_pin.o nsfs.o \
-		fs_types.o fs_context.o fs_parser.o fsopen.o
+		fs_types.o fs_context.o fs_parser.o fsopen.o \
+		kernel_read_file.o
 
 ifeq ($(CONFIG_BLOCK),y)
 obj-y +=	buffer.o block_dev.o direct-io.o mpage.o
diff --git a/fs/exec.c b/fs/exec.c
index 07a7fe9ac5be..d619b79aab30 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -923,138 +923,6 @@ struct file *open_exec(const char *name)
 }
 EXPORT_SYMBOL(open_exec);
 
-int kernel_read_file(struct file *file, void **buf, loff_t *size,
-		     loff_t max_size, enum kernel_read_file_id id)
-{
-	loff_t i_size, pos;
-	ssize_t bytes = 0;
-	void *allocated = NULL;
-	int ret;
-
-	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
-		return -EINVAL;
-
-	ret = deny_write_access(file);
-	if (ret)
-		return ret;
-
-	ret = security_kernel_read_file(file, id);
-	if (ret)
-		goto out;
-
-	i_size = i_size_read(file_inode(file));
-	if (i_size <= 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
-		ret = -EFBIG;
-		goto out;
-	}
-
-	if (!*buf)
-		*buf = allocated = vmalloc(i_size);
-	if (!*buf) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	pos = 0;
-	while (pos < i_size) {
-		bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
-		if (bytes < 0) {
-			ret = bytes;
-			goto out_free;
-		}
-
-		if (bytes == 0)
-			break;
-	}
-
-	if (pos != i_size) {
-		ret = -EIO;
-		goto out_free;
-	}
-
-	ret = security_kernel_post_read_file(file, *buf, i_size, id);
-	if (!ret)
-		*size = pos;
-
-out_free:
-	if (ret < 0) {
-		if (allocated) {
-			vfree(*buf);
-			*buf = NULL;
-		}
-	}
-
-out:
-	allow_write_access(file);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(kernel_read_file);
-
-int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
-			       loff_t max_size, enum kernel_read_file_id id)
-{
-	struct file *file;
-	int ret;
-
-	if (!path || !*path)
-		return -EINVAL;
-
-	file = filp_open(path, O_RDONLY, 0);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	ret = kernel_read_file(file, buf, size, max_size, id);
-	fput(file);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
-
-int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      loff_t *size, loff_t max_size,
-				      enum kernel_read_file_id id)
-{
-	struct file *file;
-	struct path root;
-	int ret;
-
-	if (!path || !*path)
-		return -EINVAL;
-
-	task_lock(&init_task);
-	get_fs_root(init_task.fs, &root);
-	task_unlock(&init_task);
-
-	file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0);
-	path_put(&root);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	ret = kernel_read_file(file, buf, size, max_size, id);
-	fput(file);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
-
-int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
-			     enum kernel_read_file_id id)
-{
-	struct fd f = fdget(fd);
-	int ret = -EBADF;
-
-	if (!f.file)
-		goto out;
-
-	ret = kernel_read_file(f.file, buf, size, max_size, id);
-out:
-	fdput(f);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
-
 #if defined(CONFIG_HAVE_AOUT) || defined(CONFIG_BINFMT_FLAT) || \
     defined(CONFIG_BINFMT_ELF_FDPIC)
 ssize_t read_code(struct file *file, unsigned long addr, loff_t pos, size_t len)
diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
new file mode 100644
index 000000000000..54d972d4befc
--- /dev/null
+++ b/fs/kernel_read_file.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/fs.h>
+#include <linux/fs_struct.h>
+#include <linux/kernel_read_file.h>
+#include <linux/security.h>
+#include <linux/vmalloc.h>
+
+int kernel_read_file(struct file *file, void **buf, loff_t *size,
+		     loff_t max_size, enum kernel_read_file_id id)
+{
+	loff_t i_size, pos;
+	ssize_t bytes = 0;
+	void *allocated = NULL;
+	int ret;
+
+	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
+		return -EINVAL;
+
+	ret = deny_write_access(file);
+	if (ret)
+		return ret;
+
+	ret = security_kernel_read_file(file, id);
+	if (ret)
+		goto out;
+
+	i_size = i_size_read(file_inode(file));
+	if (i_size <= 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+		ret = -EFBIG;
+		goto out;
+	}
+
+	if (!*buf)
+		*buf = allocated = vmalloc(i_size);
+	if (!*buf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pos = 0;
+	while (pos < i_size) {
+		bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
+		if (bytes < 0) {
+			ret = bytes;
+			goto out_free;
+		}
+
+		if (bytes == 0)
+			break;
+	}
+
+	if (pos != i_size) {
+		ret = -EIO;
+		goto out_free;
+	}
+
+	ret = security_kernel_post_read_file(file, *buf, i_size, id);
+	if (!ret)
+		*size = pos;
+
+out_free:
+	if (ret < 0) {
+		if (allocated) {
+			vfree(*buf);
+			*buf = NULL;
+		}
+	}
+
+out:
+	allow_write_access(file);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file);
+
+int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
+			       loff_t max_size, enum kernel_read_file_id id)
+{
+	struct file *file;
+	int ret;
+
+	if (!path || !*path)
+		return -EINVAL;
+
+	file = filp_open(path, O_RDONLY, 0);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ret = kernel_read_file(file, buf, size, max_size, id);
+	fput(file);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
+
+int kernel_read_file_from_path_initns(const char *path, void **buf,
+				      loff_t *size, loff_t max_size,
+				      enum kernel_read_file_id id)
+{
+	struct file *file;
+	struct path root;
+	int ret;
+
+	if (!path || !*path)
+		return -EINVAL;
+
+	task_lock(&init_task);
+	get_fs_root(init_task.fs, &root);
+	task_unlock(&init_task);
+
+	file = file_open_root(root.dentry, root.mnt, path, O_RDONLY, 0);
+	path_put(&root);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	ret = kernel_read_file(file, buf, size, max_size, id);
+	fput(file);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
+
+int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
+			     enum kernel_read_file_id id)
+{
+	struct fd f = fdget(fd);
+	int ret = -EBADF;
+
+	if (!f.file)
+		goto out;
+
+	ret = kernel_read_file(f.file, buf, size, max_size, id);
+out:
+	fdput(f);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(kernel_read_file_from_fd);
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (6 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 07/18] fs/kernel_read_file: Split into separate source file Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23 17:35   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t Kees Cook
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

In preparation for refactoring kernel_read_file*(), remove the redundant
"size" argument which is not needed: it can be included in the return
code, with callers adjusted. (VFS reads already cannot be larger than
INT_MAX.)

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/main.c | 10 ++++++----
 fs/kernel_read_file.c               | 20 +++++++++-----------
 include/linux/kernel_read_file.h    |  8 ++++----
 kernel/kexec_file.c                 | 14 +++++++-------
 kernel/module.c                     |  7 +++----
 security/integrity/digsig.c         |  5 +++--
 security/integrity/ima/ima_fs.c     |  6 ++++--
 7 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index d4a413ea48ce..f80c0d102be8 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -462,7 +462,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 					     size_t in_size,
 					     const void *in_buffer))
 {
-	loff_t size;
+	size_t size;
 	int i, len;
 	int rc = -ENOENT;
 	char *path;
@@ -494,10 +494,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 		fw_priv->size = 0;
 
 		/* load firmware files from the mount namespace of init */
-		rc = kernel_read_file_from_path_initns(path, &buffer,
-						       &size, msize,
+		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
 						       READING_FIRMWARE);
-		if (rc) {
+		if (rc < 0) {
 			if (rc != -ENOENT)
 				dev_warn(device, "loading %s failed with error %d\n",
 					 path, rc);
@@ -506,6 +505,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 					 path);
 			continue;
 		}
+		size = rc;
+		rc = 0;
+
 		dev_dbg(device, "Loading firmware from %s\n", path);
 		if (decompress) {
 			dev_dbg(device, "f/w decompressing %s\n",
diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
index 54d972d4befc..dc28a8def597 100644
--- a/fs/kernel_read_file.c
+++ b/fs/kernel_read_file.c
@@ -5,7 +5,7 @@
 #include <linux/security.h>
 #include <linux/vmalloc.h>
 
-int kernel_read_file(struct file *file, void **buf, loff_t *size,
+int kernel_read_file(struct file *file, void **buf,
 		     loff_t max_size, enum kernel_read_file_id id)
 {
 	loff_t i_size, pos;
@@ -29,7 +29,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 		ret = -EINVAL;
 		goto out;
 	}
-	if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+	if (i_size > INT_MAX || (max_size > 0 && i_size > max_size)) {
 		ret = -EFBIG;
 		goto out;
 	}
@@ -59,8 +59,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 	}
 
 	ret = security_kernel_post_read_file(file, *buf, i_size, id);
-	if (!ret)
-		*size = pos;
 
 out_free:
 	if (ret < 0) {
@@ -72,11 +70,11 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
 
 out:
 	allow_write_access(file);
-	return ret;
+	return ret == 0 ? pos : ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
-int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
+int kernel_read_file_from_path(const char *path, void **buf,
 			       loff_t max_size, enum kernel_read_file_id id)
 {
 	struct file *file;
@@ -89,14 +87,14 @@ int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, size, max_size, id);
+	ret = kernel_read_file(file, buf, max_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
 int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      loff_t *size, loff_t max_size,
+				      loff_t max_size,
 				      enum kernel_read_file_id id)
 {
 	struct file *file;
@@ -115,13 +113,13 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, size, max_size, id);
+	ret = kernel_read_file(file, buf, max_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
 
-int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
+int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
 			     enum kernel_read_file_id id)
 {
 	struct fd f = fdget(fd);
@@ -130,7 +128,7 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
 	if (!f.file)
 		goto out;
 
-	ret = kernel_read_file(f.file, buf, size, max_size, id);
+	ret = kernel_read_file(f.file, buf, max_size, id);
 out:
 	fdput(f);
 	return ret;
diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
index 78cf3d7dc835..0ca0bdbed1bd 100644
--- a/include/linux/kernel_read_file.h
+++ b/include/linux/kernel_read_file.h
@@ -36,16 +36,16 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
 }
 
 int kernel_read_file(struct file *file,
-		     void **buf, loff_t *size, loff_t max_size,
+		     void **buf, loff_t max_size,
 		     enum kernel_read_file_id id);
 int kernel_read_file_from_path(const char *path,
-			       void **buf, loff_t *size, loff_t max_size,
+			       void **buf, loff_t max_size,
 			       enum kernel_read_file_id id);
 int kernel_read_file_from_path_initns(const char *path,
-				      void **buf, loff_t *size, loff_t max_size,
+				      void **buf, loff_t max_size,
 				      enum kernel_read_file_id id);
 int kernel_read_file_from_fd(int fd,
-			     void **buf, loff_t *size, loff_t max_size,
+			     void **buf, loff_t max_size,
 			     enum kernel_read_file_id id);
 
 #endif /* _LINUX_KERNEL_READ_FILE_H */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 1358069ce9e9..eda19ca256a3 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -220,13 +220,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 {
 	int ret;
 	void *ldata;
-	loff_t size;
 
 	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
-				       &size, INT_MAX, READING_KEXEC_IMAGE);
-	if (ret)
+				       INT_MAX, READING_KEXEC_IMAGE);
+	if (ret < 0)
 		return ret;
-	image->kernel_buf_len = size;
+	image->kernel_buf_len = ret;
 
 	/* Call arch image probe handlers */
 	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
@@ -243,11 +242,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	/* It is possible that there no initramfs is being loaded */
 	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
 		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
-					       &size, INT_MAX,
+					       INT_MAX,
 					       READING_KEXEC_INITRAMFS);
-		if (ret)
+		if (ret < 0)
 			goto out;
-		image->initrd_buf_len = size;
+		image->initrd_buf_len = ret;
+		ret = 0;
 	}
 
 	if (cmdline_len) {
diff --git a/kernel/module.c b/kernel/module.c
index e9765803601b..b6fd4f51cc30 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3988,7 +3988,6 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
 SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 {
 	struct load_info info = { };
-	loff_t size;
 	void *hdr = NULL;
 	int err;
 
@@ -4002,12 +4001,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 		      |MODULE_INIT_IGNORE_VERMAGIC))
 		return -EINVAL;
 
-	err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX,
+	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX,
 				       READING_MODULE);
-	if (err)
+	if (err < 0)
 		return err;
 	info.hdr = hdr;
-	info.len = size;
+	info.len = err;
 
 	return load_module(&info, uargs, flags);
 }
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index f8869be45d8f..97661ffabc4e 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -171,16 +171,17 @@ int __init integrity_add_key(const unsigned int id, const void *data,
 int __init integrity_load_x509(const unsigned int id, const char *path)
 {
 	void *data = NULL;
-	loff_t size;
+	size_t size;
 	int rc;
 	key_perm_t perm;
 
-	rc = kernel_read_file_from_path(path, &data, &size, 0,
+	rc = kernel_read_file_from_path(path, &data, 0,
 					READING_X509_CERTIFICATE);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
 	}
+	size = rc;
 
 	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
 
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index e13ffece3726..602f52717757 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -275,7 +275,7 @@ static ssize_t ima_read_policy(char *path)
 {
 	void *data = NULL;
 	char *datap;
-	loff_t size;
+	size_t size;
 	int rc, pathlen = strlen(path);
 
 	char *p;
@@ -284,11 +284,13 @@ static ssize_t ima_read_policy(char *path)
 	datap = path;
 	strsep(&datap, "\n");
 
-	rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
+	rc = kernel_read_file_from_path(path, &data, 0, READING_POLICY);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
 	}
+	size = rc;
+	rc = 0;
 
 	datap = data;
 	while (size > 0 && (p = strsep(&datap, "\n"))) {
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (7 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23 17:36   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument Kees Cook
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

In preparation for further refactoring of kernel_read_file*(), rename
the "max_size" argument to the more accurate "buf_size", and correct
its type to size_t. Add kerndoc to explain the specifics of how the
arguments will be used. Note that with buf_size now size_t, it can no
longer be negative (and was never called with a negative value). Adjust
callers to use it as a "maximum size" when *buf is NULL.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/kernel_read_file.c            | 34 +++++++++++++++++++++++---------
 include/linux/kernel_read_file.h |  8 ++++----
 security/integrity/digsig.c      |  2 +-
 security/integrity/ima/ima_fs.c  |  2 +-
 4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
index dc28a8def597..e21a76001fff 100644
--- a/fs/kernel_read_file.c
+++ b/fs/kernel_read_file.c
@@ -5,15 +5,31 @@
 #include <linux/security.h>
 #include <linux/vmalloc.h>
 
+/**
+ * kernel_read_file() - read file contents into a kernel buffer
+ *
+ * @file	file to read from
+ * @buf		pointer to a "void *" buffer for reading into (if
+ *		*@buf is NULL, a buffer will be allocated, and
+ *		@buf_size will be ignored)
+ * @buf_size	size of buf, if already allocated. If @buf not
+ *		allocated, this is the largest size to allocate.
+ * @id		the kernel_read_file_id identifying the type of
+ *		file contents being read (for LSMs to examine)
+ *
+ * Returns number of bytes read (no single read will be bigger
+ * than INT_MAX), or negative on error.
+ *
+ */
 int kernel_read_file(struct file *file, void **buf,
-		     loff_t max_size, enum kernel_read_file_id id)
+		     size_t buf_size, enum kernel_read_file_id id)
 {
 	loff_t i_size, pos;
 	ssize_t bytes = 0;
 	void *allocated = NULL;
 	int ret;
 
-	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
+	if (!S_ISREG(file_inode(file)->i_mode))
 		return -EINVAL;
 
 	ret = deny_write_access(file);
@@ -29,7 +45,7 @@ int kernel_read_file(struct file *file, void **buf,
 		ret = -EINVAL;
 		goto out;
 	}
-	if (i_size > INT_MAX || (max_size > 0 && i_size > max_size)) {
+	if (i_size > INT_MAX || i_size > buf_size) {
 		ret = -EFBIG;
 		goto out;
 	}
@@ -75,7 +91,7 @@ int kernel_read_file(struct file *file, void **buf,
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
 int kernel_read_file_from_path(const char *path, void **buf,
-			       loff_t max_size, enum kernel_read_file_id id)
+			       size_t buf_size, enum kernel_read_file_id id)
 {
 	struct file *file;
 	int ret;
@@ -87,14 +103,14 @@ int kernel_read_file_from_path(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, max_size, id);
+	ret = kernel_read_file(file, buf, buf_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
 int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      loff_t max_size,
+				      size_t buf_size,
 				      enum kernel_read_file_id id)
 {
 	struct file *file;
@@ -113,13 +129,13 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, max_size, id);
+	ret = kernel_read_file(file, buf, buf_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
 
-int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
+int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
 			     enum kernel_read_file_id id)
 {
 	struct fd f = fdget(fd);
@@ -128,7 +144,7 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
 	if (!f.file)
 		goto out;
 
-	ret = kernel_read_file(f.file, buf, max_size, id);
+	ret = kernel_read_file(f.file, buf, buf_size, id);
 out:
 	fdput(f);
 	return ret;
diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
index 0ca0bdbed1bd..910039e7593e 100644
--- a/include/linux/kernel_read_file.h
+++ b/include/linux/kernel_read_file.h
@@ -36,16 +36,16 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
 }
 
 int kernel_read_file(struct file *file,
-		     void **buf, loff_t max_size,
+		     void **buf, size_t buf_size,
 		     enum kernel_read_file_id id);
 int kernel_read_file_from_path(const char *path,
-			       void **buf, loff_t max_size,
+			       void **buf, size_t buf_size,
 			       enum kernel_read_file_id id);
 int kernel_read_file_from_path_initns(const char *path,
-				      void **buf, loff_t max_size,
+				      void **buf, size_t buf_size,
 				      enum kernel_read_file_id id);
 int kernel_read_file_from_fd(int fd,
-			     void **buf, loff_t max_size,
+			     void **buf, size_t buf_size,
 			     enum kernel_read_file_id id);
 
 #endif /* _LINUX_KERNEL_READ_FILE_H */
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 97661ffabc4e..04f779c4f5ed 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
 	int rc;
 	key_perm_t perm;
 
-	rc = kernel_read_file_from_path(path, &data, 0,
+	rc = kernel_read_file_from_path(path, &data, INT_MAX,
 					READING_X509_CERTIFICATE);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 602f52717757..692b83e82edf 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -284,7 +284,7 @@ static ssize_t ima_read_policy(char *path)
 	datap = path;
 	strsep(&datap, "\n");
 
-	rc = kernel_read_file_from_path(path, &data, 0, READING_POLICY);
+	rc = kernel_read_file_from_path(path, &data, INT_MAX, READING_POLICY);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (8 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23 17:36   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook Kees Cook
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

In preparation for adding partial read support, add an optional output
argument to kernel_read_file*() that reports the file size so callers
can reason more easily about their reading progress.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/main.c |  1 +
 fs/kernel_read_file.c               | 19 +++++++++++++------
 include/linux/kernel_read_file.h    |  4 ++++
 kernel/kexec_file.c                 |  4 ++--
 kernel/module.c                     |  2 +-
 security/integrity/digsig.c         |  2 +-
 security/integrity/ima/ima_fs.c     |  2 +-
 7 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index f80c0d102be8..bd199404935f 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -495,6 +495,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 
 		/* load firmware files from the mount namespace of init */
 		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
+						       NULL,
 						       READING_FIRMWARE);
 		if (rc < 0) {
 			if (rc != -ENOENT)
diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
index e21a76001fff..2e29c38eb4df 100644
--- a/fs/kernel_read_file.c
+++ b/fs/kernel_read_file.c
@@ -14,6 +14,8 @@
  *		@buf_size will be ignored)
  * @buf_size	size of buf, if already allocated. If @buf not
  *		allocated, this is the largest size to allocate.
+ * @file_size	if non-NULL, the full size of @file will be
+ *		written here.
  * @id		the kernel_read_file_id identifying the type of
  *		file contents being read (for LSMs to examine)
  *
@@ -22,7 +24,8 @@
  *
  */
 int kernel_read_file(struct file *file, void **buf,
-		     size_t buf_size, enum kernel_read_file_id id)
+		     size_t buf_size, size_t *file_size,
+		     enum kernel_read_file_id id)
 {
 	loff_t i_size, pos;
 	ssize_t bytes = 0;
@@ -49,6 +52,8 @@ int kernel_read_file(struct file *file, void **buf,
 		ret = -EFBIG;
 		goto out;
 	}
+	if (file_size)
+		*file_size = i_size;
 
 	if (!*buf)
 		*buf = allocated = vmalloc(i_size);
@@ -91,7 +96,8 @@ int kernel_read_file(struct file *file, void **buf,
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
 int kernel_read_file_from_path(const char *path, void **buf,
-			       size_t buf_size, enum kernel_read_file_id id)
+			       size_t buf_size, size_t *file_size,
+			       enum kernel_read_file_id id)
 {
 	struct file *file;
 	int ret;
@@ -103,14 +109,14 @@ int kernel_read_file_from_path(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, buf_size, id);
+	ret = kernel_read_file(file, buf, buf_size, file_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
 int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      size_t buf_size,
+				      size_t buf_size, size_t *file_size,
 				      enum kernel_read_file_id id)
 {
 	struct file *file;
@@ -129,13 +135,14 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, buf_size, id);
+	ret = kernel_read_file(file, buf, buf_size, file_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
 
 int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
+			     size_t *file_size,
 			     enum kernel_read_file_id id)
 {
 	struct fd f = fdget(fd);
@@ -144,7 +151,7 @@ int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
 	if (!f.file)
 		goto out;
 
-	ret = kernel_read_file(f.file, buf, buf_size, id);
+	ret = kernel_read_file(f.file, buf, buf_size, file_size, id);
 out:
 	fdput(f);
 	return ret;
diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
index 910039e7593e..023293eaf948 100644
--- a/include/linux/kernel_read_file.h
+++ b/include/linux/kernel_read_file.h
@@ -37,15 +37,19 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
 
 int kernel_read_file(struct file *file,
 		     void **buf, size_t buf_size,
+		     size_t *file_size,
 		     enum kernel_read_file_id id);
 int kernel_read_file_from_path(const char *path,
 			       void **buf, size_t buf_size,
+			       size_t *file_size,
 			       enum kernel_read_file_id id);
 int kernel_read_file_from_path_initns(const char *path,
 				      void **buf, size_t buf_size,
+				      size_t *file_size,
 				      enum kernel_read_file_id id);
 int kernel_read_file_from_fd(int fd,
 			     void **buf, size_t buf_size,
+			     size_t *file_size,
 			     enum kernel_read_file_id id);
 
 #endif /* _LINUX_KERNEL_READ_FILE_H */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index eda19ca256a3..878ca684a3a1 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -222,7 +222,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	void *ldata;
 
 	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
-				       INT_MAX, READING_KEXEC_IMAGE);
+				       INT_MAX, NULL, READING_KEXEC_IMAGE);
 	if (ret < 0)
 		return ret;
 	image->kernel_buf_len = ret;
@@ -242,7 +242,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	/* It is possible that there no initramfs is being loaded */
 	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
 		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
-					       INT_MAX,
+					       INT_MAX, NULL,
 					       READING_KEXEC_INITRAMFS);
 		if (ret < 0)
 			goto out;
diff --git a/kernel/module.c b/kernel/module.c
index b6fd4f51cc30..860d713dd910 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -4001,7 +4001,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 		      |MODULE_INIT_IGNORE_VERMAGIC))
 		return -EINVAL;
 
-	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX,
+	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX, NULL,
 				       READING_MODULE);
 	if (err < 0)
 		return err;
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 04f779c4f5ed..8a523dfd7fd7 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
 	int rc;
 	key_perm_t perm;
 
-	rc = kernel_read_file_from_path(path, &data, INT_MAX,
+	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL,
 					READING_X509_CERTIFICATE);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 692b83e82edf..5fc56ccb6678 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -284,7 +284,7 @@ static ssize_t ima_read_policy(char *path)
 	datap = path;
 	strsep(&datap, "\n");
 
-	rc = kernel_read_file_from_path(path, &data, INT_MAX, READING_POLICY);
+	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL, READING_POLICY);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (9 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-23 17:39   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 12/18] firmware_loader: Use security_post_load_data() Kees Cook
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

There are a few places in the kernel where LSMs would like to have
visibility into the contents of a kernel buffer that has been loaded or
read. While security_kernel_post_read_file() (which includes the
buffer) exists as a pairing for security_kernel_read_file(), no such
hook exists to pair with security_kernel_load_data().

Earlier proposals for just using security_kernel_post_read_file() with a
NULL file argument were rejected (i.e. "file" should always be valid for
the security_..._file hooks, but it appears at least one case was
left in the kernel during earlier refactoring. (This will be fixed in
a subsequent patch.)

Since not all cases of security_kernel_load_data() can have a single
contiguous buffer made available to the LSM hook (e.g. kexec image
segments are separately loaded), there needs to be a way for the LSM to
reason about its expectations of the hook coverage. In order to handle
this, add a "contents" argument to the "kernel_load_data" hook that
indicates if the newly added "kernel_post_load_data" hook will be called
with the full contents once loaded. That way, LSMs requiring full contents
can choose to unilaterally reject "kernel_load_data" with contents=false
(which is effectively the existing hook coverage), but when contents=true
they can allow it and later evaluate the "kernel_post_load_data" hook
once the buffer is loaded.

With this change, LSMs can gain coverage over non-file-backed data loads
(e.g. init_module(2) and firmware userspace helper), which will happen
in subsequent patches.

Additionally prepare IMA to start processing these cases.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/fallback.c       |  2 +-
 .../base/firmware_loader/fallback_platform.c  |  2 +-
 include/linux/ima.h                           | 12 +++++++++--
 include/linux/lsm_hook_defs.h                 |  4 +++-
 include/linux/lsm_hooks.h                     |  9 ++++++++
 include/linux/security.h                      | 12 +++++++++--
 kernel/kexec.c                                |  2 +-
 kernel/module.c                               |  2 +-
 security/integrity/ima/ima_main.c             | 21 ++++++++++++++++++-
 security/loadpin/loadpin.c                    |  2 +-
 security/security.c                           | 18 +++++++++++++---
 security/selinux/hooks.c                      |  2 +-
 12 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 5327bfc6ba71..a196aacce22c 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -613,7 +613,7 @@ static bool fw_run_sysfs_fallback(u32 opt_flags)
 		return false;
 
 	/* Also permit LSMs and IMA to fail firmware sysfs fallback */
-	ret = security_kernel_load_data(LOADING_FIRMWARE);
+	ret = security_kernel_load_data(LOADING_FIRMWARE, false);
 	if (ret < 0)
 		return false;
 
diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
index 6958ab1a8059..a12c79d47efc 100644
--- a/drivers/base/firmware_loader/fallback_platform.c
+++ b/drivers/base/firmware_loader/fallback_platform.c
@@ -17,7 +17,7 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
 	if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
 		return -ENOENT;
 
-	rc = security_kernel_load_data(LOADING_FIRMWARE);
+	rc = security_kernel_load_data(LOADING_FIRMWARE, false);
 	if (rc)
 		return rc;
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 148636bfcc8f..502e36ad7804 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -20,7 +20,9 @@ extern void ima_post_create_tmpfile(struct inode *inode);
 extern void ima_file_free(struct file *file);
 extern int ima_file_mmap(struct file *file, unsigned long prot);
 extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
-extern int ima_load_data(enum kernel_load_data_id id);
+extern int ima_load_data(enum kernel_load_data_id id, bool contents);
+extern int ima_post_load_data(char *buf, loff_t size,
+			      enum kernel_load_data_id id);
 extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
@@ -78,7 +80,13 @@ static inline int ima_file_mprotect(struct vm_area_struct *vma,
 	return 0;
 }
 
-static inline int ima_load_data(enum kernel_load_data_id id)
+static inline int ima_load_data(enum kernel_load_data_id id, bool contents)
+{
+	return 0;
+}
+
+static inline int ima_post_load_data(char *buf, loff_t size,
+				     enum kernel_load_data_id id)
 {
 	return 0;
 }
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 6791813cd439..aaa2916bbae7 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -184,7 +184,9 @@ LSM_HOOK(void, LSM_RET_VOID, cred_getsecid, const struct cred *c, u32 *secid)
 LSM_HOOK(int, 0, kernel_act_as, struct cred *new, u32 secid)
 LSM_HOOK(int, 0, kernel_create_files_as, struct cred *new, struct inode *inode)
 LSM_HOOK(int, 0, kernel_module_request, char *kmod_name)
-LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id)
+LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id, bool contents)
+LSM_HOOK(int, 0, kernel_post_load_data, char *buf, loff_t size,
+	 enum kernel_read_file_id id)
 LSM_HOOK(int, 0, kernel_read_file, struct file *file,
 	 enum kernel_read_file_id id)
 LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf,
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 95b7c1d32062..812d626195fc 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -635,7 +635,16 @@
  * @kernel_load_data:
  *	Load data provided by userspace.
  *	@id kernel load data identifier
+ *	@contents if a subsequent @kernel_post_load_data will be called.
  *	Return 0 if permission is granted.
+ * @kernel_post_load_data:
+ *	Load data provided by a non-file source (usually userspace buffer).
+ *	@buf pointer to buffer containing the data contents.
+ *	@size length of the data contents.
+ *	@id kernel load data identifier
+ *	Return 0 if permission is granted.
+ *	This must be paired with a prior @kernel_load_data call that had
+ *	@contents set to true.
  * @kernel_read_file:
  *	Read a file specified by userspace.
  *	@file contains the file structure pointing to the file being read
diff --git a/include/linux/security.h b/include/linux/security.h
index 42df0d9b4c37..e748974c707b 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -387,7 +387,9 @@ void security_cred_getsecid(const struct cred *c, u32 *secid);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_module_request(char *kmod_name);
-int security_kernel_load_data(enum kernel_load_data_id id);
+int security_kernel_load_data(enum kernel_load_data_id id, bool contents);
+int security_kernel_post_load_data(char *buf, loff_t size,
+				   enum kernel_load_data_id id);
 int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id);
@@ -1014,7 +1016,13 @@ static inline int security_kernel_module_request(char *kmod_name)
 	return 0;
 }
 
-static inline int security_kernel_load_data(enum kernel_load_data_id id)
+static inline int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
+{
+	return 0;
+}
+
+static inline int security_kernel_post_load_data(char *buf, loff_t size,
+						 enum kernel_load_data_id id)
 {
 	return 0;
 }
diff --git a/kernel/kexec.c b/kernel/kexec.c
index f977786fe498..c82c6c06f051 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -205,7 +205,7 @@ static inline int kexec_load_check(unsigned long nr_segments,
 		return -EPERM;
 
 	/* Permit LSMs and IMA to fail the kexec */
-	result = security_kernel_load_data(LOADING_KEXEC_IMAGE);
+	result = security_kernel_load_data(LOADING_KEXEC_IMAGE, false);
 	if (result < 0)
 		return result;
 
diff --git a/kernel/module.c b/kernel/module.c
index 860d713dd910..d56cb34d9a2f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2967,7 +2967,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 	if (info->len < sizeof(*(info->hdr)))
 		return -ENOEXEC;
 
-	err = security_kernel_load_data(LOADING_MODULE);
+	err = security_kernel_load_data(LOADING_MODULE, false);
 	if (err)
 		return err;
 
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index dab4a13221cf..85000dc8595c 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -676,6 +676,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 /**
  * ima_load_data - appraise decision based on policy
  * @id: kernel load data caller identifier
+ * @contents: whether the full contents will be available in a later
+ *	      call to ima_post_load_data().
  *
  * Callers of this LSM hook can not measure, appraise, or audit the
  * data provided by userspace.  Enforce policy rules requring a file
@@ -683,7 +685,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
  *
  * For permission return 0, otherwise return -EACCES.
  */
-int ima_load_data(enum kernel_load_data_id id)
+int ima_load_data(enum kernel_load_data_id id, bool contents)
 {
 	bool ima_enforce, sig_enforce;
 
@@ -723,6 +725,23 @@ int ima_load_data(enum kernel_load_data_id id)
 	return 0;
 }
 
+/**
+ * ima_post_load_data - appraise decision based on policy
+ * @buf: pointer to in memory file contents
+ * @size: size of in memory file contents
+ * @id: kernel load data caller identifier
+ *
+ * Measure/appraise/audit in memory buffer based on policy.  Policy rules
+ * are written in terms of a policy identifier.
+ *
+ * On success return 0.  On integrity appraisal error, assuming the file
+ * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
+ */
+int ima_post_load_data(char *buf, loff_t size, enum kernel_load_data_id load_id)
+{
+	return 0;
+}
+
 /*
  * process_buffer_measurement - Measure the buffer to ima log.
  * @buf: pointer to the buffer that needs to be added to the log.
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index 81bc95127f92..db320a43f42e 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -176,7 +176,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
 	return 0;
 }
 
-static int loadpin_load_data(enum kernel_load_data_id id)
+static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
 {
 	return loadpin_read_file(NULL, (enum kernel_read_file_id) id);
 }
diff --git a/security/security.c b/security/security.c
index f5920115a325..090674f1197a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1680,17 +1680,29 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 }
 EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
 
-int security_kernel_load_data(enum kernel_load_data_id id)
+int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
 {
 	int ret;
 
-	ret = call_int_hook(kernel_load_data, 0, id);
+	ret = call_int_hook(kernel_load_data, 0, id, contents);
 	if (ret)
 		return ret;
-	return ima_load_data(id);
+	return ima_load_data(id, contents);
 }
 EXPORT_SYMBOL_GPL(security_kernel_load_data);
 
+int security_kernel_post_load_data(char *buf, loff_t size,
+				   enum kernel_load_data_id id)
+{
+	int ret;
+
+	ret = call_int_hook(kernel_post_load_data, 0, buf, size, id);
+	if (ret)
+		return ret;
+	return ima_post_load_data(buf, size, id);
+}
+EXPORT_SYMBOL_GPL(security_kernel_post_load_data);
+
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
 			     int flags)
 {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5de45010fb1a..1a5c68196faf 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4019,7 +4019,7 @@ static int selinux_kernel_read_file(struct file *file,
 	return rc;
 }
 
-static int selinux_kernel_load_data(enum kernel_load_data_id id)
+static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
 {
 	int rc = 0;
 
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 12/18] firmware_loader: Use security_post_load_data()
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (10 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 13/18] module: Call security_kernel_post_load_data() Kees Cook
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

Now that security_post_load_data() is wired up, use it instead
of the NULL file argument style of security_post_read_file(),
and update the security_kernel_load_data() call to indicate that a
security_kernel_post_load_data() call is expected.

Wire up the IMA check to match earlier logic. Perhaps a generalized
change to ima_post_load_data() might look something like this:

    return process_buffer_measurement(buf, size,
                                      kernel_load_data_id_str(load_id),
                                      read_idmap[load_id] ?: FILE_CHECK,
                                      0, NULL);

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/fallback.c       |  8 ++++----
 .../base/firmware_loader/fallback_platform.c  |  7 ++++++-
 security/integrity/ima/ima_main.c             | 20 +++++++++----------
 3 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index a196aacce22c..7cfdfdcb819c 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -272,9 +272,9 @@ static ssize_t firmware_loading_store(struct device *dev,
 				dev_err(dev, "%s: map pages failed\n",
 					__func__);
 			else
-				rc = security_kernel_post_read_file(NULL,
-						fw_priv->data, fw_priv->size,
-						READING_FIRMWARE);
+				rc = security_kernel_post_load_data(fw_priv->data,
+						fw_priv->size,
+						LOADING_FIRMWARE);
 
 			/*
 			 * Same logic as fw_load_abort, only the DONE bit
@@ -613,7 +613,7 @@ static bool fw_run_sysfs_fallback(u32 opt_flags)
 		return false;
 
 	/* Also permit LSMs and IMA to fail firmware sysfs fallback */
-	ret = security_kernel_load_data(LOADING_FIRMWARE, false);
+	ret = security_kernel_load_data(LOADING_FIRMWARE, true);
 	if (ret < 0)
 		return false;
 
diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
index a12c79d47efc..4d1157af0e86 100644
--- a/drivers/base/firmware_loader/fallback_platform.c
+++ b/drivers/base/firmware_loader/fallback_platform.c
@@ -17,7 +17,7 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
 	if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
 		return -ENOENT;
 
-	rc = security_kernel_load_data(LOADING_FIRMWARE, false);
+	rc = security_kernel_load_data(LOADING_FIRMWARE, true);
 	if (rc)
 		return rc;
 
@@ -27,6 +27,11 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
 
 	if (fw_priv->data && size > fw_priv->allocated_size)
 		return -ENOMEM;
+
+	rc = security_kernel_post_load_data((u8 *)data, size, LOADING_FIRMWARE);
+	if (rc)
+		return rc;
+
 	if (!fw_priv->data)
 		fw_priv->data = vmalloc(size);
 	if (!fw_priv->data)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 85000dc8595c..1a7bc4c7437d 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -648,15 +648,6 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
 	enum ima_hooks func;
 	u32 secid;
 
-	if (!file && read_id == READING_FIRMWARE) {
-		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
-		    (ima_appraise & IMA_APPRAISE_ENFORCE)) {
-			pr_err("Prevent firmware loading_store.\n");
-			return -EACCES;	/* INTEGRITY_UNKNOWN */
-		}
-		return 0;
-	}
-
 	/* permit signed certs */
 	if (!file && read_id == READING_X509_CERTIFICATE)
 		return 0;
@@ -706,7 +697,7 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
 		}
 		break;
 	case LOADING_FIRMWARE:
-		if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE)) {
+		if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE) && !contents) {
 			pr_err("Prevent firmware sysfs fallback loading.\n");
 			return -EACCES;	/* INTEGRITY_UNKNOWN */
 		}
@@ -739,6 +730,15 @@ int ima_load_data(enum kernel_load_data_id id, bool contents)
  */
 int ima_post_load_data(char *buf, loff_t size, enum kernel_load_data_id load_id)
 {
+	if (load_id == LOADING_FIRMWARE) {
+		if ((ima_appraise & IMA_APPRAISE_FIRMWARE) &&
+		    (ima_appraise & IMA_APPRAISE_ENFORCE)) {
+			pr_err("Prevent firmware loading_store.\n");
+			return -EACCES; /* INTEGRITY_UNKNOWN */
+		}
+		return 0;
+	}
+
 	return 0;
 }
 
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 13/18] module: Call security_kernel_post_load_data()
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (11 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 12/18] firmware_loader: Use security_post_load_data() Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 14/18] LSM: Add "contents" flag to kernel_read_file hook Kees Cook
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

Now that there is an API for checking loaded contents for modules
loaded without a file, call into the LSM hooks.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/module.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/kernel/module.c b/kernel/module.c
index d56cb34d9a2f..90a4788dff9d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2967,7 +2967,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 	if (info->len < sizeof(*(info->hdr)))
 		return -ENOEXEC;
 
-	err = security_kernel_load_data(LOADING_MODULE, false);
+	err = security_kernel_load_data(LOADING_MODULE, true);
 	if (err)
 		return err;
 
@@ -2977,11 +2977,17 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 		return -ENOMEM;
 
 	if (copy_chunked_from_user(info->hdr, umod, info->len) != 0) {
-		vfree(info->hdr);
-		return -EFAULT;
+		err = -EFAULT;
+		goto out;
 	}
 
-	return 0;
+	err = security_kernel_post_load_data((char *)info->hdr, info->len,
+					     LOADING_MODULE);
+out:
+	if (err)
+		vfree(info->hdr);
+
+	return err;
 }
 
 static void free_copy(struct load_info *info)
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 14/18] LSM: Add "contents" flag to kernel_read_file hook
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (12 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 13/18] module: Call security_kernel_post_load_data() Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads Kees Cook
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

As with the kernel_load_data LSM hook, add a "contents" flag to the
kernel_read_file LSM hook that indicates whether the LSM can expect
a matching call to the kernel_post_read_file LSM hook with the full
contents of the file. With the coming addition of partial file read
support for kernel_read_file*() API, the LSM will no longer be able
to always see the entire contents of a file during the read calls.

For cases where the LSM must read examine the complete file contents,
it will need to do so on its own every time the kernel_read_file
hook is called with contents=false (or reject such cases). Adjust all
existing LSMs to retain existing behavior.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/kernel_read_file.c             |  2 +-
 include/linux/ima.h               |  6 ++++--
 include/linux/lsm_hook_defs.h     |  2 +-
 include/linux/lsm_hooks.h         |  3 +++
 include/linux/security.h          |  6 ++++--
 security/integrity/ima/ima_main.c | 10 +++++++++-
 security/loadpin/loadpin.c        | 14 ++++++++++++--
 security/security.c               |  7 ++++---
 security/selinux/hooks.c          |  5 +++--
 9 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
index 2e29c38eb4df..d73bc3fa710a 100644
--- a/fs/kernel_read_file.c
+++ b/fs/kernel_read_file.c
@@ -39,7 +39,7 @@ int kernel_read_file(struct file *file, void **buf,
 	if (ret)
 		return ret;
 
-	ret = security_kernel_read_file(file, id);
+	ret = security_kernel_read_file(file, id, true);
 	if (ret)
 		goto out;
 
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 502e36ad7804..259023039dc9 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -23,7 +23,8 @@ extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
 extern int ima_load_data(enum kernel_load_data_id id, bool contents);
 extern int ima_post_load_data(char *buf, loff_t size,
 			      enum kernel_load_data_id id);
-extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
+extern int ima_read_file(struct file *file, enum kernel_read_file_id id,
+			 bool contents);
 extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
 			      enum kernel_read_file_id id);
 extern void ima_post_path_mknod(struct dentry *dentry);
@@ -91,7 +92,8 @@ static inline int ima_post_load_data(char *buf, loff_t size,
 	return 0;
 }
 
-static inline int ima_read_file(struct file *file, enum kernel_read_file_id id)
+static inline int ima_read_file(struct file *file, enum kernel_read_file_id id,
+				bool contents)
 {
 	return 0;
 }
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index aaa2916bbae7..c2ded57c5d9b 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -188,7 +188,7 @@ LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id, bool contents)
 LSM_HOOK(int, 0, kernel_post_load_data, char *buf, loff_t size,
 	 enum kernel_read_file_id id)
 LSM_HOOK(int, 0, kernel_read_file, struct file *file,
-	 enum kernel_read_file_id id)
+	 enum kernel_read_file_id id, bool contents)
 LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf,
 	 loff_t size, enum kernel_read_file_id id)
 LSM_HOOK(int, 0, task_fix_setuid, struct cred *new, const struct cred *old,
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 812d626195fc..b66433b5aa15 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -650,6 +650,7 @@
  *	@file contains the file structure pointing to the file being read
  *	by the kernel.
  *	@id kernel read file identifier
+ *	@contents if a subsequent @kernel_post_read_file will be called.
  *	Return 0 if permission is granted.
  * @kernel_post_read_file:
  *	Read a file specified by userspace.
@@ -658,6 +659,8 @@
  *	@buf pointer to buffer containing the file contents.
  *	@size length of the file contents.
  *	@id kernel read file identifier
+ *	This must be paired with a prior @kernel_read_file call that had
+ *	@contents set to true.
  *	Return 0 if permission is granted.
  * @task_fix_setuid:
  *	Update the module's state after setting one or more of the user
diff --git a/include/linux/security.h b/include/linux/security.h
index e748974c707b..a5d66b89cd6c 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -390,7 +390,8 @@ int security_kernel_module_request(char *kmod_name);
 int security_kernel_load_data(enum kernel_load_data_id id, bool contents);
 int security_kernel_post_load_data(char *buf, loff_t size,
 				   enum kernel_load_data_id id);
-int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
+int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
+			      bool contents);
 int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
 				   enum kernel_read_file_id id);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
@@ -1028,7 +1029,8 @@ static inline int security_kernel_post_load_data(char *buf, loff_t size,
 }
 
 static inline int security_kernel_read_file(struct file *file,
-					    enum kernel_read_file_id id)
+					    enum kernel_read_file_id id,
+					    bool contents)
 {
 	return 0;
 }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1a7bc4c7437d..dc4f90660aa6 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -602,6 +602,7 @@ void ima_post_path_mknod(struct dentry *dentry)
  * ima_read_file - pre-measure/appraise hook decision based on policy
  * @file: pointer to the file to be measured/appraised/audit
  * @read_id: caller identifier
+ * @contents: whether a subsequent call will be made to ima_post_read_file()
  *
  * Permit reading a file based on policy. The policy rules are written
  * in terms of the policy identifier.  Appraising the integrity of
@@ -609,8 +610,15 @@ void ima_post_path_mknod(struct dentry *dentry)
  *
  * For permission return 0, otherwise return -EACCES.
  */
-int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
+int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
+		  bool contents)
 {
+	/* Reject all partial reads during appraisal. */
+	if (!contents) {
+		if (ima_appraise & IMA_APPRAISE_ENFORCE)
+			return -EACCES;
+	}
+
 	/*
 	 * Do devices using pre-allocated memory run the risk of the
 	 * firmware being accessible to the device prior to the completion
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index db320a43f42e..a1778ebef137 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -117,11 +117,21 @@ static void loadpin_sb_free_security(struct super_block *mnt_sb)
 	}
 }
 
-static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
+static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+			     bool contents)
 {
 	struct super_block *load_root;
 	const char *origin = kernel_read_file_id_str(id);
 
+	/*
+	 * If we will not know that we'll be seeing the full contents
+	 * then we cannot trust a load will be complete and unchanged
+	 * off disk. Treat all contents=false hooks as if there were
+	 * no associated file struct.
+	 */
+	if (!contents)
+		file = NULL;
+
 	/* If the file id is excluded, ignore the pinning. */
 	if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) &&
 	    ignore_read_file_id[id]) {
@@ -178,7 +188,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
 
 static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
 {
-	return loadpin_read_file(NULL, (enum kernel_read_file_id) id);
+	return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents);
 }
 
 static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
diff --git a/security/security.c b/security/security.c
index 090674f1197a..800af5403176 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1657,14 +1657,15 @@ int security_kernel_module_request(char *kmod_name)
 	return integrity_kernel_module_request(kmod_name);
 }
 
-int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
+int security_kernel_read_file(struct file *file, enum kernel_read_file_id id,
+			      bool contents)
 {
 	int ret;
 
-	ret = call_int_hook(kernel_read_file, 0, file, id);
+	ret = call_int_hook(kernel_read_file, 0, file, id, contents);
 	if (ret)
 		return ret;
-	return ima_read_file(file, id);
+	return ima_read_file(file, id, contents);
 }
 EXPORT_SYMBOL_GPL(security_kernel_read_file);
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1a5c68196faf..6d183bbc12a6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4004,13 +4004,14 @@ static int selinux_kernel_module_from_file(struct file *file)
 }
 
 static int selinux_kernel_read_file(struct file *file,
-				    enum kernel_read_file_id id)
+				    enum kernel_read_file_id id,
+				    bool contents)
 {
 	int rc = 0;
 
 	switch (id) {
 	case READING_MODULE:
-		rc = selinux_kernel_module_from_file(file);
+		rc = selinux_kernel_module_from_file(contents ? file : NULL);
 		break;
 	default:
 		break;
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (13 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 14/18] LSM: Add "contents" flag to kernel_read_file hook Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 22:29   ` Scott Branden
  2020-07-22 19:30 ` [PATCH v2 16/18] firmware: Store opt_flags in fw_priv Kees Cook
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

To perform partial reads, callers of kernel_read_file*() must have a
non-NULL file_size argument and a preallocated buffer. The new "offset"
argument can then be used to seek to specific locations in the file to
fill the buffer to, at most, "buf_size" per call.

Where possible, the LSM hooks can report whether a full file has been
read or not so that the contents can be reasoned about.

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/main.c |  2 +-
 fs/kernel_read_file.c               | 78 ++++++++++++++++++++---------
 include/linux/kernel_read_file.h    |  8 +--
 kernel/kexec_file.c                 |  4 +-
 kernel/module.c                     |  2 +-
 security/integrity/digsig.c         |  2 +-
 security/integrity/ima/ima_fs.c     |  3 +-
 7 files changed, 65 insertions(+), 34 deletions(-)

diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index bd199404935f..d95249b5284e 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -494,7 +494,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 		fw_priv->size = 0;
 
 		/* load firmware files from the mount namespace of init */
-		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
+		rc = kernel_read_file_from_path_initns(path, 0, &buffer, msize,
 						       NULL,
 						       READING_FIRMWARE);
 		if (rc < 0) {
diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
index d73bc3fa710a..90d255fbdd9b 100644
--- a/fs/kernel_read_file.c
+++ b/fs/kernel_read_file.c
@@ -9,6 +9,7 @@
  * kernel_read_file() - read file contents into a kernel buffer
  *
  * @file	file to read from
+ * @offset	where to start reading from (see below).
  * @buf		pointer to a "void *" buffer for reading into (if
  *		*@buf is NULL, a buffer will be allocated, and
  *		@buf_size will be ignored)
@@ -19,19 +20,31 @@
  * @id		the kernel_read_file_id identifying the type of
  *		file contents being read (for LSMs to examine)
  *
+ * @offset must be 0 unless both @buf and @file_size are non-NULL
+ * (i.e. the caller must be expecting to read partial file contents
+ * via an already-allocated @buf, in at most @buf_size chunks, and
+ * will be able to determine when the entire file was read by
+ * checking @file_size). This isn't a recommended way to read a
+ * file, though, since it is possible that the contents might
+ * change between calls to kernel_read_file().
+ *
  * Returns number of bytes read (no single read will be bigger
  * than INT_MAX), or negative on error.
  *
  */
-int kernel_read_file(struct file *file, void **buf,
+int kernel_read_file(struct file *file, loff_t offset, void **buf,
 		     size_t buf_size, size_t *file_size,
 		     enum kernel_read_file_id id)
 {
 	loff_t i_size, pos;
-	ssize_t bytes = 0;
+	size_t copied;
 	void *allocated = NULL;
+	bool whole_file;
 	int ret;
 
+	if (offset != 0 && (!*buf || !file_size))
+		return -EINVAL;
+
 	if (!S_ISREG(file_inode(file)->i_mode))
 		return -EINVAL;
 
@@ -39,19 +52,27 @@ int kernel_read_file(struct file *file, void **buf,
 	if (ret)
 		return ret;
 
-	ret = security_kernel_read_file(file, id, true);
-	if (ret)
-		goto out;
-
 	i_size = i_size_read(file_inode(file));
 	if (i_size <= 0) {
 		ret = -EINVAL;
 		goto out;
 	}
-	if (i_size > INT_MAX || i_size > buf_size) {
+	/* The file is too big for sane activities. */
+	if (i_size > INT_MAX) {
+		ret = -EFBIG;
+		goto out;
+	}
+	/* The entire file cannot be read in one buffer. */
+	if (!file_size && offset == 0 && i_size > buf_size) {
 		ret = -EFBIG;
 		goto out;
 	}
+
+	whole_file = (offset == 0 && i_size <= buf_size);
+	ret = security_kernel_read_file(file, id, whole_file);
+	if (ret)
+		goto out;
+
 	if (file_size)
 		*file_size = i_size;
 
@@ -62,9 +83,14 @@ int kernel_read_file(struct file *file, void **buf,
 		goto out;
 	}
 
-	pos = 0;
-	while (pos < i_size) {
-		bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
+	pos = offset;
+	copied = 0;
+	while (copied < buf_size) {
+		ssize_t bytes;
+		size_t wanted = min_t(size_t, buf_size - copied,
+					      i_size - pos);
+
+		bytes = kernel_read(file, *buf + copied, wanted, &pos);
 		if (bytes < 0) {
 			ret = bytes;
 			goto out_free;
@@ -72,14 +98,17 @@ int kernel_read_file(struct file *file, void **buf,
 
 		if (bytes == 0)
 			break;
+		copied += bytes;
 	}
 
-	if (pos != i_size) {
-		ret = -EIO;
-		goto out_free;
-	}
+	if (whole_file) {
+		if (pos != i_size) {
+			ret = -EIO;
+			goto out_free;
+		}
 
-	ret = security_kernel_post_read_file(file, *buf, i_size, id);
+		ret = security_kernel_post_read_file(file, *buf, i_size, id);
+	}
 
 out_free:
 	if (ret < 0) {
@@ -91,11 +120,11 @@ int kernel_read_file(struct file *file, void **buf,
 
 out:
 	allow_write_access(file);
-	return ret == 0 ? pos : ret;
+	return ret == 0 ? copied : ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file);
 
-int kernel_read_file_from_path(const char *path, void **buf,
+int kernel_read_file_from_path(const char *path, loff_t offset, void **buf,
 			       size_t buf_size, size_t *file_size,
 			       enum kernel_read_file_id id)
 {
@@ -109,14 +138,15 @@ int kernel_read_file_from_path(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, buf_size, file_size, id);
+	ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
 
-int kernel_read_file_from_path_initns(const char *path, void **buf,
-				      size_t buf_size, size_t *file_size,
+int kernel_read_file_from_path_initns(const char *path, loff_t offset,
+				      void **buf, size_t buf_size,
+				      size_t *file_size,
 				      enum kernel_read_file_id id)
 {
 	struct file *file;
@@ -135,14 +165,14 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
-	ret = kernel_read_file(file, buf, buf_size, file_size, id);
+	ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
 	fput(file);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
 
-int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
-			     size_t *file_size,
+int kernel_read_file_from_fd(int fd, loff_t offset, void **buf,
+			     size_t buf_size, size_t *file_size,
 			     enum kernel_read_file_id id)
 {
 	struct fd f = fdget(fd);
@@ -151,7 +181,7 @@ int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
 	if (!f.file)
 		goto out;
 
-	ret = kernel_read_file(f.file, buf, buf_size, file_size, id);
+	ret = kernel_read_file(f.file, offset, buf, buf_size, file_size, id);
 out:
 	fdput(f);
 	return ret;
diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
index 023293eaf948..575ffa1031d3 100644
--- a/include/linux/kernel_read_file.h
+++ b/include/linux/kernel_read_file.h
@@ -35,19 +35,19 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
 	return kernel_read_file_str[id];
 }
 
-int kernel_read_file(struct file *file,
+int kernel_read_file(struct file *file, loff_t offset,
 		     void **buf, size_t buf_size,
 		     size_t *file_size,
 		     enum kernel_read_file_id id);
-int kernel_read_file_from_path(const char *path,
+int kernel_read_file_from_path(const char *path, loff_t offset,
 			       void **buf, size_t buf_size,
 			       size_t *file_size,
 			       enum kernel_read_file_id id);
-int kernel_read_file_from_path_initns(const char *path,
+int kernel_read_file_from_path_initns(const char *path, loff_t offset,
 				      void **buf, size_t buf_size,
 				      size_t *file_size,
 				      enum kernel_read_file_id id);
-int kernel_read_file_from_fd(int fd,
+int kernel_read_file_from_fd(int fd, loff_t offset,
 			     void **buf, size_t buf_size,
 			     size_t *file_size,
 			     enum kernel_read_file_id id);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 878ca684a3a1..45726bc8f6ce 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -221,7 +221,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	int ret;
 	void *ldata;
 
-	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
+	ret = kernel_read_file_from_fd(kernel_fd, 0, &image->kernel_buf,
 				       INT_MAX, NULL, READING_KEXEC_IMAGE);
 	if (ret < 0)
 		return ret;
@@ -241,7 +241,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 #endif
 	/* It is possible that there no initramfs is being loaded */
 	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
-		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
+		ret = kernel_read_file_from_fd(initrd_fd, 0, &image->initrd_buf,
 					       INT_MAX, NULL,
 					       READING_KEXEC_INITRAMFS);
 		if (ret < 0)
diff --git a/kernel/module.c b/kernel/module.c
index 90a4788dff9d..d353d1f67681 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -4007,7 +4007,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
 		      |MODULE_INIT_IGNORE_VERMAGIC))
 		return -EINVAL;
 
-	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX, NULL,
+	err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL,
 				       READING_MODULE);
 	if (err < 0)
 		return err;
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8a523dfd7fd7..0f518dcfde05 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
 	int rc;
 	key_perm_t perm;
 
-	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL,
+	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
 					READING_X509_CERTIFICATE);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 5fc56ccb6678..ea8ff8a07b36 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -284,7 +284,8 @@ static ssize_t ima_read_policy(char *path)
 	datap = path;
 	strsep(&datap, "\n");
 
-	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL, READING_POLICY);
+	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
+					READING_POLICY);
 	if (rc < 0) {
 		pr_err("Unable to open file: %s (%d)", path, rc);
 		return rc;
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 16/18] firmware: Store opt_flags in fw_priv
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (14 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 17/18] firmware: Add request_partial_firmware_into_buf() Kees Cook
  2020-07-22 19:30 ` [PATCH v2 18/18] test_firmware: Test partial read support Kees Cook
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

Instead of passing opt_flags around so much, store it in the private
structure so it can be examined by internals without needing to add more
arguments to functions.

Co-developed-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/fallback.c       | 11 +++-----
 drivers/base/firmware_loader/fallback.h       |  5 ++--
 .../base/firmware_loader/fallback_platform.c  |  4 +--
 drivers/base/firmware_loader/firmware.h       |  3 ++-
 drivers/base/firmware_loader/main.c           | 25 +++++++++++--------
 5 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index 7cfdfdcb819c..0a94c8739959 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -490,13 +490,11 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
 /**
  * fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism
  * @fw_sysfs: firmware sysfs information for the firmware to load
- * @opt_flags: flags of options, FW_OPT_*
  * @timeout: timeout to wait for the load
  *
  * In charge of constructing a sysfs fallback interface for firmware loading.
  **/
-static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
-				  u32 opt_flags, long timeout)
+static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
 {
 	int retval = 0;
 	struct device *f_dev = &fw_sysfs->dev;
@@ -518,7 +516,7 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
 	list_add(&fw_priv->pending_list, &pending_fw_head);
 	mutex_unlock(&fw_lock);
 
-	if (opt_flags & FW_OPT_UEVENT) {
+	if (fw_priv->opt_flags & FW_OPT_UEVENT) {
 		fw_priv->need_uevent = true;
 		dev_set_uevent_suppress(f_dev, false);
 		dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name);
@@ -580,10 +578,10 @@ static int fw_load_from_user_helper(struct firmware *firmware,
 	}
 
 	fw_sysfs->fw_priv = firmware->priv;
-	ret = fw_load_sysfs_fallback(fw_sysfs, opt_flags, timeout);
+	ret = fw_load_sysfs_fallback(fw_sysfs, timeout);
 
 	if (!ret)
-		ret = assign_fw(firmware, device, opt_flags);
+		ret = assign_fw(firmware, device);
 
 out_unlock:
 	usermodehelper_read_unlock();
@@ -625,7 +623,6 @@ static bool fw_run_sysfs_fallback(u32 opt_flags)
  * @fw: pointer to firmware image
  * @name: name of firmware file to look for
  * @device: device for which firmware is being loaded
- * @opt_flags: options to control firmware loading behaviour
  * @ret: return value from direct lookup which triggered the fallback mechanism
  *
  * This function is called if direct lookup for the firmware failed, it enables
diff --git a/drivers/base/firmware_loader/fallback.h b/drivers/base/firmware_loader/fallback.h
index 2afdb6adb23f..3af7205b302f 100644
--- a/drivers/base/firmware_loader/fallback.h
+++ b/drivers/base/firmware_loader/fallback.h
@@ -67,10 +67,9 @@ static inline void unregister_sysfs_loader(void)
 #endif /* CONFIG_FW_LOADER_USER_HELPER */
 
 #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
-int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags);
+int firmware_fallback_platform(struct fw_priv *fw_priv);
 #else
-static inline int firmware_fallback_platform(struct fw_priv *fw_priv,
-					     u32 opt_flags)
+static inline int firmware_fallback_platform(struct fw_priv *fw_priv)
 {
 	return -ENOENT;
 }
diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
index 4d1157af0e86..38de68d7e973 100644
--- a/drivers/base/firmware_loader/fallback_platform.c
+++ b/drivers/base/firmware_loader/fallback_platform.c
@@ -8,13 +8,13 @@
 #include "fallback.h"
 #include "firmware.h"
 
-int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
+int firmware_fallback_platform(struct fw_priv *fw_priv)
 {
 	const u8 *data;
 	size_t size;
 	int rc;
 
-	if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
+	if (!(fw_priv->opt_flags & FW_OPT_FALLBACK_PLATFORM))
 		return -ENOENT;
 
 	rc = security_kernel_load_data(LOADING_FIRMWARE, true);
diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h
index 933e2192fbe8..7ad5fe52bc72 100644
--- a/drivers/base/firmware_loader/firmware.h
+++ b/drivers/base/firmware_loader/firmware.h
@@ -68,6 +68,7 @@ struct fw_priv {
 	void *data;
 	size_t size;
 	size_t allocated_size;
+	u32 opt_flags;
 #ifdef CONFIG_FW_LOADER_PAGED_BUF
 	bool is_paged_buf;
 	struct page **pages;
@@ -136,7 +137,7 @@ static inline void fw_state_done(struct fw_priv *fw_priv)
 	__fw_state_set(fw_priv, FW_STATUS_DONE);
 }
 
-int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags);
+int assign_fw(struct firmware *fw, struct device *device);
 
 #ifdef CONFIG_FW_LOADER_PAGED_BUF
 void fw_free_paged_buf(struct fw_priv *fw_priv);
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index d95249b5284e..814a18cc51bd 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -168,7 +168,9 @@ static int fw_cache_piggyback_on_request(const char *name);
 
 static struct fw_priv *__allocate_fw_priv(const char *fw_name,
 					  struct firmware_cache *fwc,
-					  void *dbuf, size_t size)
+					  void *dbuf,
+					  size_t size,
+					  u32 opt_flags)
 {
 	struct fw_priv *fw_priv;
 
@@ -186,6 +188,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
 	fw_priv->fwc = fwc;
 	fw_priv->data = dbuf;
 	fw_priv->allocated_size = size;
+	fw_priv->opt_flags = opt_flags;
 	fw_state_init(fw_priv);
 #ifdef CONFIG_FW_LOADER_USER_HELPER
 	INIT_LIST_HEAD(&fw_priv->pending_list);
@@ -210,8 +213,10 @@ static struct fw_priv *__lookup_fw_priv(const char *fw_name)
 /* Returns 1 for batching firmware requests with the same name */
 static int alloc_lookup_fw_priv(const char *fw_name,
 				struct firmware_cache *fwc,
-				struct fw_priv **fw_priv, void *dbuf,
-				size_t size, u32 opt_flags)
+				struct fw_priv **fw_priv,
+				void *dbuf,
+				size_t size,
+				u32 opt_flags)
 {
 	struct fw_priv *tmp;
 
@@ -227,7 +232,7 @@ static int alloc_lookup_fw_priv(const char *fw_name,
 		}
 	}
 
-	tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size);
+	tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size, opt_flags);
 	if (tmp) {
 		INIT_LIST_HEAD(&tmp->list);
 		if (!(opt_flags & FW_OPT_NOCACHE))
@@ -635,7 +640,7 @@ static int fw_add_devm_name(struct device *dev, const char *name)
 }
 #endif
 
-int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
+int assign_fw(struct firmware *fw, struct device *device)
 {
 	struct fw_priv *fw_priv = fw->priv;
 	int ret;
@@ -654,8 +659,8 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
 	 * should be fixed in devres or driver core.
 	 */
 	/* don't cache firmware handled without uevent */
-	if (device && (opt_flags & FW_OPT_UEVENT) &&
-	    !(opt_flags & FW_OPT_NOCACHE)) {
+	if (device && (fw_priv->opt_flags & FW_OPT_UEVENT) &&
+	    !(fw_priv->opt_flags & FW_OPT_NOCACHE)) {
 		ret = fw_add_devm_name(device, fw_priv->fw_name);
 		if (ret) {
 			mutex_unlock(&fw_lock);
@@ -667,7 +672,7 @@ int assign_fw(struct firmware *fw, struct device *device, u32 opt_flags)
 	 * After caching firmware image is started, let it piggyback
 	 * on request firmware.
 	 */
-	if (!(opt_flags & FW_OPT_NOCACHE) &&
+	if (!(fw_priv->opt_flags & FW_OPT_NOCACHE) &&
 	    fw_priv->fwc->state == FW_LOADER_START_CACHE) {
 		if (fw_cache_piggyback_on_request(fw_priv->fw_name))
 			kref_get(&fw_priv->ref);
@@ -778,7 +783,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 #endif
 
 	if (ret == -ENOENT)
-		ret = firmware_fallback_platform(fw->priv, opt_flags);
+		ret = firmware_fallback_platform(fw->priv);
 
 	if (ret) {
 		if (!(opt_flags & FW_OPT_NO_WARN))
@@ -787,7 +792,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 				 name, ret);
 		ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
 	} else
-		ret = assign_fw(fw, device, opt_flags);
+		ret = assign_fw(fw, device);
 
  out:
 	if (ret < 0) {
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 17/18] firmware: Add request_partial_firmware_into_buf()
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (15 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 16/18] firmware: Store opt_flags in fw_priv Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  2020-07-22 19:30 ` [PATCH v2 18/18] test_firmware: Test partial read support Kees Cook
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

From: Scott Branden <scott.branden@broadcom.com>

Add request_partial_firmware_into_buf() to allow for portions of a
firmware file to be read into a buffer. This is needed when large firmware
must be loaded in portions from a file on memory constrained systems.

Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/base/firmware_loader/firmware.h |   4 +
 drivers/base/firmware_loader/main.c     | 109 +++++++++++++++++++-----
 include/linux/firmware.h                |  12 +++
 3 files changed, 105 insertions(+), 20 deletions(-)

diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h
index 7ad5fe52bc72..3f6eda46b3a2 100644
--- a/drivers/base/firmware_loader/firmware.h
+++ b/drivers/base/firmware_loader/firmware.h
@@ -32,6 +32,8 @@
  * @FW_OPT_FALLBACK_PLATFORM: Enable fallback to device fw copy embedded in
  *	the platform's main firmware. If both this fallback and the sysfs
  *      fallback are enabled, then this fallback will be tried first.
+ * @FW_OPT_PARTIAL: Allow partial read of firmware instead of needing to read
+ *	entire file.
  */
 enum fw_opt {
 	FW_OPT_UEVENT			= BIT(0),
@@ -41,6 +43,7 @@ enum fw_opt {
 	FW_OPT_NOCACHE			= BIT(4),
 	FW_OPT_NOFALLBACK_SYSFS		= BIT(5),
 	FW_OPT_FALLBACK_PLATFORM	= BIT(6),
+	FW_OPT_PARTIAL			= BIT(7),
 };
 
 enum fw_status {
@@ -68,6 +71,7 @@ struct fw_priv {
 	void *data;
 	size_t size;
 	size_t allocated_size;
+	size_t offset;
 	u32 opt_flags;
 #ifdef CONFIG_FW_LOADER_PAGED_BUF
 	bool is_paged_buf;
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 814a18cc51bd..7aa22bdc2f60 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -170,10 +170,19 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
 					  struct firmware_cache *fwc,
 					  void *dbuf,
 					  size_t size,
+					  size_t offset,
 					  u32 opt_flags)
 {
 	struct fw_priv *fw_priv;
 
+	/* For a partial read, the buffer must be preallocated. */
+	if ((opt_flags & FW_OPT_PARTIAL) && !dbuf)
+		return NULL;
+
+	/* Only partial reads are allowed to use an offset. */
+	if (offset != 0 && !(opt_flags & FW_OPT_PARTIAL))
+		return NULL;
+
 	fw_priv = kzalloc(sizeof(*fw_priv), GFP_ATOMIC);
 	if (!fw_priv)
 		return NULL;
@@ -188,6 +197,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name,
 	fw_priv->fwc = fwc;
 	fw_priv->data = dbuf;
 	fw_priv->allocated_size = size;
+	fw_priv->offset = offset;
 	fw_priv->opt_flags = opt_flags;
 	fw_state_init(fw_priv);
 #ifdef CONFIG_FW_LOADER_USER_HELPER
@@ -216,12 +226,17 @@ static int alloc_lookup_fw_priv(const char *fw_name,
 				struct fw_priv **fw_priv,
 				void *dbuf,
 				size_t size,
+				size_t offset,
 				u32 opt_flags)
 {
 	struct fw_priv *tmp;
 
 	spin_lock(&fwc->lock);
-	if (!(opt_flags & FW_OPT_NOCACHE)) {
+	/*
+	 * Do not merge requests that are marked to be non-cached or
+	 * are performing partial reads.
+	 */
+	if (!(opt_flags & (FW_OPT_NOCACHE | FW_OPT_PARTIAL))) {
 		tmp = __lookup_fw_priv(fw_name);
 		if (tmp) {
 			kref_get(&tmp->ref);
@@ -232,7 +247,7 @@ static int alloc_lookup_fw_priv(const char *fw_name,
 		}
 	}
 
-	tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size, opt_flags);
+	tmp = __allocate_fw_priv(fw_name, fwc, dbuf, size, offset, opt_flags);
 	if (tmp) {
 		INIT_LIST_HEAD(&tmp->list);
 		if (!(opt_flags & FW_OPT_NOCACHE))
@@ -439,6 +454,12 @@ static int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv,
 	else
 		return fw_decompress_xz_pages(dev, fw_priv, in_size, in_buffer);
 }
+#else
+static inline int fw_decompress_xz(struct device *dev, struct fw_priv *fw_priv,
+				   size_t in_size, const void *in_buffer)
+{
+	return -ENOENT;
+}
 #endif /* CONFIG_FW_LOADER_COMPRESS */
 
 /* direct firmware loading support */
@@ -485,6 +506,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 		return -ENOMEM;
 
 	for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
+		size_t file_size = 0;
+		size_t *file_size_ptr = NULL;
+
 		/* skip the unset customized path */
 		if (!fw_path[i][0])
 			continue;
@@ -498,9 +522,18 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
 
 		fw_priv->size = 0;
 
+		/*
+		 * The total file size is only examined when doing a partial
+		 * read; the "full read" case needs to fail if the whole
+		 * firmware was not completely loaded.
+		 */
+		if ((fw_priv->opt_flags & FW_OPT_PARTIAL) && buffer)
+			file_size_ptr = &file_size;
+
 		/* load firmware files from the mount namespace of init */
-		rc = kernel_read_file_from_path_initns(path, 0, &buffer, msize,
-						       NULL,
+		rc = kernel_read_file_from_path_initns(path, fw_priv->offset,
+						       &buffer, msize,
+						       file_size_ptr,
 						       READING_FIRMWARE);
 		if (rc < 0) {
 			if (rc != -ENOENT)
@@ -691,7 +724,7 @@ int assign_fw(struct firmware *fw, struct device *device)
 static int
 _request_firmware_prepare(struct firmware **firmware_p, const char *name,
 			  struct device *device, void *dbuf, size_t size,
-			  u32 opt_flags)
+			  size_t offset, u32 opt_flags)
 {
 	struct firmware *firmware;
 	struct fw_priv *fw_priv;
@@ -710,7 +743,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
 	}
 
 	ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size,
-				  opt_flags);
+				   offset, opt_flags);
 
 	/*
 	 * bind with 'priv' now to avoid warning in failure path
@@ -757,9 +790,10 @@ static void fw_abort_batch_reqs(struct firmware *fw)
 static int
 _request_firmware(const struct firmware **firmware_p, const char *name,
 		  struct device *device, void *buf, size_t size,
-		  u32 opt_flags)
+		  size_t offset, u32 opt_flags)
 {
 	struct firmware *fw = NULL;
+	bool nondirect = false;
 	int ret;
 
 	if (!firmware_p)
@@ -771,18 +805,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 	}
 
 	ret = _request_firmware_prepare(&fw, name, device, buf, size,
-					opt_flags);
+					offset, opt_flags);
 	if (ret <= 0) /* error or already assigned */
 		goto out;
 
 	ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);
-#ifdef CONFIG_FW_LOADER_COMPRESS
-	if (ret == -ENOENT)
+
+	/* Only full reads can support decompression, platform, and sysfs. */
+	if (!(opt_flags & FW_OPT_PARTIAL))
+		nondirect = true;
+
+	if (ret == -ENOENT && nondirect)
 		ret = fw_get_filesystem_firmware(device, fw->priv, ".xz",
 						 fw_decompress_xz);
-#endif
-
-	if (ret == -ENOENT)
+	if (ret == -ENOENT && nondirect)
 		ret = firmware_fallback_platform(fw->priv);
 
 	if (ret) {
@@ -790,7 +826,9 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
 			dev_warn(device,
 				 "Direct firmware load for %s failed with error %d\n",
 				 name, ret);
-		ret = firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
+		if (nondirect)
+			ret = firmware_fallback_sysfs(fw, name, device,
+						      opt_flags, ret);
 	} else
 		ret = assign_fw(fw, device);
 
@@ -833,7 +871,7 @@ request_firmware(const struct firmware **firmware_p, const char *name,
 
 	/* Need to pin this module until return */
 	__module_get(THIS_MODULE);
-	ret = _request_firmware(firmware_p, name, device, NULL, 0,
+	ret = _request_firmware(firmware_p, name, device, NULL, 0, 0,
 				FW_OPT_UEVENT);
 	module_put(THIS_MODULE);
 	return ret;
@@ -860,7 +898,7 @@ int firmware_request_nowarn(const struct firmware **firmware, const char *name,
 
 	/* Need to pin this module until return */
 	__module_get(THIS_MODULE);
-	ret = _request_firmware(firmware, name, device, NULL, 0,
+	ret = _request_firmware(firmware, name, device, NULL, 0, 0,
 				FW_OPT_UEVENT | FW_OPT_NO_WARN);
 	module_put(THIS_MODULE);
 	return ret;
@@ -884,7 +922,7 @@ int request_firmware_direct(const struct firmware **firmware_p,
 	int ret;
 
 	__module_get(THIS_MODULE);
-	ret = _request_firmware(firmware_p, name, device, NULL, 0,
+	ret = _request_firmware(firmware_p, name, device, NULL, 0, 0,
 				FW_OPT_UEVENT | FW_OPT_NO_WARN |
 				FW_OPT_NOFALLBACK_SYSFS);
 	module_put(THIS_MODULE);
@@ -909,7 +947,7 @@ int firmware_request_platform(const struct firmware **firmware,
 
 	/* Need to pin this module until return */
 	__module_get(THIS_MODULE);
-	ret = _request_firmware(firmware, name, device, NULL, 0,
+	ret = _request_firmware(firmware, name, device, NULL, 0, 0,
 				FW_OPT_UEVENT | FW_OPT_FALLBACK_PLATFORM);
 	module_put(THIS_MODULE);
 	return ret;
@@ -965,13 +1003,44 @@ request_firmware_into_buf(const struct firmware **firmware_p, const char *name,
 		return -EOPNOTSUPP;
 
 	__module_get(THIS_MODULE);
-	ret = _request_firmware(firmware_p, name, device, buf, size,
+	ret = _request_firmware(firmware_p, name, device, buf, size, 0,
 				FW_OPT_UEVENT | FW_OPT_NOCACHE);
 	module_put(THIS_MODULE);
 	return ret;
 }
 EXPORT_SYMBOL(request_firmware_into_buf);
 
+/**
+ * request_partial_firmware_into_buf() - load partial firmware into a previously allocated buffer
+ * @firmware_p: pointer to firmware image
+ * @name: name of firmware file
+ * @device: device for which firmware is being loaded and DMA region allocated
+ * @buf: address of buffer to load firmware into
+ * @size: size of buffer
+ * @offset: offset into file to read
+ *
+ * This function works pretty much like request_firmware_into_buf except
+ * it allows a partial read of the file.
+ */
+int
+request_partial_firmware_into_buf(const struct firmware **firmware_p,
+				  const char *name, struct device *device,
+				  void *buf, size_t size, size_t offset)
+{
+	int ret;
+
+	if (fw_cache_is_setup(device, name))
+		return -EOPNOTSUPP;
+
+	__module_get(THIS_MODULE);
+	ret = _request_firmware(firmware_p, name, device, buf, size, offset,
+				FW_OPT_UEVENT | FW_OPT_NOCACHE |
+				FW_OPT_PARTIAL);
+	module_put(THIS_MODULE);
+	return ret;
+}
+EXPORT_SYMBOL(request_partial_firmware_into_buf);
+
 /**
  * release_firmware() - release the resource associated with a firmware image
  * @fw: firmware resource to release
@@ -1004,7 +1073,7 @@ static void request_firmware_work_func(struct work_struct *work)
 
 	fw_work = container_of(work, struct firmware_work, work);
 
-	_request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0,
+	_request_firmware(&fw, fw_work->name, fw_work->device, NULL, 0, 0,
 			  fw_work->opt_flags);
 	fw_work->cont(fw, fw_work->context);
 	put_device(fw_work->device); /* taken in request_firmware_nowait() */
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index cb3e2c06ed8a..c15acadc6cf4 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -53,6 +53,9 @@ int request_firmware_direct(const struct firmware **fw, const char *name,
 			    struct device *device);
 int request_firmware_into_buf(const struct firmware **firmware_p,
 	const char *name, struct device *device, void *buf, size_t size);
+int request_partial_firmware_into_buf(const struct firmware **firmware_p,
+				      const char *name, struct device *device,
+				      void *buf, size_t size, size_t offset);
 
 void release_firmware(const struct firmware *fw);
 #else
@@ -102,6 +105,15 @@ static inline int request_firmware_into_buf(const struct firmware **firmware_p,
 	return -EINVAL;
 }
 
+static inline int request_partial_firmware_into_buf
+					(const struct firmware **firmware_p,
+					 const char *name,
+					 struct device *device,
+					 void *buf, size_t size, size_t offset)
+{
+	return -EINVAL;
+}
+
 #endif
 
 int firmware_request_cache(struct device *device, const char *name);
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH v2 18/18] test_firmware: Test partial read support
  2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
                   ` (16 preceding siblings ...)
  2020-07-22 19:30 ` [PATCH v2 17/18] firmware: Add request_partial_firmware_into_buf() Kees Cook
@ 2020-07-22 19:30 ` Kees Cook
  17 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-22 19:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Kees Cook, Scott Branden, selinux, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi, Dmitry Kasatkin,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn, Jessica Yu,
	Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

From: Scott Branden <scott.branden@broadcom.com>

Add additional hooks to test_firmware to pass in support
for partial file read using request_firmware_into_buf():

	buf_size: size of buffer to request firmware into
	partial: indicates that a partial file request is being made
	file_offset: to indicate offset into file to request

Also update firmware selftests to use the new partial read test API.

Signed-off-by: Scott Branden <scott.branden@broadcom.com>
Co-developed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
This merges Scott's two test patches into one and I refactored the
selftests to not be batched, test the no-file condition, and to not
pass needless arguments, etc.
---
 lib/test_firmware.c                           | 154 ++++++++++++++++--
 .../selftests/firmware/fw_filesystem.sh       |  91 +++++++++++
 2 files changed, 233 insertions(+), 12 deletions(-)

diff --git a/lib/test_firmware.c b/lib/test_firmware.c
index 62af792e151c..387acb94eeea 100644
--- a/lib/test_firmware.c
+++ b/lib/test_firmware.c
@@ -50,6 +50,9 @@ struct test_batched_req {
  * @name: the name of the firmware file to look for
  * @into_buf: when the into_buf is used if this is true
  *	request_firmware_into_buf() will be used instead.
+ * @buf_size: size of buf to allocate when into_buf is true
+ * @file_offset: file offset to request when calling request_firmware_into_buf
+ * @partial: partial read opt when calling request_firmware_into_buf
  * @sync_direct: when the sync trigger is used if this is true
  *	request_firmware_direct() will be used instead.
  * @send_uevent: whether or not to send a uevent for async requests
@@ -89,6 +92,9 @@ struct test_batched_req {
 struct test_config {
 	char *name;
 	bool into_buf;
+	size_t buf_size;
+	size_t file_offset;
+	bool partial;
 	bool sync_direct;
 	bool send_uevent;
 	u8 num_requests;
@@ -183,6 +189,9 @@ static int __test_firmware_config_init(void)
 	test_fw_config->num_requests = TEST_FIRMWARE_NUM_REQS;
 	test_fw_config->send_uevent = true;
 	test_fw_config->into_buf = false;
+	test_fw_config->buf_size = TEST_FIRMWARE_BUF_SIZE;
+	test_fw_config->file_offset = 0;
+	test_fw_config->partial = false;
 	test_fw_config->sync_direct = false;
 	test_fw_config->req_firmware = request_firmware;
 	test_fw_config->test_result = 0;
@@ -236,28 +245,35 @@ static ssize_t config_show(struct device *dev,
 			dev_name(dev));
 
 	if (test_fw_config->name)
-		len += scnprintf(buf+len, PAGE_SIZE - len,
+		len += scnprintf(buf + len, PAGE_SIZE - len,
 				"name:\t%s\n",
 				test_fw_config->name);
 	else
-		len += scnprintf(buf+len, PAGE_SIZE - len,
+		len += scnprintf(buf + len, PAGE_SIZE - len,
 				"name:\tEMTPY\n");
 
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"num_requests:\t%u\n", test_fw_config->num_requests);
 
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"send_uevent:\t\t%s\n",
 			test_fw_config->send_uevent ?
 			"FW_ACTION_HOTPLUG" :
 			"FW_ACTION_NOHOTPLUG");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"into_buf:\t\t%s\n",
 			test_fw_config->into_buf ? "true" : "false");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"buf_size:\t%zu\n", test_fw_config->buf_size);
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"file_offset:\t%zu\n", test_fw_config->file_offset);
+	len += scnprintf(buf + len, PAGE_SIZE - len,
+			"partial:\t\t%s\n",
+			test_fw_config->partial ? "true" : "false");
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"sync_direct:\t\t%s\n",
 			test_fw_config->sync_direct ? "true" : "false");
-	len += scnprintf(buf+len, PAGE_SIZE - len,
+	len += scnprintf(buf + len, PAGE_SIZE - len,
 			"read_fw_idx:\t%u\n", test_fw_config->read_fw_idx);
 
 	mutex_unlock(&test_fw_mutex);
@@ -315,6 +331,30 @@ static ssize_t test_dev_config_show_bool(char *buf, bool val)
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
 }
 
+static int test_dev_config_update_size_t(const char *buf,
+					 size_t size,
+					 size_t *cfg)
+{
+	int ret;
+	long new;
+
+	ret = kstrtol(buf, 10, &new);
+	if (ret)
+		return ret;
+
+	mutex_lock(&test_fw_mutex);
+	*(size_t *)cfg = new;
+	mutex_unlock(&test_fw_mutex);
+
+	/* Always return full write size even if we didn't consume all */
+	return size;
+}
+
+static ssize_t test_dev_config_show_size_t(char *buf, size_t val)
+{
+	return snprintf(buf, PAGE_SIZE, "%zu\n", val);
+}
+
 static ssize_t test_dev_config_show_int(char *buf, int val)
 {
 	return snprintf(buf, PAGE_SIZE, "%d\n", val);
@@ -400,6 +440,83 @@ static ssize_t config_into_buf_show(struct device *dev,
 }
 static DEVICE_ATTR_RW(config_into_buf);
 
+static ssize_t config_buf_size_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	int rc;
+
+	mutex_lock(&test_fw_mutex);
+	if (test_fw_config->reqs) {
+		pr_err("Must call release_all_firmware prior to changing config\n");
+		rc = -EINVAL;
+		mutex_unlock(&test_fw_mutex);
+		goto out;
+	}
+	mutex_unlock(&test_fw_mutex);
+
+	rc = test_dev_config_update_size_t(buf, count,
+					   &test_fw_config->buf_size);
+
+out:
+	return rc;
+}
+
+static ssize_t config_buf_size_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	return test_dev_config_show_size_t(buf, test_fw_config->buf_size);
+}
+static DEVICE_ATTR_RW(config_buf_size);
+
+static ssize_t config_file_offset_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	int rc;
+
+	mutex_lock(&test_fw_mutex);
+	if (test_fw_config->reqs) {
+		pr_err("Must call release_all_firmware prior to changing config\n");
+		rc = -EINVAL;
+		mutex_unlock(&test_fw_mutex);
+		goto out;
+	}
+	mutex_unlock(&test_fw_mutex);
+
+	rc = test_dev_config_update_size_t(buf, count,
+					   &test_fw_config->file_offset);
+
+out:
+	return rc;
+}
+
+static ssize_t config_file_offset_show(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	return test_dev_config_show_size_t(buf, test_fw_config->file_offset);
+}
+static DEVICE_ATTR_RW(config_file_offset);
+
+static ssize_t config_partial_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	return test_dev_config_update_bool(buf,
+					   count,
+					   &test_fw_config->partial);
+}
+
+static ssize_t config_partial_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	return test_dev_config_show_bool(buf, test_fw_config->partial);
+}
+static DEVICE_ATTR_RW(config_partial);
+
 static ssize_t config_sync_direct_store(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
@@ -655,11 +772,21 @@ static int test_fw_run_batch_request(void *data)
 		if (!test_buf)
 			return -ENOSPC;
 
-		req->rc = request_firmware_into_buf(&req->fw,
-						    req->name,
-						    req->dev,
-						    test_buf,
-						    TEST_FIRMWARE_BUF_SIZE);
+		if (test_fw_config->partial)
+			req->rc = request_partial_firmware_into_buf
+						(&req->fw,
+						 req->name,
+						 req->dev,
+						 test_buf,
+						 test_fw_config->buf_size,
+						 test_fw_config->file_offset);
+		else
+			req->rc = request_firmware_into_buf
+						(&req->fw,
+						 req->name,
+						 req->dev,
+						 test_buf,
+						 test_fw_config->buf_size);
 		if (!req->fw)
 			kfree(test_buf);
 	} else {
@@ -932,6 +1059,9 @@ static struct attribute *test_dev_attrs[] = {
 	TEST_FW_DEV_ATTR(config_name),
 	TEST_FW_DEV_ATTR(config_num_requests),
 	TEST_FW_DEV_ATTR(config_into_buf),
+	TEST_FW_DEV_ATTR(config_buf_size),
+	TEST_FW_DEV_ATTR(config_file_offset),
+	TEST_FW_DEV_ATTR(config_partial),
 	TEST_FW_DEV_ATTR(config_sync_direct),
 	TEST_FW_DEV_ATTR(config_send_uevent),
 	TEST_FW_DEV_ATTR(config_read_fw_idx),
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
index fcc281373b4d..c2a2a100114b 100755
--- a/tools/testing/selftests/firmware/fw_filesystem.sh
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -149,6 +149,26 @@ config_unset_into_buf()
 	echo 0 >  $DIR/config_into_buf
 }
 
+config_set_buf_size()
+{
+	echo $1 >  $DIR/config_buf_size
+}
+
+config_set_file_offset()
+{
+	echo $1 >  $DIR/config_file_offset
+}
+
+config_set_partial()
+{
+	echo 1 >  $DIR/config_partial
+}
+
+config_unset_partial()
+{
+	echo 0 >  $DIR/config_partial
+}
+
 config_set_sync_direct()
 {
 	echo 1 >  $DIR/config_sync_direct
@@ -207,6 +227,35 @@ read_firmwares()
 	done
 }
 
+read_partial_firmwares()
+{
+	if [ "$(cat $DIR/config_into_buf)" == "1" ]; then
+		fwfile="${FW_INTO_BUF}"
+	else
+		fwfile="${FW}"
+	fi
+
+	if [ "$1" = "xzonly" ]; then
+		fwfile="${fwfile}-orig"
+	fi
+
+	# Strip fwfile down to match partial offset and length
+	partial_data="$(cat $fwfile)"
+	partial_data="${partial_data:$2:$3}"
+
+	for i in $(seq 0 3); do
+		config_set_read_fw_idx $i
+
+		read_firmware="$(cat $DIR/read_firmware)"
+
+		# Verify the contents are what we expect.
+		if [ $read_firmware != $partial_data ]; then
+			echo "request #$i: partial firmware was not loaded" >&2
+			exit 1
+		fi
+	done
+}
+
 read_firmwares_expect_nofile()
 {
 	for i in $(seq 0 3); do
@@ -242,6 +291,21 @@ test_batched_request_firmware_into_buf_nofile()
 	echo "OK"
 }
 
+test_request_partial_firmware_into_buf_nofile()
+{
+	echo -n "Test request_partial_firmware_into_buf() off=$1 size=$2 nofile: "
+	config_reset
+	config_set_name nope-test-firmware.bin
+	config_set_into_buf
+	config_set_partial
+	config_set_buf_size $2
+	config_set_file_offset $1
+	config_trigger_sync
+	read_firmwares_expect_nofile
+	release_all_firmware
+	echo "OK"
+}
+
 test_batched_request_firmware_direct_nofile()
 {
 	echo -n "Batched request_firmware_direct() nofile try #$1: "
@@ -356,6 +420,21 @@ test_request_firmware_nowait_custom()
 	echo "OK"
 }
 
+test_request_partial_firmware_into_buf()
+{
+	echo -n "Test request_partial_firmware_into_buf() off=$1 size=$2: "
+	config_reset
+	config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME
+	config_set_into_buf
+	config_set_partial
+	config_set_buf_size $2
+	config_set_file_offset $1
+	config_trigger_sync
+	read_partial_firmwares normal $1 $2
+	release_all_firmware
+	echo "OK"
+}
+
 # Only continue if batched request triggers are present on the
 # test-firmware driver
 test_config_present
@@ -383,6 +462,12 @@ for i in $(seq 1 5); do
 	test_request_firmware_nowait_custom $i normal
 done
 
+# Partial loads cannot use fallback, so do not repeat tests.
+test_request_partial_firmware_into_buf 0 10
+test_request_partial_firmware_into_buf 0 5
+test_request_partial_firmware_into_buf 1 6
+test_request_partial_firmware_into_buf 2 10
+
 # Test for file not found, errors are expected, the failure would be
 # a hung task, which would require a hard reset.
 echo
@@ -407,6 +492,12 @@ for i in $(seq 1 5); do
 	test_request_firmware_nowait_custom_nofile $i
 done
 
+# Partial loads cannot use fallback, so do not repeat tests.
+test_request_partial_firmware_into_buf_nofile 0 10
+test_request_partial_firmware_into_buf_nofile 0 5
+test_request_partial_firmware_into_buf_nofile 1 6
+test_request_partial_firmware_into_buf_nofile 2 10
+
 test "$HAS_FW_LOADER_COMPRESS" != "yes" && exit 0
 
 # test with both files present
-- 
2.25.1


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-22 19:30 ` [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads Kees Cook
@ 2020-07-22 22:29   ` Scott Branden
  2020-07-23  6:23     ` Scott Branden
  2020-07-23 19:15     ` Kees Cook
  0 siblings, 2 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-22 22:29 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

Hi Kees,

These changes don't pass the kernel-selftest for partial reads I added
(which are at the end of this patch v2 series).
See change below added for temp workaround for issue.
Even with such change real request_partial_firmware_into_buf doesn't
work fully with my bcm-vk driver.  I'm trying to debug that.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> To perform partial reads, callers of kernel_read_file*() must have a
> non-NULL file_size argument and a preallocated buffer. The new "offset"
> argument can then be used to seek to specific locations in the file to
> fill the buffer to, at most, "buf_size" per call.
>
> Where possible, the LSM hooks can report whether a full file has been
> read or not so that the contents can be reasoned about.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>   drivers/base/firmware_loader/main.c |  2 +-
>   fs/kernel_read_file.c               | 78 ++++++++++++++++++++---------
>   include/linux/kernel_read_file.h    |  8 +--
>   kernel/kexec_file.c                 |  4 +-
>   kernel/module.c                     |  2 +-
>   security/integrity/digsig.c         |  2 +-
>   security/integrity/ima/ima_fs.c     |  3 +-
>   7 files changed, 65 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
> index bd199404935f..d95249b5284e 100644
> --- a/drivers/base/firmware_loader/main.c
> +++ b/drivers/base/firmware_loader/main.c
> @@ -494,7 +494,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
>   		fw_priv->size = 0;
>   
>   		/* load firmware files from the mount namespace of init */
> -		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
> +		rc = kernel_read_file_from_path_initns(path, 0, &buffer, msize,
>   						       NULL,
>   						       READING_FIRMWARE);
>   		if (rc < 0) {
> diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
> index d73bc3fa710a..90d255fbdd9b 100644
> --- a/fs/kernel_read_file.c
> +++ b/fs/kernel_read_file.c
> @@ -9,6 +9,7 @@
>    * kernel_read_file() - read file contents into a kernel buffer
>    *
>    * @file	file to read from
> + * @offset	where to start reading from (see below).
>    * @buf		pointer to a "void *" buffer for reading into (if
>    *		*@buf is NULL, a buffer will be allocated, and
>    *		@buf_size will be ignored)
> @@ -19,19 +20,31 @@
>    * @id		the kernel_read_file_id identifying the type of
>    *		file contents being read (for LSMs to examine)
>    *
> + * @offset must be 0 unless both @buf and @file_size are non-NULL
> + * (i.e. the caller must be expecting to read partial file contents
> + * via an already-allocated @buf, in at most @buf_size chunks, and
> + * will be able to determine when the entire file was read by
> + * checking @file_size). This isn't a recommended way to read a
> + * file, though, since it is possible that the contents might
> + * change between calls to kernel_read_file().
> + *
>    * Returns number of bytes read (no single read will be bigger
>    * than INT_MAX), or negative on error.
>    *
>    */
> -int kernel_read_file(struct file *file, void **buf,
> +int kernel_read_file(struct file *file, loff_t offset, void **buf,
>   		     size_t buf_size, size_t *file_size,
>   		     enum kernel_read_file_id id)
>   {
>   	loff_t i_size, pos;
> -	ssize_t bytes = 0;
> +	size_t copied;
>   	void *allocated = NULL;
> +	bool whole_file;
>   	int ret;
>   
> +	if (offset != 0 && (!*buf || !file_size))
> +		return -EINVAL;
> +
>   	if (!S_ISREG(file_inode(file)->i_mode))
>   		return -EINVAL;
>   
> @@ -39,19 +52,27 @@ int kernel_read_file(struct file *file, void **buf,
>   	if (ret)
>   		return ret;
>   
> -	ret = security_kernel_read_file(file, id, true);
> -	if (ret)
> -		goto out;
> -
>   	i_size = i_size_read(file_inode(file));
>   	if (i_size <= 0) {
>   		ret = -EINVAL;
>   		goto out;
>   	}
> -	if (i_size > INT_MAX || i_size > buf_size) {
> +	/* The file is too big for sane activities. */
> +	if (i_size > INT_MAX) {
> +		ret = -EFBIG;
> +		goto out;
> +	}
> +	/* The entire file cannot be read in one buffer. */
> +	if (!file_size && offset == 0 && i_size > buf_size) {
>   		ret = -EFBIG;
>   		goto out;
>   	}
> +
> +	whole_file = (offset == 0 && i_size <= buf_size);
A hack to get this passing I added which probably breaks some security?
if (whole_file) {
> +	ret = security_kernel_read_file(file, id, whole_file);
> +	if (ret)
> +		goto out;
> +
}
>   	if (file_size)
>   		*file_size = i_size;
>   
> @@ -62,9 +83,14 @@ int kernel_read_file(struct file *file, void **buf,
>   		goto out;
>   	}
>   
> -	pos = 0;
> -	while (pos < i_size) {
> -		bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
> +	pos = offset;
> +	copied = 0;
> +	while (copied < buf_size) {
> +		ssize_t bytes;
> +		size_t wanted = min_t(size_t, buf_size - copied,
> +					      i_size - pos);
> +
> +		bytes = kernel_read(file, *buf + copied, wanted, &pos);
>   		if (bytes < 0) {
>   			ret = bytes;
>   			goto out_free;
> @@ -72,14 +98,17 @@ int kernel_read_file(struct file *file, void **buf,
>   
>   		if (bytes == 0)
>   			break;
> +		copied += bytes;
>   	}
>   
> -	if (pos != i_size) {
> -		ret = -EIO;
> -		goto out_free;
> -	}
> +	if (whole_file) {
> +		if (pos != i_size) {
> +			ret = -EIO;
> +			goto out_free;
> +		}
>   
> -	ret = security_kernel_post_read_file(file, *buf, i_size, id);
> +		ret = security_kernel_post_read_file(file, *buf, i_size, id);
> +	}
>   
>   out_free:
>   	if (ret < 0) {
> @@ -91,11 +120,11 @@ int kernel_read_file(struct file *file, void **buf,
>   
>   out:
>   	allow_write_access(file);
> -	return ret == 0 ? pos : ret;
> +	return ret == 0 ? copied : ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file);
>   
> -int kernel_read_file_from_path(const char *path, void **buf,
> +int kernel_read_file_from_path(const char *path, loff_t offset, void **buf,
>   			       size_t buf_size, size_t *file_size,
>   			       enum kernel_read_file_id id)
>   {
> @@ -109,14 +138,15 @@ int kernel_read_file_from_path(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, buf_size, file_size, id);
> +	ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>   
> -int kernel_read_file_from_path_initns(const char *path, void **buf,
> -				      size_t buf_size, size_t *file_size,
> +int kernel_read_file_from_path_initns(const char *path, loff_t offset,
> +				      void **buf, size_t buf_size,
> +				      size_t *file_size,
>   				      enum kernel_read_file_id id)
>   {
>   	struct file *file;
> @@ -135,14 +165,14 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, buf_size, file_size, id);
> +	ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
>   
> -int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
> -			     size_t *file_size,
> +int kernel_read_file_from_fd(int fd, loff_t offset, void **buf,
> +			     size_t buf_size, size_t *file_size,
>   			     enum kernel_read_file_id id)
>   {
>   	struct fd f = fdget(fd);
> @@ -151,7 +181,7 @@ int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
>   	if (!f.file)
>   		goto out;
>   
> -	ret = kernel_read_file(f.file, buf, buf_size, file_size, id);
> +	ret = kernel_read_file(f.file, offset, buf, buf_size, file_size, id);
>   out:
>   	fdput(f);
>   	return ret;
> diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
> index 023293eaf948..575ffa1031d3 100644
> --- a/include/linux/kernel_read_file.h
> +++ b/include/linux/kernel_read_file.h
> @@ -35,19 +35,19 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
>   	return kernel_read_file_str[id];
>   }
>   
> -int kernel_read_file(struct file *file,
> +int kernel_read_file(struct file *file, loff_t offset,
>   		     void **buf, size_t buf_size,
>   		     size_t *file_size,
>   		     enum kernel_read_file_id id);
> -int kernel_read_file_from_path(const char *path,
> +int kernel_read_file_from_path(const char *path, loff_t offset,
>   			       void **buf, size_t buf_size,
>   			       size_t *file_size,
>   			       enum kernel_read_file_id id);
> -int kernel_read_file_from_path_initns(const char *path,
> +int kernel_read_file_from_path_initns(const char *path, loff_t offset,
>   				      void **buf, size_t buf_size,
>   				      size_t *file_size,
>   				      enum kernel_read_file_id id);
> -int kernel_read_file_from_fd(int fd,
> +int kernel_read_file_from_fd(int fd, loff_t offset,
>   			     void **buf, size_t buf_size,
>   			     size_t *file_size,
>   			     enum kernel_read_file_id id);
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 878ca684a3a1..45726bc8f6ce 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -221,7 +221,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   	int ret;
>   	void *ldata;
>   
> -	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
> +	ret = kernel_read_file_from_fd(kernel_fd, 0, &image->kernel_buf,
>   				       INT_MAX, NULL, READING_KEXEC_IMAGE);
>   	if (ret < 0)
>   		return ret;
> @@ -241,7 +241,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   #endif
>   	/* It is possible that there no initramfs is being loaded */
>   	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
> -		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
> +		ret = kernel_read_file_from_fd(initrd_fd, 0, &image->initrd_buf,
>   					       INT_MAX, NULL,
>   					       READING_KEXEC_INITRAMFS);
>   		if (ret < 0)
> diff --git a/kernel/module.c b/kernel/module.c
> index 90a4788dff9d..d353d1f67681 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -4007,7 +4007,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>   		      |MODULE_INIT_IGNORE_VERMAGIC))
>   		return -EINVAL;
>   
> -	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX, NULL,
> +	err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL,
>   				       READING_MODULE);
>   	if (err < 0)
>   		return err;
> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> index 8a523dfd7fd7..0f518dcfde05 100644
> --- a/security/integrity/digsig.c
> +++ b/security/integrity/digsig.c
> @@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
>   	int rc;
>   	key_perm_t perm;
>   
> -	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL,
> +	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
>   					READING_X509_CERTIFICATE);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 5fc56ccb6678..ea8ff8a07b36 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -284,7 +284,8 @@ static ssize_t ima_read_policy(char *path)
>   	datap = path;
>   	strsep(&datap, "\n");
>   
> -	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL, READING_POLICY);
> +	rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
> +					READING_POLICY);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
>   		return rc;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-22 22:29   ` Scott Branden
@ 2020-07-23  6:23     ` Scott Branden
  2020-07-23 19:17       ` Kees Cook
  2020-07-23 19:15     ` Kees Cook
  1 sibling, 1 reply; 38+ messages in thread
From: Scott Branden @ 2020-07-23  6:23 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann



On 2020-07-22 3:29 p.m., Scott Branden wrote:
> Hi Kees,
>
> These changes don't pass the kernel-selftest for partial reads I added
> (which are at the end of this patch v2 series).
> See change below added for temp workaround for issue.
> Even with such change real request_partial_firmware_into_buf doesn't
> work fully with my bcm-vk driver.  I'm trying to debug that.
I made an adjustment in the logic of the driver with use of 
request_partial_firmware_into_buf
and now everything is working.  So only issue I find with this entire 
patch series is the problem
of security failing without the workaround below.
>
> On 2020-07-22 12:30 p.m., Kees Cook wrote:
>> To perform partial reads, callers of kernel_read_file*() must have a
>> non-NULL file_size argument and a preallocated buffer. The new "offset"
>> argument can then be used to seek to specific locations in the file to
>> fill the buffer to, at most, "buf_size" per call.
>>
>> Where possible, the LSM hooks can report whether a full file has been
>> read or not so that the contents can be reasoned about.
>>
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>>   drivers/base/firmware_loader/main.c |  2 +-
>>   fs/kernel_read_file.c               | 78 ++++++++++++++++++++---------
>>   include/linux/kernel_read_file.h    |  8 +--
>>   kernel/kexec_file.c                 |  4 +-
>>   kernel/module.c                     |  2 +-
>>   security/integrity/digsig.c         |  2 +-
>>   security/integrity/ima/ima_fs.c     |  3 +-
>>   7 files changed, 65 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/base/firmware_loader/main.c 
>> b/drivers/base/firmware_loader/main.c
>> index bd199404935f..d95249b5284e 100644
>> --- a/drivers/base/firmware_loader/main.c
>> +++ b/drivers/base/firmware_loader/main.c
>> @@ -494,7 +494,7 @@ fw_get_filesystem_firmware(struct device *device, 
>> struct fw_priv *fw_priv,
>>           fw_priv->size = 0;
>>             /* load firmware files from the mount namespace of init */
>> -        rc = kernel_read_file_from_path_initns(path, &buffer, msize,
>> +        rc = kernel_read_file_from_path_initns(path, 0, &buffer, msize,
>>                                  NULL,
>>                                  READING_FIRMWARE);
>>           if (rc < 0) {
>> diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
>> index d73bc3fa710a..90d255fbdd9b 100644
>> --- a/fs/kernel_read_file.c
>> +++ b/fs/kernel_read_file.c
>> @@ -9,6 +9,7 @@
>>    * kernel_read_file() - read file contents into a kernel buffer
>>    *
>>    * @file    file to read from
>> + * @offset    where to start reading from (see below).
>>    * @buf        pointer to a "void *" buffer for reading into (if
>>    *        *@buf is NULL, a buffer will be allocated, and
>>    *        @buf_size will be ignored)
>> @@ -19,19 +20,31 @@
>>    * @id        the kernel_read_file_id identifying the type of
>>    *        file contents being read (for LSMs to examine)
>>    *
>> + * @offset must be 0 unless both @buf and @file_size are non-NULL
>> + * (i.e. the caller must be expecting to read partial file contents
>> + * via an already-allocated @buf, in at most @buf_size chunks, and
>> + * will be able to determine when the entire file was read by
>> + * checking @file_size). This isn't a recommended way to read a
>> + * file, though, since it is possible that the contents might
>> + * change between calls to kernel_read_file().
>> + *
>>    * Returns number of bytes read (no single read will be bigger
>>    * than INT_MAX), or negative on error.
>>    *
>>    */
>> -int kernel_read_file(struct file *file, void **buf,
>> +int kernel_read_file(struct file *file, loff_t offset, void **buf,
>>                size_t buf_size, size_t *file_size,
>>                enum kernel_read_file_id id)
>>   {
>>       loff_t i_size, pos;
>> -    ssize_t bytes = 0;
>> +    size_t copied;
>>       void *allocated = NULL;
>> +    bool whole_file;
>>       int ret;
>>   +    if (offset != 0 && (!*buf || !file_size))
>> +        return -EINVAL;
>> +
>>       if (!S_ISREG(file_inode(file)->i_mode))
>>           return -EINVAL;
>>   @@ -39,19 +52,27 @@ int kernel_read_file(struct file *file, void 
>> **buf,
>>       if (ret)
>>           return ret;
>>   -    ret = security_kernel_read_file(file, id, true);
>> -    if (ret)
>> -        goto out;
>> -
>>       i_size = i_size_read(file_inode(file));
>>       if (i_size <= 0) {
>>           ret = -EINVAL;
>>           goto out;
>>       }
>> -    if (i_size > INT_MAX || i_size > buf_size) {
>> +    /* The file is too big for sane activities. */
>> +    if (i_size > INT_MAX) {
>> +        ret = -EFBIG;
>> +        goto out;
>> +    }
>> +    /* The entire file cannot be read in one buffer. */
>> +    if (!file_size && offset == 0 && i_size > buf_size) {
>>           ret = -EFBIG;
>>           goto out;
>>       }
>> +
>> +    whole_file = (offset == 0 && i_size <= buf_size);
> A hack to get this passing I added which probably breaks some security?
> if (whole_file) {
>> +    ret = security_kernel_read_file(file, id, whole_file);
>> +    if (ret)
>> +        goto out;
>> +
> }
>>       if (file_size)
>>           *file_size = i_size;
>>   @@ -62,9 +83,14 @@ int kernel_read_file(struct file *file, void **buf,
>>           goto out;
>>       }
>>   -    pos = 0;
>> -    while (pos < i_size) {
>> -        bytes = kernel_read(file, *buf + pos, i_size - pos, &pos);
>> +    pos = offset;
>> +    copied = 0;
>> +    while (copied < buf_size) {
>> +        ssize_t bytes;
>> +        size_t wanted = min_t(size_t, buf_size - copied,
>> +                          i_size - pos);
>> +
>> +        bytes = kernel_read(file, *buf + copied, wanted, &pos);
>>           if (bytes < 0) {
>>               ret = bytes;
>>               goto out_free;
>> @@ -72,14 +98,17 @@ int kernel_read_file(struct file *file, void **buf,
>>             if (bytes == 0)
>>               break;
>> +        copied += bytes;
>>       }
>>   -    if (pos != i_size) {
>> -        ret = -EIO;
>> -        goto out_free;
>> -    }
>> +    if (whole_file) {
>> +        if (pos != i_size) {
>> +            ret = -EIO;
>> +            goto out_free;
>> +        }
>>   -    ret = security_kernel_post_read_file(file, *buf, i_size, id);
>> +        ret = security_kernel_post_read_file(file, *buf, i_size, id);
>> +    }
>>     out_free:
>>       if (ret < 0) {
>> @@ -91,11 +120,11 @@ int kernel_read_file(struct file *file, void **buf,
>>     out:
>>       allow_write_access(file);
>> -    return ret == 0 ? pos : ret;
>> +    return ret == 0 ? copied : ret;
>>   }
>>   EXPORT_SYMBOL_GPL(kernel_read_file);
>>   -int kernel_read_file_from_path(const char *path, void **buf,
>> +int kernel_read_file_from_path(const char *path, loff_t offset, void 
>> **buf,
>>                      size_t buf_size, size_t *file_size,
>>                      enum kernel_read_file_id id)
>>   {
>> @@ -109,14 +138,15 @@ int kernel_read_file_from_path(const char 
>> *path, void **buf,
>>       if (IS_ERR(file))
>>           return PTR_ERR(file);
>>   -    ret = kernel_read_file(file, buf, buf_size, file_size, id);
>> +    ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
>>       fput(file);
>>       return ret;
>>   }
>>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>>   -int kernel_read_file_from_path_initns(const char *path, void **buf,
>> -                      size_t buf_size, size_t *file_size,
>> +int kernel_read_file_from_path_initns(const char *path, loff_t offset,
>> +                      void **buf, size_t buf_size,
>> +                      size_t *file_size,
>>                         enum kernel_read_file_id id)
>>   {
>>       struct file *file;
>> @@ -135,14 +165,14 @@ int kernel_read_file_from_path_initns(const 
>> char *path, void **buf,
>>       if (IS_ERR(file))
>>           return PTR_ERR(file);
>>   -    ret = kernel_read_file(file, buf, buf_size, file_size, id);
>> +    ret = kernel_read_file(file, offset, buf, buf_size, file_size, id);
>>       fput(file);
>>       return ret;
>>   }
>>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
>>   -int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
>> -                 size_t *file_size,
>> +int kernel_read_file_from_fd(int fd, loff_t offset, void **buf,
>> +                 size_t buf_size, size_t *file_size,
>>                    enum kernel_read_file_id id)
>>   {
>>       struct fd f = fdget(fd);
>> @@ -151,7 +181,7 @@ int kernel_read_file_from_fd(int fd, void **buf, 
>> size_t buf_size,
>>       if (!f.file)
>>           goto out;
>>   -    ret = kernel_read_file(f.file, buf, buf_size, file_size, id);
>> +    ret = kernel_read_file(f.file, offset, buf, buf_size, file_size, 
>> id);
>>   out:
>>       fdput(f);
>>       return ret;
>> diff --git a/include/linux/kernel_read_file.h 
>> b/include/linux/kernel_read_file.h
>> index 023293eaf948..575ffa1031d3 100644
>> --- a/include/linux/kernel_read_file.h
>> +++ b/include/linux/kernel_read_file.h
>> @@ -35,19 +35,19 @@ static inline const char 
>> *kernel_read_file_id_str(enum kernel_read_file_id id)
>>       return kernel_read_file_str[id];
>>   }
>>   -int kernel_read_file(struct file *file,
>> +int kernel_read_file(struct file *file, loff_t offset,
>>                void **buf, size_t buf_size,
>>                size_t *file_size,
>>                enum kernel_read_file_id id);
>> -int kernel_read_file_from_path(const char *path,
>> +int kernel_read_file_from_path(const char *path, loff_t offset,
>>                      void **buf, size_t buf_size,
>>                      size_t *file_size,
>>                      enum kernel_read_file_id id);
>> -int kernel_read_file_from_path_initns(const char *path,
>> +int kernel_read_file_from_path_initns(const char *path, loff_t offset,
>>                         void **buf, size_t buf_size,
>>                         size_t *file_size,
>>                         enum kernel_read_file_id id);
>> -int kernel_read_file_from_fd(int fd,
>> +int kernel_read_file_from_fd(int fd, loff_t offset,
>>                    void **buf, size_t buf_size,
>>                    size_t *file_size,
>>                    enum kernel_read_file_id id);
>> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
>> index 878ca684a3a1..45726bc8f6ce 100644
>> --- a/kernel/kexec_file.c
>> +++ b/kernel/kexec_file.c
>> @@ -221,7 +221,7 @@ kimage_file_prepare_segments(struct kimage 
>> *image, int kernel_fd, int initrd_fd,
>>       int ret;
>>       void *ldata;
>>   -    ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
>> +    ret = kernel_read_file_from_fd(kernel_fd, 0, &image->kernel_buf,
>>                          INT_MAX, NULL, READING_KEXEC_IMAGE);
>>       if (ret < 0)
>>           return ret;
>> @@ -241,7 +241,7 @@ kimage_file_prepare_segments(struct kimage 
>> *image, int kernel_fd, int initrd_fd,
>>   #endif
>>       /* It is possible that there no initramfs is being loaded */
>>       if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
>> -        ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
>> +        ret = kernel_read_file_from_fd(initrd_fd, 0, 
>> &image->initrd_buf,
>>                              INT_MAX, NULL,
>>                              READING_KEXEC_INITRAMFS);
>>           if (ret < 0)
>> diff --git a/kernel/module.c b/kernel/module.c
>> index 90a4788dff9d..d353d1f67681 100644
>> --- a/kernel/module.c
>> +++ b/kernel/module.c
>> @@ -4007,7 +4007,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const 
>> char __user *, uargs, int, flags)
>>                 |MODULE_INIT_IGNORE_VERMAGIC))
>>           return -EINVAL;
>>   -    err = kernel_read_file_from_fd(fd, &hdr, INT_MAX, NULL,
>> +    err = kernel_read_file_from_fd(fd, 0, &hdr, INT_MAX, NULL,
>>                          READING_MODULE);
>>       if (err < 0)
>>           return err;
>> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
>> index 8a523dfd7fd7..0f518dcfde05 100644
>> --- a/security/integrity/digsig.c
>> +++ b/security/integrity/digsig.c
>> @@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int 
>> id, const char *path)
>>       int rc;
>>       key_perm_t perm;
>>   -    rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL,
>> +    rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
>>                       READING_X509_CERTIFICATE);
>>       if (rc < 0) {
>>           pr_err("Unable to open file: %s (%d)", path, rc);
>> diff --git a/security/integrity/ima/ima_fs.c 
>> b/security/integrity/ima/ima_fs.c
>> index 5fc56ccb6678..ea8ff8a07b36 100644
>> --- a/security/integrity/ima/ima_fs.c
>> +++ b/security/integrity/ima/ima_fs.c
>> @@ -284,7 +284,8 @@ static ssize_t ima_read_policy(char *path)
>>       datap = path;
>>       strsep(&datap, "\n");
>>   -    rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL, 
>> READING_POLICY);
>> +    rc = kernel_read_file_from_path(path, 0, &data, INT_MAX, NULL,
>> +                    READING_POLICY);
>>       if (rc < 0) {
>>           pr_err("Unable to open file: %s (%d)", path, rc);
>>           return rc;
>


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings
  2020-07-22 19:30 ` [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings Kees Cook
@ 2020-07-23  6:38   ` SeongJae Park
  2020-07-23 17:34   ` Scott Branden
  1 sibling, 0 replies; 38+ messages in thread
From: SeongJae Park @ 2020-07-23  6:38 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, Scott Branden, selinux, Jessica Yu, Hans de Goede,
	Alexander Viro, Matthieu Baerts, KP Singh, Eric Paris,
	linux-integrity, Florent Revest, Andrea Righi,
	Greg Kroah-Hartman, Stephen Smalley, Randy Dunlap, kexec,
	linux-kernel, Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Wed, 22 Jul 2020 12:30:04 -0700 Kees Cook <keescook@chromium.org> wrote:

> The firmware tests would always time out for me. Add a correct timeout,
> including details on how the value was reached. Additionally allow the
> test harness to skip comments in settings files and report how long a
> given timeout was.
> 
> Signed-off-by: Kees Cook <keescook@chromium.org>

Reviewed-by: SeongJae Park <sjpark@amazon.de>

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems
  2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
@ 2020-07-23 17:32   ` Scott Branden
  2020-07-29  0:48   ` Luis Chamberlain
  1 sibling, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:32 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, stable, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

Looks good.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> On non-EFI systems, it wasn't possible to test the platform firmware
> loader because it will have never set "checked_fw" during __init.
> Instead, allow the test code to override this check. Additionally split
> the declarations into a private header file so it there is greater
> enforcement of the symbol visibility.
>
> Fixes: 548193cba2a7 ("test_firmware: add support for firmware_request_platform")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
>   drivers/firmware/efi/embedded-firmware.c | 21 ++++++++++++++++-----
>   drivers/firmware/efi/embedded-firmware.h | 19 +++++++++++++++++++
>   include/linux/efi_embedded_fw.h          | 13 -------------
>   lib/test_firmware.c                      |  5 +++++
>   4 files changed, 40 insertions(+), 18 deletions(-)
>   create mode 100644 drivers/firmware/efi/embedded-firmware.h
>
> diff --git a/drivers/firmware/efi/embedded-firmware.c b/drivers/firmware/efi/embedded-firmware.c
> index a1b199de9006..0fb03cd0a5a2 100644
> --- a/drivers/firmware/efi/embedded-firmware.c
> +++ b/drivers/firmware/efi/embedded-firmware.c
> @@ -14,11 +14,22 @@
>   #include <linux/vmalloc.h>
>   #include <crypto/sha.h>
>   
> +#include "embedded-firmware.h"
> +
> +#ifdef CONFIG_TEST_FIRMWARE
> +# define EFI_EMBEDDED_FW_VISIBILITY
> +#else
> +# define EFI_EMBEDDED_FW_VISIBILITY static
> +#endif
> +
> +EFI_EMBEDDED_FW_VISIBILITY LIST_HEAD(efi_embedded_fw_list);
> +EFI_EMBEDDED_FW_VISIBILITY bool efi_embedded_fw_checked;
> +
>   /* Exported for use by lib/test_firmware.c only */
> -LIST_HEAD(efi_embedded_fw_list);
> +#ifdef CONFIG_TEST_FIRMWARE
>   EXPORT_SYMBOL_GPL(efi_embedded_fw_list);
> -
> -static bool checked_for_fw;
> +EXPORT_SYMBOL_GPL(efi_embedded_fw_checked);
> +#endif
>   
>   static const struct dmi_system_id * const embedded_fw_table[] = {
>   #ifdef CONFIG_TOUCHSCREEN_DMI
> @@ -119,14 +130,14 @@ void __init efi_check_for_embedded_firmwares(void)
>   		}
>   	}
>   
> -	checked_for_fw = true;
> +	efi_embedded_fw_checked = true;
>   }
>   
>   int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size)
>   {
>   	struct efi_embedded_fw *iter, *fw = NULL;
>   
> -	if (!checked_for_fw) {
> +	if (!efi_embedded_fw_checked) {
>   		pr_warn("Warning %s called while we did not check for embedded fw\n",
>   			__func__);
>   		return -ENOENT;
> diff --git a/drivers/firmware/efi/embedded-firmware.h b/drivers/firmware/efi/embedded-firmware.h
> new file mode 100644
> index 000000000000..34113316d068
> --- /dev/null
> +++ b/drivers/firmware/efi/embedded-firmware.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _EFI_EMBEDDED_FW_INTERNAL_H_
> +#define _EFI_EMBEDDED_FW_INTERNAL_H_
> +
> +/*
> + * This struct and efi_embedded_fw_list are private to the efi-embedded fw
> + * implementation they only in separate header for use by lib/test_firmware.c.
> + */
> +struct efi_embedded_fw {
> +	struct list_head list;
> +	const char *name;
> +	const u8 *data;
> +	size_t length;
> +};
> +
> +extern struct list_head efi_embedded_fw_list;
> +extern bool efi_embedded_fw_checked;
> +
> +#endif /* _EFI_EMBEDDED_FW_INTERNAL_H_ */
> diff --git a/include/linux/efi_embedded_fw.h b/include/linux/efi_embedded_fw.h
> index 57eac5241303..4ad5db9f5312 100644
> --- a/include/linux/efi_embedded_fw.h
> +++ b/include/linux/efi_embedded_fw.h
> @@ -7,19 +7,6 @@
>   
>   #define EFI_EMBEDDED_FW_PREFIX_LEN		8
>   
> -/*
> - * This struct and efi_embedded_fw_list are private to the efi-embedded fw
> - * implementation they are in this header for use by lib/test_firmware.c only!
> - */
> -struct efi_embedded_fw {
> -	struct list_head list;
> -	const char *name;
> -	const u8 *data;
> -	size_t length;
> -};
> -
> -extern struct list_head efi_embedded_fw_list;
> -
>   /**
>    * struct efi_embedded_fw_desc - This struct is used by the EFI embedded-fw
>    *                               code to search for embedded firmwares.
> diff --git a/lib/test_firmware.c b/lib/test_firmware.c
> index 9fee2b93a8d1..62af792e151c 100644
> --- a/lib/test_firmware.c
> +++ b/lib/test_firmware.c
> @@ -489,6 +489,7 @@ static ssize_t trigger_request_store(struct device *dev,
>   static DEVICE_ATTR_WO(trigger_request);
>   
>   #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE
> +#include "../drivers/firmware/efi/embedded-firmware.h"
>   static ssize_t trigger_request_platform_store(struct device *dev,
>   					      struct device_attribute *attr,
>   					      const char *buf, size_t count)
> @@ -501,6 +502,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
>   	};
>   	struct efi_embedded_fw efi_embedded_fw;
>   	const struct firmware *firmware = NULL;
> +	bool saved_efi_embedded_fw_checked;
>   	char *name;
>   	int rc;
>   
> @@ -513,6 +515,8 @@ static ssize_t trigger_request_platform_store(struct device *dev,
>   	efi_embedded_fw.data = (void *)test_data;
>   	efi_embedded_fw.length = sizeof(test_data);
>   	list_add(&efi_embedded_fw.list, &efi_embedded_fw_list);
> +	saved_efi_embedded_fw_checked = efi_embedded_fw_checked;
> +	efi_embedded_fw_checked = true;
>   
>   	pr_info("loading '%s'\n", name);
>   	rc = firmware_request_platform(&firmware, name, dev);
> @@ -530,6 +534,7 @@ static ssize_t trigger_request_platform_store(struct device *dev,
>   	rc = count;
>   
>   out:
> +	efi_embedded_fw_checked = saved_efi_embedded_fw_checked;
>   	release_firmware(firmware);
>   	list_del(&efi_embedded_fw.list);
>   	kfree(name);


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings
  2020-07-22 19:30 ` [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings Kees Cook
  2020-07-23  6:38   ` SeongJae Park
@ 2020-07-23 17:34   ` Scott Branden
  1 sibling, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:34 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

works.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> The firmware tests would always time out for me. Add a correct timeout,
> including details on how the value was reached. Additionally allow the
> test harness to skip comments in settings files and report how long a
> given timeout was.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
>   tools/testing/selftests/firmware/settings   | 8 ++++++++
>   tools/testing/selftests/kselftest/runner.sh | 6 +++++-
>   2 files changed, 13 insertions(+), 1 deletion(-)
>   create mode 100644 tools/testing/selftests/firmware/settings
>
> diff --git a/tools/testing/selftests/firmware/settings b/tools/testing/selftests/firmware/settings
> new file mode 100644
> index 000000000000..085e664ee093
> --- /dev/null
> +++ b/tools/testing/selftests/firmware/settings
> @@ -0,0 +1,8 @@
> +# The async firmware timeout is set to 1 second (but ends up being effectively
> +# 2 seconds). There are 3 test configs, each done with and without firmware
> +# present, each with 2 "nowait" functions tested 5 times. Expected time for a
> +# normal execution should be 2 * 3 * 2 * 2 * 5 = 120 seconds for those alone.
> +# Additionally, fw_fallback may take 5 seconds for internal timeouts in each
> +# of the 3 configs, so at least another 15 seconds are needed. Add another
> +# 10 seconds for each testing config: 120 + 15 + 30
> +timeout=165
> diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh
> index 676b3a8b114d..cd5ddf979f15 100644
> --- a/tools/testing/selftests/kselftest/runner.sh
> +++ b/tools/testing/selftests/kselftest/runner.sh
> @@ -53,6 +53,10 @@ run_one()
>   	settings="$BASE_DIR/$DIR/settings"
>   	if [ -r "$settings" ] ; then
>   		while read line ; do
> +			# Skip comments.
> +			if echo "$line" | grep -q '^#'; then
> +				continue
> +			fi
>   			field=$(echo "$line" | cut -d= -f1)
>   			value=$(echo "$line" | cut -d= -f2-)
>   			eval "kselftest_$field"="$value"
> @@ -80,7 +84,7 @@ run_one()
>   			echo "not ok $test_num $TEST_HDR_MSG # SKIP"
>   		elif [ $rc -eq $timeout_rc ]; then \
>   			echo "#"
> -			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT"
> +			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
>   		else
>   			echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
>   		fi)


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument
  2020-07-22 19:30 ` [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument Kees Cook
@ 2020-07-23 17:35   ` Scott Branden
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:35 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

works

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> In preparation for refactoring kernel_read_file*(), remove the redundant
> "size" argument which is not needed: it can be included in the return
> code, with callers adjusted. (VFS reads already cannot be larger than
> INT_MAX.)
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
>   drivers/base/firmware_loader/main.c | 10 ++++++----
>   fs/kernel_read_file.c               | 20 +++++++++-----------
>   include/linux/kernel_read_file.h    |  8 ++++----
>   kernel/kexec_file.c                 | 14 +++++++-------
>   kernel/module.c                     |  7 +++----
>   security/integrity/digsig.c         |  5 +++--
>   security/integrity/ima/ima_fs.c     |  6 ++++--
>   7 files changed, 36 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
> index d4a413ea48ce..f80c0d102be8 100644
> --- a/drivers/base/firmware_loader/main.c
> +++ b/drivers/base/firmware_loader/main.c
> @@ -462,7 +462,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
>   					     size_t in_size,
>   					     const void *in_buffer))
>   {
> -	loff_t size;
> +	size_t size;
>   	int i, len;
>   	int rc = -ENOENT;
>   	char *path;
> @@ -494,10 +494,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
>   		fw_priv->size = 0;
>   
>   		/* load firmware files from the mount namespace of init */
> -		rc = kernel_read_file_from_path_initns(path, &buffer,
> -						       &size, msize,
> +		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
>   						       READING_FIRMWARE);
> -		if (rc) {
> +		if (rc < 0) {
>   			if (rc != -ENOENT)
>   				dev_warn(device, "loading %s failed with error %d\n",
>   					 path, rc);
> @@ -506,6 +505,9 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
>   					 path);
>   			continue;
>   		}
> +		size = rc;
> +		rc = 0;
> +
>   		dev_dbg(device, "Loading firmware from %s\n", path);
>   		if (decompress) {
>   			dev_dbg(device, "f/w decompressing %s\n",
> diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
> index 54d972d4befc..dc28a8def597 100644
> --- a/fs/kernel_read_file.c
> +++ b/fs/kernel_read_file.c
> @@ -5,7 +5,7 @@
>   #include <linux/security.h>
>   #include <linux/vmalloc.h>
>   
> -int kernel_read_file(struct file *file, void **buf, loff_t *size,
> +int kernel_read_file(struct file *file, void **buf,
>   		     loff_t max_size, enum kernel_read_file_id id)
>   {
>   	loff_t i_size, pos;
> @@ -29,7 +29,7 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>   		ret = -EINVAL;
>   		goto out;
>   	}
> -	if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
> +	if (i_size > INT_MAX || (max_size > 0 && i_size > max_size)) {
>   		ret = -EFBIG;
>   		goto out;
>   	}
> @@ -59,8 +59,6 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>   	}
>   
>   	ret = security_kernel_post_read_file(file, *buf, i_size, id);
> -	if (!ret)
> -		*size = pos;
>   
>   out_free:
>   	if (ret < 0) {
> @@ -72,11 +70,11 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
>   
>   out:
>   	allow_write_access(file);
> -	return ret;
> +	return ret == 0 ? pos : ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file);
>   
> -int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
> +int kernel_read_file_from_path(const char *path, void **buf,
>   			       loff_t max_size, enum kernel_read_file_id id)
>   {
>   	struct file *file;
> @@ -89,14 +87,14 @@ int kernel_read_file_from_path(const char *path, void **buf, loff_t *size,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, size, max_size, id);
> +	ret = kernel_read_file(file, buf, max_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>   
>   int kernel_read_file_from_path_initns(const char *path, void **buf,
> -				      loff_t *size, loff_t max_size,
> +				      loff_t max_size,
>   				      enum kernel_read_file_id id)
>   {
>   	struct file *file;
> @@ -115,13 +113,13 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, size, max_size, id);
> +	ret = kernel_read_file(file, buf, max_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
>   
> -int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
> +int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
>   			     enum kernel_read_file_id id)
>   {
>   	struct fd f = fdget(fd);
> @@ -130,7 +128,7 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t *size, loff_t max_size,
>   	if (!f.file)
>   		goto out;
>   
> -	ret = kernel_read_file(f.file, buf, size, max_size, id);
> +	ret = kernel_read_file(f.file, buf, max_size, id);
>   out:
>   	fdput(f);
>   	return ret;
> diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
> index 78cf3d7dc835..0ca0bdbed1bd 100644
> --- a/include/linux/kernel_read_file.h
> +++ b/include/linux/kernel_read_file.h
> @@ -36,16 +36,16 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
>   }
>   
>   int kernel_read_file(struct file *file,
> -		     void **buf, loff_t *size, loff_t max_size,
> +		     void **buf, loff_t max_size,
>   		     enum kernel_read_file_id id);
>   int kernel_read_file_from_path(const char *path,
> -			       void **buf, loff_t *size, loff_t max_size,
> +			       void **buf, loff_t max_size,
>   			       enum kernel_read_file_id id);
>   int kernel_read_file_from_path_initns(const char *path,
> -				      void **buf, loff_t *size, loff_t max_size,
> +				      void **buf, loff_t max_size,
>   				      enum kernel_read_file_id id);
>   int kernel_read_file_from_fd(int fd,
> -			     void **buf, loff_t *size, loff_t max_size,
> +			     void **buf, loff_t max_size,
>   			     enum kernel_read_file_id id);
>   
>   #endif /* _LINUX_KERNEL_READ_FILE_H */
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index 1358069ce9e9..eda19ca256a3 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -220,13 +220,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   {
>   	int ret;
>   	void *ldata;
> -	loff_t size;
>   
>   	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
> -				       &size, INT_MAX, READING_KEXEC_IMAGE);
> -	if (ret)
> +				       INT_MAX, READING_KEXEC_IMAGE);
> +	if (ret < 0)
>   		return ret;
> -	image->kernel_buf_len = size;
> +	image->kernel_buf_len = ret;
>   
>   	/* Call arch image probe handlers */
>   	ret = arch_kexec_kernel_image_probe(image, image->kernel_buf,
> @@ -243,11 +242,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   	/* It is possible that there no initramfs is being loaded */
>   	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
>   		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
> -					       &size, INT_MAX,
> +					       INT_MAX,
>   					       READING_KEXEC_INITRAMFS);
> -		if (ret)
> +		if (ret < 0)
>   			goto out;
> -		image->initrd_buf_len = size;
> +		image->initrd_buf_len = ret;
> +		ret = 0;
>   	}
>   
>   	if (cmdline_len) {
> diff --git a/kernel/module.c b/kernel/module.c
> index e9765803601b..b6fd4f51cc30 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -3988,7 +3988,6 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
>   SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>   {
>   	struct load_info info = { };
> -	loff_t size;
>   	void *hdr = NULL;
>   	int err;
>   
> @@ -4002,12 +4001,12 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>   		      |MODULE_INIT_IGNORE_VERMAGIC))
>   		return -EINVAL;
>   
> -	err = kernel_read_file_from_fd(fd, &hdr, &size, INT_MAX,
> +	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX,
>   				       READING_MODULE);
> -	if (err)
> +	if (err < 0)
>   		return err;
>   	info.hdr = hdr;
> -	info.len = size;
> +	info.len = err;
>   
>   	return load_module(&info, uargs, flags);
>   }
> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> index f8869be45d8f..97661ffabc4e 100644
> --- a/security/integrity/digsig.c
> +++ b/security/integrity/digsig.c
> @@ -171,16 +171,17 @@ int __init integrity_add_key(const unsigned int id, const void *data,
>   int __init integrity_load_x509(const unsigned int id, const char *path)
>   {
>   	void *data = NULL;
> -	loff_t size;
> +	size_t size;
>   	int rc;
>   	key_perm_t perm;
>   
> -	rc = kernel_read_file_from_path(path, &data, &size, 0,
> +	rc = kernel_read_file_from_path(path, &data, 0,
>   					READING_X509_CERTIFICATE);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
>   		return rc;
>   	}
> +	size = rc;
>   
>   	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
>   
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index e13ffece3726..602f52717757 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -275,7 +275,7 @@ static ssize_t ima_read_policy(char *path)
>   {
>   	void *data = NULL;
>   	char *datap;
> -	loff_t size;
> +	size_t size;
>   	int rc, pathlen = strlen(path);
>   
>   	char *p;
> @@ -284,11 +284,13 @@ static ssize_t ima_read_policy(char *path)
>   	datap = path;
>   	strsep(&datap, "\n");
>   
> -	rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
> +	rc = kernel_read_file_from_path(path, &data, 0, READING_POLICY);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
>   		return rc;
>   	}
> +	size = rc;
> +	rc = 0;
>   
>   	datap = data;
>   	while (size > 0 && (p = strsep(&datap, "\n"))) {


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t
  2020-07-22 19:30 ` [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t Kees Cook
@ 2020-07-23 17:36   ` Scott Branden
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:36 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

works.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> In preparation for further refactoring of kernel_read_file*(), rename
> the "max_size" argument to the more accurate "buf_size", and correct
> its type to size_t. Add kerndoc to explain the specifics of how the
> arguments will be used. Note that with buf_size now size_t, it can no
> longer be negative (and was never called with a negative value). Adjust
> callers to use it as a "maximum size" when *buf is NULL.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
>   fs/kernel_read_file.c            | 34 +++++++++++++++++++++++---------
>   include/linux/kernel_read_file.h |  8 ++++----
>   security/integrity/digsig.c      |  2 +-
>   security/integrity/ima/ima_fs.c  |  2 +-
>   4 files changed, 31 insertions(+), 15 deletions(-)
>
> diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
> index dc28a8def597..e21a76001fff 100644
> --- a/fs/kernel_read_file.c
> +++ b/fs/kernel_read_file.c
> @@ -5,15 +5,31 @@
>   #include <linux/security.h>
>   #include <linux/vmalloc.h>
>   
> +/**
> + * kernel_read_file() - read file contents into a kernel buffer
> + *
> + * @file	file to read from
> + * @buf		pointer to a "void *" buffer for reading into (if
> + *		*@buf is NULL, a buffer will be allocated, and
> + *		@buf_size will be ignored)
> + * @buf_size	size of buf, if already allocated. If @buf not
> + *		allocated, this is the largest size to allocate.
> + * @id		the kernel_read_file_id identifying the type of
> + *		file contents being read (for LSMs to examine)
> + *
> + * Returns number of bytes read (no single read will be bigger
> + * than INT_MAX), or negative on error.
> + *
> + */
>   int kernel_read_file(struct file *file, void **buf,
> -		     loff_t max_size, enum kernel_read_file_id id)
> +		     size_t buf_size, enum kernel_read_file_id id)
>   {
>   	loff_t i_size, pos;
>   	ssize_t bytes = 0;
>   	void *allocated = NULL;
>   	int ret;
>   
> -	if (!S_ISREG(file_inode(file)->i_mode) || max_size < 0)
> +	if (!S_ISREG(file_inode(file)->i_mode))
>   		return -EINVAL;
>   
>   	ret = deny_write_access(file);
> @@ -29,7 +45,7 @@ int kernel_read_file(struct file *file, void **buf,
>   		ret = -EINVAL;
>   		goto out;
>   	}
> -	if (i_size > INT_MAX || (max_size > 0 && i_size > max_size)) {
> +	if (i_size > INT_MAX || i_size > buf_size) {
>   		ret = -EFBIG;
>   		goto out;
>   	}
> @@ -75,7 +91,7 @@ int kernel_read_file(struct file *file, void **buf,
>   EXPORT_SYMBOL_GPL(kernel_read_file);
>   
>   int kernel_read_file_from_path(const char *path, void **buf,
> -			       loff_t max_size, enum kernel_read_file_id id)
> +			       size_t buf_size, enum kernel_read_file_id id)
>   {
>   	struct file *file;
>   	int ret;
> @@ -87,14 +103,14 @@ int kernel_read_file_from_path(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, max_size, id);
> +	ret = kernel_read_file(file, buf, buf_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>   
>   int kernel_read_file_from_path_initns(const char *path, void **buf,
> -				      loff_t max_size,
> +				      size_t buf_size,
>   				      enum kernel_read_file_id id)
>   {
>   	struct file *file;
> @@ -113,13 +129,13 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, max_size, id);
> +	ret = kernel_read_file(file, buf, buf_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
>   
> -int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
> +int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
>   			     enum kernel_read_file_id id)
>   {
>   	struct fd f = fdget(fd);
> @@ -128,7 +144,7 @@ int kernel_read_file_from_fd(int fd, void **buf, loff_t max_size,
>   	if (!f.file)
>   		goto out;
>   
> -	ret = kernel_read_file(f.file, buf, max_size, id);
> +	ret = kernel_read_file(f.file, buf, buf_size, id);
>   out:
>   	fdput(f);
>   	return ret;
> diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
> index 0ca0bdbed1bd..910039e7593e 100644
> --- a/include/linux/kernel_read_file.h
> +++ b/include/linux/kernel_read_file.h
> @@ -36,16 +36,16 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
>   }
>   
>   int kernel_read_file(struct file *file,
> -		     void **buf, loff_t max_size,
> +		     void **buf, size_t buf_size,
>   		     enum kernel_read_file_id id);
>   int kernel_read_file_from_path(const char *path,
> -			       void **buf, loff_t max_size,
> +			       void **buf, size_t buf_size,
>   			       enum kernel_read_file_id id);
>   int kernel_read_file_from_path_initns(const char *path,
> -				      void **buf, loff_t max_size,
> +				      void **buf, size_t buf_size,
>   				      enum kernel_read_file_id id);
>   int kernel_read_file_from_fd(int fd,
> -			     void **buf, loff_t max_size,
> +			     void **buf, size_t buf_size,
>   			     enum kernel_read_file_id id);
>   
>   #endif /* _LINUX_KERNEL_READ_FILE_H */
> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> index 97661ffabc4e..04f779c4f5ed 100644
> --- a/security/integrity/digsig.c
> +++ b/security/integrity/digsig.c
> @@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
>   	int rc;
>   	key_perm_t perm;
>   
> -	rc = kernel_read_file_from_path(path, &data, 0,
> +	rc = kernel_read_file_from_path(path, &data, INT_MAX,
>   					READING_X509_CERTIFICATE);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 602f52717757..692b83e82edf 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -284,7 +284,7 @@ static ssize_t ima_read_policy(char *path)
>   	datap = path;
>   	strsep(&datap, "\n");
>   
> -	rc = kernel_read_file_from_path(path, &data, 0, READING_POLICY);
> +	rc = kernel_read_file_from_path(path, &data, INT_MAX, READING_POLICY);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
>   		return rc;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument
  2020-07-22 19:30 ` [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument Kees Cook
@ 2020-07-23 17:36   ` Scott Branden
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:36 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

works.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> In preparation for adding partial read support, add an optional output
> argument to kernel_read_file*() that reports the file size so callers
> can reason more easily about their reading progress.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Scott Branden <scott.branden@broadcom.com>
> ---
>   drivers/base/firmware_loader/main.c |  1 +
>   fs/kernel_read_file.c               | 19 +++++++++++++------
>   include/linux/kernel_read_file.h    |  4 ++++
>   kernel/kexec_file.c                 |  4 ++--
>   kernel/module.c                     |  2 +-
>   security/integrity/digsig.c         |  2 +-
>   security/integrity/ima/ima_fs.c     |  2 +-
>   7 files changed, 23 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
> index f80c0d102be8..bd199404935f 100644
> --- a/drivers/base/firmware_loader/main.c
> +++ b/drivers/base/firmware_loader/main.c
> @@ -495,6 +495,7 @@ fw_get_filesystem_firmware(struct device *device, struct fw_priv *fw_priv,
>   
>   		/* load firmware files from the mount namespace of init */
>   		rc = kernel_read_file_from_path_initns(path, &buffer, msize,
> +						       NULL,
>   						       READING_FIRMWARE);
>   		if (rc < 0) {
>   			if (rc != -ENOENT)
> diff --git a/fs/kernel_read_file.c b/fs/kernel_read_file.c
> index e21a76001fff..2e29c38eb4df 100644
> --- a/fs/kernel_read_file.c
> +++ b/fs/kernel_read_file.c
> @@ -14,6 +14,8 @@
>    *		@buf_size will be ignored)
>    * @buf_size	size of buf, if already allocated. If @buf not
>    *		allocated, this is the largest size to allocate.
> + * @file_size	if non-NULL, the full size of @file will be
> + *		written here.
>    * @id		the kernel_read_file_id identifying the type of
>    *		file contents being read (for LSMs to examine)
>    *
> @@ -22,7 +24,8 @@
>    *
>    */
>   int kernel_read_file(struct file *file, void **buf,
> -		     size_t buf_size, enum kernel_read_file_id id)
> +		     size_t buf_size, size_t *file_size,
> +		     enum kernel_read_file_id id)
>   {
>   	loff_t i_size, pos;
>   	ssize_t bytes = 0;
> @@ -49,6 +52,8 @@ int kernel_read_file(struct file *file, void **buf,
>   		ret = -EFBIG;
>   		goto out;
>   	}
> +	if (file_size)
> +		*file_size = i_size;
>   
>   	if (!*buf)
>   		*buf = allocated = vmalloc(i_size);
> @@ -91,7 +96,8 @@ int kernel_read_file(struct file *file, void **buf,
>   EXPORT_SYMBOL_GPL(kernel_read_file);
>   
>   int kernel_read_file_from_path(const char *path, void **buf,
> -			       size_t buf_size, enum kernel_read_file_id id)
> +			       size_t buf_size, size_t *file_size,
> +			       enum kernel_read_file_id id)
>   {
>   	struct file *file;
>   	int ret;
> @@ -103,14 +109,14 @@ int kernel_read_file_from_path(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, buf_size, id);
> +	ret = kernel_read_file(file, buf, buf_size, file_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path);
>   
>   int kernel_read_file_from_path_initns(const char *path, void **buf,
> -				      size_t buf_size,
> +				      size_t buf_size, size_t *file_size,
>   				      enum kernel_read_file_id id)
>   {
>   	struct file *file;
> @@ -129,13 +135,14 @@ int kernel_read_file_from_path_initns(const char *path, void **buf,
>   	if (IS_ERR(file))
>   		return PTR_ERR(file);
>   
> -	ret = kernel_read_file(file, buf, buf_size, id);
> +	ret = kernel_read_file(file, buf, buf_size, file_size, id);
>   	fput(file);
>   	return ret;
>   }
>   EXPORT_SYMBOL_GPL(kernel_read_file_from_path_initns);
>   
>   int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
> +			     size_t *file_size,
>   			     enum kernel_read_file_id id)
>   {
>   	struct fd f = fdget(fd);
> @@ -144,7 +151,7 @@ int kernel_read_file_from_fd(int fd, void **buf, size_t buf_size,
>   	if (!f.file)
>   		goto out;
>   
> -	ret = kernel_read_file(f.file, buf, buf_size, id);
> +	ret = kernel_read_file(f.file, buf, buf_size, file_size, id);
>   out:
>   	fdput(f);
>   	return ret;
> diff --git a/include/linux/kernel_read_file.h b/include/linux/kernel_read_file.h
> index 910039e7593e..023293eaf948 100644
> --- a/include/linux/kernel_read_file.h
> +++ b/include/linux/kernel_read_file.h
> @@ -37,15 +37,19 @@ static inline const char *kernel_read_file_id_str(enum kernel_read_file_id id)
>   
>   int kernel_read_file(struct file *file,
>   		     void **buf, size_t buf_size,
> +		     size_t *file_size,
>   		     enum kernel_read_file_id id);
>   int kernel_read_file_from_path(const char *path,
>   			       void **buf, size_t buf_size,
> +			       size_t *file_size,
>   			       enum kernel_read_file_id id);
>   int kernel_read_file_from_path_initns(const char *path,
>   				      void **buf, size_t buf_size,
> +				      size_t *file_size,
>   				      enum kernel_read_file_id id);
>   int kernel_read_file_from_fd(int fd,
>   			     void **buf, size_t buf_size,
> +			     size_t *file_size,
>   			     enum kernel_read_file_id id);
>   
>   #endif /* _LINUX_KERNEL_READ_FILE_H */
> diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
> index eda19ca256a3..878ca684a3a1 100644
> --- a/kernel/kexec_file.c
> +++ b/kernel/kexec_file.c
> @@ -222,7 +222,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   	void *ldata;
>   
>   	ret = kernel_read_file_from_fd(kernel_fd, &image->kernel_buf,
> -				       INT_MAX, READING_KEXEC_IMAGE);
> +				       INT_MAX, NULL, READING_KEXEC_IMAGE);
>   	if (ret < 0)
>   		return ret;
>   	image->kernel_buf_len = ret;
> @@ -242,7 +242,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
>   	/* It is possible that there no initramfs is being loaded */
>   	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
>   		ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf,
> -					       INT_MAX,
> +					       INT_MAX, NULL,
>   					       READING_KEXEC_INITRAMFS);
>   		if (ret < 0)
>   			goto out;
> diff --git a/kernel/module.c b/kernel/module.c
> index b6fd4f51cc30..860d713dd910 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -4001,7 +4001,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
>   		      |MODULE_INIT_IGNORE_VERMAGIC))
>   		return -EINVAL;
>   
> -	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX,
> +	err = kernel_read_file_from_fd(fd, &hdr, INT_MAX, NULL,
>   				       READING_MODULE);
>   	if (err < 0)
>   		return err;
> diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
> index 04f779c4f5ed..8a523dfd7fd7 100644
> --- a/security/integrity/digsig.c
> +++ b/security/integrity/digsig.c
> @@ -175,7 +175,7 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
>   	int rc;
>   	key_perm_t perm;
>   
> -	rc = kernel_read_file_from_path(path, &data, INT_MAX,
> +	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL,
>   					READING_X509_CERTIFICATE);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 692b83e82edf..5fc56ccb6678 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -284,7 +284,7 @@ static ssize_t ima_read_policy(char *path)
>   	datap = path;
>   	strsep(&datap, "\n");
>   
> -	rc = kernel_read_file_from_path(path, &data, INT_MAX, READING_POLICY);
> +	rc = kernel_read_file_from_path(path, &data, INT_MAX, NULL, READING_POLICY);
>   	if (rc < 0) {
>   		pr_err("Unable to open file: %s (%d)", path, rc);
>   		return rc;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook
  2020-07-22 19:30 ` [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook Kees Cook
@ 2020-07-23 17:39   ` Scott Branden
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-23 17:39 UTC (permalink / raw)
  To: Kees Cook, Greg Kroah-Hartman
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Dmitry Kasatkin, Stephen Smalley,
	Randy Dunlap, kexec, linux-kernel, Luis Chamberlain,
	Eric Biederman, Dave Olsthoorn, Jessica Yu, Casey Schaufler,
	Joe Perches, Andrew Morton, Thiago Jung Bauermann

Patch 11-14 work for me but I have little knowledge to comment on these 
patches.

On 2020-07-22 12:30 p.m., Kees Cook wrote:
> There are a few places in the kernel where LSMs would like to have
> visibility into the contents of a kernel buffer that has been loaded or
> read. While security_kernel_post_read_file() (which includes the
> buffer) exists as a pairing for security_kernel_read_file(), no such
> hook exists to pair with security_kernel_load_data().
>
> Earlier proposals for just using security_kernel_post_read_file() with a
> NULL file argument were rejected (i.e. "file" should always be valid for
> the security_..._file hooks, but it appears at least one case was
> left in the kernel during earlier refactoring. (This will be fixed in
> a subsequent patch.)
>
> Since not all cases of security_kernel_load_data() can have a single
> contiguous buffer made available to the LSM hook (e.g. kexec image
> segments are separately loaded), there needs to be a way for the LSM to
> reason about its expectations of the hook coverage. In order to handle
> this, add a "contents" argument to the "kernel_load_data" hook that
> indicates if the newly added "kernel_post_load_data" hook will be called
> with the full contents once loaded. That way, LSMs requiring full contents
> can choose to unilaterally reject "kernel_load_data" with contents=false
> (which is effectively the existing hook coverage), but when contents=true
> they can allow it and later evaluate the "kernel_post_load_data" hook
> once the buffer is loaded.
>
> With this change, LSMs can gain coverage over non-file-backed data loads
> (e.g. init_module(2) and firmware userspace helper), which will happen
> in subsequent patches.
>
> Additionally prepare IMA to start processing these cases.
>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>   drivers/base/firmware_loader/fallback.c       |  2 +-
>   .../base/firmware_loader/fallback_platform.c  |  2 +-
>   include/linux/ima.h                           | 12 +++++++++--
>   include/linux/lsm_hook_defs.h                 |  4 +++-
>   include/linux/lsm_hooks.h                     |  9 ++++++++
>   include/linux/security.h                      | 12 +++++++++--
>   kernel/kexec.c                                |  2 +-
>   kernel/module.c                               |  2 +-
>   security/integrity/ima/ima_main.c             | 21 ++++++++++++++++++-
>   security/loadpin/loadpin.c                    |  2 +-
>   security/security.c                           | 18 +++++++++++++---
>   security/selinux/hooks.c                      |  2 +-
>   12 files changed, 73 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
> index 5327bfc6ba71..a196aacce22c 100644
> --- a/drivers/base/firmware_loader/fallback.c
> +++ b/drivers/base/firmware_loader/fallback.c
> @@ -613,7 +613,7 @@ static bool fw_run_sysfs_fallback(u32 opt_flags)
>   		return false;
>   
>   	/* Also permit LSMs and IMA to fail firmware sysfs fallback */
> -	ret = security_kernel_load_data(LOADING_FIRMWARE);
> +	ret = security_kernel_load_data(LOADING_FIRMWARE, false);
>   	if (ret < 0)
>   		return false;
>   
> diff --git a/drivers/base/firmware_loader/fallback_platform.c b/drivers/base/firmware_loader/fallback_platform.c
> index 6958ab1a8059..a12c79d47efc 100644
> --- a/drivers/base/firmware_loader/fallback_platform.c
> +++ b/drivers/base/firmware_loader/fallback_platform.c
> @@ -17,7 +17,7 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
>   	if (!(opt_flags & FW_OPT_FALLBACK_PLATFORM))
>   		return -ENOENT;
>   
> -	rc = security_kernel_load_data(LOADING_FIRMWARE);
> +	rc = security_kernel_load_data(LOADING_FIRMWARE, false);
>   	if (rc)
>   		return rc;
>   
> diff --git a/include/linux/ima.h b/include/linux/ima.h
> index 148636bfcc8f..502e36ad7804 100644
> --- a/include/linux/ima.h
> +++ b/include/linux/ima.h
> @@ -20,7 +20,9 @@ extern void ima_post_create_tmpfile(struct inode *inode);
>   extern void ima_file_free(struct file *file);
>   extern int ima_file_mmap(struct file *file, unsigned long prot);
>   extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
> -extern int ima_load_data(enum kernel_load_data_id id);
> +extern int ima_load_data(enum kernel_load_data_id id, bool contents);
> +extern int ima_post_load_data(char *buf, loff_t size,
> +			      enum kernel_load_data_id id);
>   extern int ima_read_file(struct file *file, enum kernel_read_file_id id);
>   extern int ima_post_read_file(struct file *file, void *buf, loff_t size,
>   			      enum kernel_read_file_id id);
> @@ -78,7 +80,13 @@ static inline int ima_file_mprotect(struct vm_area_struct *vma,
>   	return 0;
>   }
>   
> -static inline int ima_load_data(enum kernel_load_data_id id)
> +static inline int ima_load_data(enum kernel_load_data_id id, bool contents)
> +{
> +	return 0;
> +}
> +
> +static inline int ima_post_load_data(char *buf, loff_t size,
> +				     enum kernel_load_data_id id)
>   {
>   	return 0;
>   }
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 6791813cd439..aaa2916bbae7 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -184,7 +184,9 @@ LSM_HOOK(void, LSM_RET_VOID, cred_getsecid, const struct cred *c, u32 *secid)
>   LSM_HOOK(int, 0, kernel_act_as, struct cred *new, u32 secid)
>   LSM_HOOK(int, 0, kernel_create_files_as, struct cred *new, struct inode *inode)
>   LSM_HOOK(int, 0, kernel_module_request, char *kmod_name)
> -LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id)
> +LSM_HOOK(int, 0, kernel_load_data, enum kernel_load_data_id id, bool contents)
> +LSM_HOOK(int, 0, kernel_post_load_data, char *buf, loff_t size,
> +	 enum kernel_read_file_id id)
>   LSM_HOOK(int, 0, kernel_read_file, struct file *file,
>   	 enum kernel_read_file_id id)
>   LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf,
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 95b7c1d32062..812d626195fc 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -635,7 +635,16 @@
>    * @kernel_load_data:
>    *	Load data provided by userspace.
>    *	@id kernel load data identifier
> + *	@contents if a subsequent @kernel_post_load_data will be called.
>    *	Return 0 if permission is granted.
> + * @kernel_post_load_data:
> + *	Load data provided by a non-file source (usually userspace buffer).
> + *	@buf pointer to buffer containing the data contents.
> + *	@size length of the data contents.
> + *	@id kernel load data identifier
> + *	Return 0 if permission is granted.
> + *	This must be paired with a prior @kernel_load_data call that had
> + *	@contents set to true.
>    * @kernel_read_file:
>    *	Read a file specified by userspace.
>    *	@file contains the file structure pointing to the file being read
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 42df0d9b4c37..e748974c707b 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -387,7 +387,9 @@ void security_cred_getsecid(const struct cred *c, u32 *secid);
>   int security_kernel_act_as(struct cred *new, u32 secid);
>   int security_kernel_create_files_as(struct cred *new, struct inode *inode);
>   int security_kernel_module_request(char *kmod_name);
> -int security_kernel_load_data(enum kernel_load_data_id id);
> +int security_kernel_load_data(enum kernel_load_data_id id, bool contents);
> +int security_kernel_post_load_data(char *buf, loff_t size,
> +				   enum kernel_load_data_id id);
>   int security_kernel_read_file(struct file *file, enum kernel_read_file_id id);
>   int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>   				   enum kernel_read_file_id id);
> @@ -1014,7 +1016,13 @@ static inline int security_kernel_module_request(char *kmod_name)
>   	return 0;
>   }
>   
> -static inline int security_kernel_load_data(enum kernel_load_data_id id)
> +static inline int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
> +{
> +	return 0;
> +}
> +
> +static inline int security_kernel_post_load_data(char *buf, loff_t size,
> +						 enum kernel_load_data_id id)
>   {
>   	return 0;
>   }
> diff --git a/kernel/kexec.c b/kernel/kexec.c
> index f977786fe498..c82c6c06f051 100644
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -205,7 +205,7 @@ static inline int kexec_load_check(unsigned long nr_segments,
>   		return -EPERM;
>   
>   	/* Permit LSMs and IMA to fail the kexec */
> -	result = security_kernel_load_data(LOADING_KEXEC_IMAGE);
> +	result = security_kernel_load_data(LOADING_KEXEC_IMAGE, false);
>   	if (result < 0)
>   		return result;
>   
> diff --git a/kernel/module.c b/kernel/module.c
> index 860d713dd910..d56cb34d9a2f 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2967,7 +2967,7 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
>   	if (info->len < sizeof(*(info->hdr)))
>   		return -ENOEXEC;
>   
> -	err = security_kernel_load_data(LOADING_MODULE);
> +	err = security_kernel_load_data(LOADING_MODULE, false);
>   	if (err)
>   		return err;
>   
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index dab4a13221cf..85000dc8595c 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -676,6 +676,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>   /**
>    * ima_load_data - appraise decision based on policy
>    * @id: kernel load data caller identifier
> + * @contents: whether the full contents will be available in a later
> + *	      call to ima_post_load_data().
>    *
>    * Callers of this LSM hook can not measure, appraise, or audit the
>    * data provided by userspace.  Enforce policy rules requring a file
> @@ -683,7 +685,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
>    *
>    * For permission return 0, otherwise return -EACCES.
>    */
> -int ima_load_data(enum kernel_load_data_id id)
> +int ima_load_data(enum kernel_load_data_id id, bool contents)
>   {
>   	bool ima_enforce, sig_enforce;
>   
> @@ -723,6 +725,23 @@ int ima_load_data(enum kernel_load_data_id id)
>   	return 0;
>   }
>   
> +/**
> + * ima_post_load_data - appraise decision based on policy
> + * @buf: pointer to in memory file contents
> + * @size: size of in memory file contents
> + * @id: kernel load data caller identifier
> + *
> + * Measure/appraise/audit in memory buffer based on policy.  Policy rules
> + * are written in terms of a policy identifier.
> + *
> + * On success return 0.  On integrity appraisal error, assuming the file
> + * is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
> + */
> +int ima_post_load_data(char *buf, loff_t size, enum kernel_load_data_id load_id)
> +{
> +	return 0;
> +}
> +
>   /*
>    * process_buffer_measurement - Measure the buffer to ima log.
>    * @buf: pointer to the buffer that needs to be added to the log.
> diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
> index 81bc95127f92..db320a43f42e 100644
> --- a/security/loadpin/loadpin.c
> +++ b/security/loadpin/loadpin.c
> @@ -176,7 +176,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id)
>   	return 0;
>   }
>   
> -static int loadpin_load_data(enum kernel_load_data_id id)
> +static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
>   {
>   	return loadpin_read_file(NULL, (enum kernel_read_file_id) id);
>   }
> diff --git a/security/security.c b/security/security.c
> index f5920115a325..090674f1197a 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1680,17 +1680,29 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
>   }
>   EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
>   
> -int security_kernel_load_data(enum kernel_load_data_id id)
> +int security_kernel_load_data(enum kernel_load_data_id id, bool contents)
>   {
>   	int ret;
>   
> -	ret = call_int_hook(kernel_load_data, 0, id);
> +	ret = call_int_hook(kernel_load_data, 0, id, contents);
>   	if (ret)
>   		return ret;
> -	return ima_load_data(id);
> +	return ima_load_data(id, contents);
>   }
>   EXPORT_SYMBOL_GPL(security_kernel_load_data);
>   
> +int security_kernel_post_load_data(char *buf, loff_t size,
> +				   enum kernel_load_data_id id)
> +{
> +	int ret;
> +
> +	ret = call_int_hook(kernel_post_load_data, 0, buf, size, id);
> +	if (ret)
> +		return ret;
> +	return ima_post_load_data(buf, size, id);
> +}
> +EXPORT_SYMBOL_GPL(security_kernel_post_load_data);
> +
>   int security_task_fix_setuid(struct cred *new, const struct cred *old,
>   			     int flags)
>   {
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 5de45010fb1a..1a5c68196faf 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4019,7 +4019,7 @@ static int selinux_kernel_read_file(struct file *file,
>   	return rc;
>   }
>   
> -static int selinux_kernel_load_data(enum kernel_load_data_id id)
> +static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
>   {
>   	int rc = 0;
>   


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-22 22:29   ` Scott Branden
  2020-07-23  6:23     ` Scott Branden
@ 2020-07-23 19:15     ` Kees Cook
  2020-07-24  5:41       ` Scott Branden
  1 sibling, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-23 19:15 UTC (permalink / raw)
  To: Scott Branden
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Wed, Jul 22, 2020 at 03:29:26PM -0700, Scott Branden wrote:
> These changes don't pass the kernel-selftest for partial reads I added
> (which are at the end of this patch v2 series).

Oh, interesting. Is there any feedback in dmesg? I wonder if I have the
LSMs configured differently than you?

> See change below added for temp workaround for issue.

> > [...]
> > +
> > +	whole_file = (offset == 0 && i_size <= buf_size);
> A hack to get this passing I added which probably breaks some security?
> if (whole_file) {
> > +	ret = security_kernel_read_file(file, id, whole_file);
> > +	if (ret)
> > +		goto out;
> > +
> }

This would imply I did something wrong in the LSM hook refactoring (i.e.
some LSM is rejecting the !whole_file case, but if the entire call to
the hooks are skipped, it's okay).

What does this return on your test system:

	echo $(cat /sys/kernel/security/lsm)

(I wonder if I have IMA configured differently...)

Mimi, have you had a chance to test these changes?

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-23  6:23     ` Scott Branden
@ 2020-07-23 19:17       ` Kees Cook
  2020-07-24  5:46         ` Scott Branden
  0 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-23 19:17 UTC (permalink / raw)
  To: Scott Branden
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Wed, Jul 22, 2020 at 11:23:43PM -0700, Scott Branden wrote:
> I made an adjustment in the logic of the driver with use of
> request_partial_firmware_into_buf and now everything is working.

Excellent! Was there something wrong with how I ported the
request_partial_firmware_into_buf() changes? (Should the behavior be
changed in some way? I didn't change the self-tests, so I thought the
behavior matched your original series.)

> So only issue I find with this entire patch series is the problem
> of security failing without the workaround below.

Yup; I'm trying to reproduce this now too...

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-23 19:15     ` Kees Cook
@ 2020-07-24  5:41       ` Scott Branden
  2020-07-24 18:23         ` Kees Cook
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Branden @ 2020-07-24  5:41 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

[-- Attachment #1: Type: text/plain, Size: 1459 bytes --]



On 2020-07-23 12:15 p.m., Kees Cook wrote:
> On Wed, Jul 22, 2020 at 03:29:26PM -0700, Scott Branden wrote:
>> These changes don't pass the kernel-selftest for partial reads I added
>> (which are at the end of this patch v2 series).
> Oh, interesting. Is there any feedback in dmesg? I wonder if I have the
> LSMs configured differently than you?
I have no LSMs configured that I know of.
Yes, there is failure in dmesg which is how I determined to add my 
workaround.
Without workaround, dmesg log attached after booting and running 
fw_run_tests.h
>> See change below added for temp workaround for issue.
>>> [...]
>>> +
>>> +	whole_file = (offset == 0 && i_size <= buf_size);
>> A hack to get this passing I added which probably breaks some security?
>> if (whole_file) {
>>> +	ret = security_kernel_read_file(file, id, whole_file);
>>> +	if (ret)
>>> +		goto out;
>>> +
>> }
> This would imply I did something wrong in the LSM hook refactoring (i.e.
> some LSM is rejecting the !whole_file case, but if the entire call to
> the hooks are skipped, it's okay).
>
> What does this return on your test system:
>
> 	echo $(cat /sys/kernel/security/lsm)
ima kernel configs are enabled but I don't enable security policies
on the kernel command line.

echo $(cat /sys/kernel/security/lsm)
cat: /sys/kernel/security/lsm: No such file or directory

>
> (I wonder if I have IMA configured differently...)
>
> Mimi, have you had a chance to test these changes?
>


[-- Attachment #2: out.txt --]
[-- Type: text/plain, Size: 106350 bytes --]

[    0.000000] Linux version 5.8.0-rc6 (oe-user@oe-host) (x86_64-poky-linux-gcc (GCC) 10.1.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Wed Jul 22 22:13:12 UTC 2020
[    0.000000] Command line: BOOT_IMAGE=/bzImage ip=dhcp raid=noautodetect console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfs/vxc,hard,tcp,intr,v3 rootwait nfsrootdebug
[    0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[    0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
[    0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
[    0.000000] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[    0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'compacted' format.
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009d3ff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009d400-0x000000000009ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000000e0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x0000000009d01fff] usable
[    0.000000] BIOS-e820: [mem 0x0000000009d02000-0x0000000009ffffff] reserved
[    0.000000] BIOS-e820: [mem 0x000000000a000000-0x000000000a1fffff] usable
[    0.000000] BIOS-e820: [mem 0x000000000a200000-0x000000000a20bfff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x000000000a20c000-0x00000000d8983fff] usable
[    0.000000] BIOS-e820: [mem 0x00000000d8984000-0x00000000d8acdfff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000d8ace000-0x00000000d8c56fff] ACPI data
[    0.000000] BIOS-e820: [mem 0x00000000d8c57000-0x00000000d9107fff] ACPI NVS
[    0.000000] BIOS-e820: [mem 0x00000000d9108000-0x00000000da55cfff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000da55d000-0x00000000dcffffff] usable
[    0.000000] BIOS-e820: [mem 0x00000000dd000000-0x00000000dfffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000f8000000-0x00000000fbffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fd000000-0x00000000ffffffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000041f37ffff] usable
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] SMBIOS 3.2.0 present.
[    0.000000] DMI: System manufacturer System Product Name/PRIME X570-P, BIOS 1405 11/19/2019
[    0.000000] tsc: Fast TSC calibration failed
[    0.000000] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[    0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable
[    0.000000] last_pfn = 0x41f380 max_arch_pfn = 0x400000000
[    0.000000] MTRR default type: uncachable
[    0.000000] MTRR fixed ranges enabled:
[    0.000000]   00000-9FFFF write-back
[    0.000000]   A0000-BFFFF write-through
[    0.000000]   C0000-FFFFF write-protect
[    0.000000] MTRR variable ranges enabled:
[    0.000000]   0 base 000000000000 mask FFFF80000000 write-back
[    0.000000]   1 base 000080000000 mask FFFFC0000000 write-back
[    0.000000]   2 base 0000C0000000 mask FFFFE0000000 write-back
[    0.000000]   3 base 0000D9CB0000 mask FFFFFFFF0000 uncachable
[    0.000000]   4 disabled
[    0.000000]   5 disabled
[    0.000000]   6 disabled
[    0.000000]   7 disabled
[    0.000000] TOM2: 0000000420000000 aka 16896M
[    0.000000] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
[    0.000000] e820: update [mem 0xd9cb0000-0xd9cbffff] usable ==> reserved
[    0.000000] e820: update [mem 0xe0000000-0xffffffff] usable ==> reserved
[    0.000000] last_pfn = 0xdd000 max_arch_pfn = 0x400000000
[    0.000000] check: Scanning 1 areas for low memory corruption
[    0.000000] Using GB pages for direct mapping
[    0.000000] ACPI: Early table checksum verification disabled
[    0.000000] ACPI: RSDP 0x00000000000F05A0 000024 (v02 ALASKA)
[    0.000000] ACPI: XSDT 0x00000000D8BF30A0 0000BC (v01 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: FACP 0x00000000D8BFEBF0 000114 (v06 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: DSDT 0x00000000D8BF31F8 00B9F4 (v02 ALASKA A M I    01072009 INTL 20120913)
[    0.000000] ACPI: FACS 0x00000000D90F0E00 000040
[    0.000000] ACPI: APIC 0x00000000D8BFED08 00015E (v03 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: FPDT 0x00000000D8BFEE68 000044 (v01 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: FIDT 0x00000000D8BFEEB0 00009C (v01 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: SSDT 0x00000000D8BFEF50 0000C8 (v02 ALASKA CPUSSDT  01072009 AMI  01072009)
[    0.000000] ACPI: WSMT 0x00000000D8C10E08 000028 (v01 ALASKA A M I    01072009 AMI  00010013)
[    0.000000] ACPI: SSDT 0x00000000D8BFF070 008C98 (v02 AMD    AMD ALIB 00000002 MSFT 04000000)
[    0.000000] ACPI: SSDT 0x00000000D8C07D08 00368A (v01 AMD    AMD AOD  00000001 INTL 20120913)
[    0.000000] ACPI: MCFG 0x00000000D8C0B398 00003C (v01 ALASKA A M I    01072009 MSFT 00010013)
[    0.000000] ACPI: HPET 0x00000000D8C0B3D8 000038 (v01 ALASKA A M I    01072009 AMI  00000005)
[    0.000000] ACPI: SSDT 0x00000000D8C0B410 000024 (v01 AMD    BIXBY    00001000 INTL 20120913)
[    0.000000] ACPI: UEFI 0x00000000D8C0B438 000042 (v01 ALASKA A M I    00000002      01000013)
[    0.000000] ACPI: WPBT 0x00000000D8C0B480 00003C (v01 ALASKA A M I    00000001 ASUS 00000001)
[    0.000000] ACPI: IVRS 0x00000000D8C0B4C0 0000D0 (v02 AMD    AMD IVRS 00000001 AMD  00000000)
[    0.000000] ACPI: PCCT 0x00000000D8C0B590 00006E (v01 AMD    AMD PCCT 00000001 AMD  00000000)
[    0.000000] ACPI: SSDT 0x00000000D8C0B600 002F29 (v01 AMD    AMD CPU  00000001 AMD  00000001)
[    0.000000] ACPI: CRAT 0x00000000D8C0E530 000B58 (v01 AMD    AMD CRAT 00000001 AMD  00000001)
[    0.000000] ACPI: CDIT 0x00000000D8C0F088 000029 (v01 AMD    AMD CDIT 00000001 AMD  00000001)
[    0.000000] ACPI: SSDT 0x00000000D8C0F0B8 001D4A (v01 AMD    AmdTable 00000001 INTL 20120913)
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] No NUMA configuration found
[    0.000000] Faking a node at [mem 0x0000000000000000-0x000000041f37ffff]
[    0.000000] NODE_DATA(0) allocated [mem 0x41f37c000-0x41f37ffff]
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.000000]   DMA32    [mem 0x0000000001000000-0x00000000ffffffff]
[    0.000000]   Normal   [mem 0x0000000100000000-0x000000041f37ffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000001000-0x000000000009cfff]
[    0.000000]   node   0: [mem 0x0000000000100000-0x0000000009d01fff]
[    0.000000]   node   0: [mem 0x000000000a000000-0x000000000a1fffff]
[    0.000000]   node   0: [mem 0x000000000a20c000-0x00000000d8983fff]
[    0.000000]   node   0: [mem 0x00000000da55d000-0x00000000dcffffff]
[    0.000000]   node   0: [mem 0x0000000100000000-0x000000041f37ffff]
[    0.000000] Zeroed struct page in unavailable ranges: 23495 pages
[    0.000000] Initmem setup node 0 [mem 0x0000000000001000-0x000000041f37ffff]
[    0.000000] On node 0 totalpages: 4170809
[    0.000000]   DMA zone: 64 pages used for memmap
[    0.000000]   DMA zone: 21 pages reserved
[    0.000000]   DMA zone: 3996 pages, LIFO batch:0
[    0.000000]   DMA32 zone: 13957 pages used for memmap
[    0.000000]   DMA32 zone: 893213 pages, LIFO batch:63
[    0.000000]   Normal zone: 51150 pages used for memmap
[    0.000000]   Normal zone: 3273600 pages, LIFO batch:63
[    0.000000] ACPI: PM-Timer IO Port: 0x808
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] ACPI: LAPIC_NMI (acpi_id[0xff] high edge lint[0x1])
[    0.000000] IOAPIC[0]: apic_id 13, version 33, address 0xfec00000, GSI 0-23
[    0.000000] IOAPIC[1]: apic_id 14, version 33, address 0xfec01000, GSI 24-55
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
[    0.000000] ACPI: IRQ0 used by override.
[    0.000000] ACPI: IRQ9 used by override.
[    0.000000] Using ACPI (MADT) for SMP configuration information
[    0.000000] ACPI: HPET id: 0x10228201 base: 0xfed00000
[    0.000000] smpboot: Allowing 32 CPUs, 20 hotplug CPUs
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x0009d000-0x0009dfff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x0009e000-0x0009ffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x000a0000-0x000dffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x000e0000-0x000fffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x09d02000-0x09ffffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0x0a200000-0x0a20bfff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xd8984000-0xd8acdfff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xd8ace000-0xd8c56fff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xd8c57000-0xd9107fff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xd9108000-0xda55cfff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xdd000000-0xdfffffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xe0000000-0xf7ffffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xf8000000-0xfbffffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xfc000000-0xfcffffff]
[    0.000000] PM: hibernation: Registered nosave memory: [mem 0xfd000000-0xffffffff]
[    0.000000] [mem 0xe0000000-0xf7ffffff] available for PCI devices
[    0.000000] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns
[    0.000000] setup_percpu: NR_CPUS:64 nr_cpumask_bits:64 nr_cpu_ids:32 nr_node_ids:1
[    0.000000] percpu: Embedded 52 pages/cpu s172760 r8192 d32040 u262144
[    0.000000] pcpu-alloc: s172760 r8192 d32040 u262144 alloc=1*2097152
[    0.000000] pcpu-alloc: [0] 00 01 02 03 04 05 06 07 [0] 08 09 10 11 12 13 14 15 
[    0.000000] pcpu-alloc: [0] 16 17 18 19 20 21 22 23 [0] 24 25 26 27 28 29 30 31 
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 4105617
[    0.000000] Policy zone: Normal
[    0.000000] Kernel command line: BOOT_IMAGE=/bzImage ip=dhcp raid=noautodetect console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfs/vxc,hard,tcp,intr,v3 rootwait nfsrootdebug
[    0.000000] Dentry cache hash table entries: 2097152 (order: 12, 16777216 bytes, linear)
[    0.000000] Inode-cache hash table entries: 1048576 (order: 11, 8388608 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 16288896K/16683236K available (16388K kernel code, 1982K rwdata, 4144K rodata, 1604K init, 1484K bss, 394340K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=32, Nodes=1
[    0.000000] ftrace: allocating 48968 entries in 192 pages
[    0.000000] ftrace: allocated 192 pages with 2 groups
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu: 	RCU event tracing is enabled.
[    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=32.
[    0.000000] 	Rude variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=32
[    0.000000] NR_IRQS: 4352, nr_irqs: 1224, preallocated irqs: 16
[    0.000000] random: get_random_bytes called from start_kernel+0x361/0x531 with crng_init=0
[    0.000000] Console: colour VGA+ 80x25
[    0.000000] printk: console [ttyS0] enabled
[    0.000000] ACPI: Core revision 20200528
[    0.000000] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 133484873504 ns
[    0.000000] APIC: Switch to symmetric I/O mode setup
[    0.001000] Switched APIC routing to physical flat.
[    0.003000] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.010000] tsc: PIT calibration matches HPET. 2 loops
[    0.011000] tsc: Detected 3792.935 MHz processor
[    0.000003] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x6d588d6a09c, max_idle_ns: 881590727049 ns
[    0.010768] Calibrating delay loop (skipped), value calculated using timer frequency.. 7585.87 BogoMIPS (lpj=3792935)
[    0.011768] pid_max: default: 32768 minimum: 301
[    0.012779] LSM: Security Framework initializing
[    0.013772] SELinux:  Initializing.
[    0.014803] Mount-cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    0.015791] Mountpoint-cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[    0.016878] x86/cpu: User Mode Instruction Prevention (UMIP) activated
[    0.017816] LVT offset 1 assigned for vector 0xf9
[    0.018900] LVT offset 2 assigned for vector 0xf4
[    0.019803] Last level iTLB entries: 4KB 1024, 2MB 1024, 4MB 512
[    0.020768] Last level dTLB entries: 4KB 2048, 2MB 2048, 4MB 1024, 1GB 0
[    0.021769] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization
[    0.022768] Spectre V2 : Mitigation: Full AMD retpoline
[    0.023768] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch
[    0.024769] Spectre V2 : mitigation: Enabling conditional Indirect Branch Prediction Barrier
[    0.025768] Spectre V2 : User space: Mitigation: STIBP via seccomp and prctl
[    0.026768] Speculative Store Bypass: Mitigation: Speculative Store Bypass disabled via prctl and seccomp
[    0.027961] Freeing SMP alternatives memory: 44K
[    0.132653] smpboot: CPU0: AMD Ryzen 5 3600X 6-Core Processor (family: 0x17, model: 0x71, stepping: 0x0)
[    0.132812] Performance Events: Fam17h+ core perfctr, AMD PMU driver.
[    0.133768] ... version:                0
[    0.134768] ... bit width:              48
[    0.135768] ... generic registers:      6
[    0.136768] ... value mask:             0000ffffffffffff
[    0.137768] ... max period:             00007fffffffffff
[    0.138768] ... fixed-purpose events:   0
[    0.139768] ... event mask:             000000000000003f
[    0.141776] rcu: Hierarchical SRCU implementation.
[    0.144060] smp: Bringing up secondary CPUs ...
[    0.144805] x86: Booting SMP configuration:
[    0.145768] .... node  #0, CPUs:        #1  #2  #3  #4  #5  #6  #7  #8  #9 #10 #11
[    0.158783] smp: Brought up 1 node, 12 CPUs
[    0.160769] smpboot: Max logical packages: 3
[    0.161768] smpboot: Total of 12 processors activated (91030.44 BogoMIPS)
[    0.164205] devtmpfs: initialized
[    0.167814] PM: Registering ACPI NVS region [mem 0x0a200000-0x0a20bfff] (49152 bytes)
[    0.174769] PM: Registering ACPI NVS region [mem 0xd8c57000-0xd9107fff] (4919296 bytes)
[    0.183774] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    0.192772] futex hash table entries: 8192 (order: 7, 524288 bytes, linear)
[    0.199956] PM: RTC time: 13:13:08, date: 2020-07-24
[    0.204769] thermal_sys: Registered thermal governor 'step_wise'
[    0.204769] thermal_sys: Registered thermal governor 'user_space'
[    0.210831] NET: Registered protocol family 16
[    0.221810] audit: initializing netlink subsys (disabled)
[    0.226775] audit: type=2000 audit(1595596387.230:1): state=initialized audit_enabled=0 res=1
[    0.235770] cpuidle: using governor menu
[    0.236776] Detected 1 PCC Subspaces
[    0.237778] Registering PCC driver as Mailbox controller
[    0.238787] ACPI: bus type PCI registered
[    0.242803] PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xf8000000-0xfbffffff] (base 0xf8000000)
[    0.251770] PCI: MMCONFIG at [mem 0xf8000000-0xfbffffff] reserved in E820
[    0.258774] PCI: Using configuration type 1 for base access
[    0.265897] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.272780] cryptomgr_test (79) used greatest stack depth: 15712 bytes left
[    0.279597] cryptomgr_test (83) used greatest stack depth: 15376 bytes left
[    0.286768] cryptomgr_test (84) used greatest stack depth: 15240 bytes left
[    0.293796] ACPI: Added _OSI(Module Device)
[    0.297770] ACPI: Added _OSI(Processor Device)
[    0.301769] ACPI: Added _OSI(3.0 _SCP Extensions)
[    0.306768] ACPI: Added _OSI(Processor Aggregator Device)
[    0.311769] ACPI: Added _OSI(Linux-Dell-Video)
[    0.316768] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)
[    0.321768] ACPI: Added _OSI(Linux-HPI-Hybrid-Graphics)
[    0.331982] ACPI: 7 ACPI AML tables successfully acquired and loaded
[    0.339153] ACPI: [Firmware Bug]: BIOS _OSI(Linux) query ignored
[    0.346574] ACPI: Interpreter enabled
[    0.350777] ACPI: (supports S0 S3 S4 S5)
[    0.354768] ACPI: Using IOAPIC for interrupt routing
[    0.359960] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.368918] ACPI: Enabled 2 GPEs in block 00 to 1F
[    0.378193] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.383771] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
[    0.392848] acpi PNP0A08:00: _OSC: platform does not support [PCIeHotplug PME LTR]
[    0.400842] acpi PNP0A08:00: _OSC: OS now controls [PCIeCapability]
[    0.406774] acpi PNP0A08:00: [Firmware Info]: MMCONFIG for domain 0000 [bus 00-3f] only partially covers this bridge
[    0.417839] PCI host bridge to bus 0000:00
[    0.421769] pci_bus 0000:00: root bus resource [io  0x0000-0x03af window]
[    0.428768] pci_bus 0000:00: root bus resource [io  0x03e0-0x0cf7 window]
[    0.434768] pci_bus 0000:00: root bus resource [io  0x03b0-0x03df window]
[    0.441768] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    0.448768] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
[    0.455768] pci_bus 0000:00: root bus resource [mem 0x000c0000-0x000dffff window]
[    0.463768] pci_bus 0000:00: root bus resource [mem 0xe0000000-0xf7ffffff window]
[    0.470768] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.476769] pci_bus 0000:00: scanning bus
[    0.476775] pci 0000:00:00.0: [1022:1480] type 00 class 0x060000
[    0.482849] pci 0000:00:00.2: [1022:1481] type 00 class 0x080600
[    0.488857] pci 0000:00:01.0: [1022:1482] type 00 class 0x060000
[    0.494829] pci 0000:00:01.2: [1022:1483] type 01 class 0x060400
[    0.500800] pci 0000:00:01.2: enabling Extended Tags
[    0.505813] pci 0000:00:01.2: PME# supported from D0 D3hot D3cold
[    0.511770] pci 0000:00:01.2: PME# disabled
[    0.511850] pci 0000:00:02.0: [1022:1482] type 00 class 0x060000
[    0.517831] pci 0000:00:03.0: [1022:1482] type 00 class 0x060000
[    0.523826] pci 0000:00:03.1: [1022:1483] type 01 class 0x060400
[    0.530797] pci 0000:00:03.1: PME# supported from D0 D3hot D3cold
[    0.536769] pci 0000:00:03.1: PME# disabled
[    0.536855] pci 0000:00:04.0: [1022:1482] type 00 class 0x060000
[    0.542832] pci 0000:00:05.0: [1022:1482] type 00 class 0x060000
[    0.548831] pci 0000:00:07.0: [1022:1482] type 00 class 0x060000
[    0.554825] pci 0000:00:07.1: [1022:1484] type 01 class 0x060400
[    0.560797] pci 0000:00:07.1: enabling Extended Tags
[    0.565804] pci 0000:00:07.1: PME# supported from D0 D3hot D3cold
[    0.571769] pci 0000:00:07.1: PME# disabled
[    0.571840] pci 0000:00:08.0: [1022:1482] type 00 class 0x060000
[    0.577826] pci 0000:00:08.1: [1022:1484] type 01 class 0x060400
[    0.583799] pci 0000:00:08.1: enabling Extended Tags
[    0.588808] pci 0000:00:08.1: PME# supported from D0 D3hot D3cold
[    0.594769] pci 0000:00:08.1: PME# disabled
[    0.594839] pci 0000:00:08.2: [1022:1484] type 01 class 0x060400
[    0.600800] pci 0000:00:08.2: enabling Extended Tags
[    0.605808] pci 0000:00:08.2: PME# supported from D0 D3hot D3cold
[    0.612770] pci 0000:00:08.2: PME# disabled
[    0.612829] pci 0000:00:08.3: [1022:1484] type 01 class 0x060400
[    0.618799] pci 0000:00:08.3: enabling Extended Tags
[    0.623808] pci 0000:00:08.3: PME# supported from D0 D3hot D3cold
[    0.629769] pci 0000:00:08.3: PME# disabled
[    0.629853] pci 0000:00:14.0: [1022:790b] type 00 class 0x0c0500
[    0.635876] pci 0000:00:14.3: [1022:790e] type 00 class 0x060100
[    0.641879] pci 0000:00:18.0: [1022:1440] type 00 class 0x060000
[    0.647804] pci 0000:00:18.1: [1022:1441] type 00 class 0x060000
[    0.653803] pci 0000:00:18.2: [1022:1442] type 00 class 0x060000
[    0.659803] pci 0000:00:18.3: [1022:1443] type 00 class 0x060000
[    0.665803] pci 0000:00:18.4: [1022:1444] type 00 class 0x060000
[    0.671804] pci 0000:00:18.5: [1022:1445] type 00 class 0x060000
[    0.677803] pci 0000:00:18.6: [1022:1446] type 00 class 0x060000
[    0.683803] pci 0000:00:18.7: [1022:1447] type 00 class 0x060000
[    0.689810] pci_bus 0000:00: fixups for bus
[    0.689812] pci 0000:00:01.2: scanning [bus 01-07] behind bridge, pass 0
[    0.689833] pci_bus 0000:01: scanning bus
[    0.689846] pci 0000:01:00.0: [1022:57ad] type 01 class 0x060400
[    0.695837] pci 0000:01:00.0: enabling Extended Tags
[    0.700849] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
[    0.707795] pci 0000:01:00.0: PME# disabled
[    0.707846] pci 0000:01:00.0: 63.012 Gb/s available PCIe bandwidth, limited by 16.0 GT/s PCIe x4 link at 0000:00:01.2 (capable of 126.024 Gb/s with 16.0 GT/s PCIe x8 link)
[    0.722832] pci_bus 0000:01: fixups for bus
[    0.722833] pci 0000:00:01.2: PCI bridge to [bus 01-07]
[    0.727771] pci 0000:00:01.2:   bridge window [io  0xe000-0xffff]
[    0.733769] pci 0000:00:01.2:   bridge window [mem 0xf6000000-0xf76fffff]
[    0.740771] pci 0000:00:01.2:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    0.748770] pci 0000:01:00.0: scanning [bus 02-07] behind bridge, pass 0
[    0.748800] pci_bus 0000:02: scanning bus
[    0.748906] pci 0000:02:04.0: [1022:57a3] type 01 class 0x060400
[    0.754863] pci 0000:02:04.0: enabling Extended Tags
[    0.759944] pci 0000:02:04.0: PME# supported from D0 D3hot D3cold
[    0.765771] pci 0000:02:04.0: PME# disabled
[    0.765948] pci 0000:02:05.0: [1022:57a3] type 01 class 0x060400
[    0.772820] pci 0000:02:05.0: enabling Extended Tags
[    0.777944] pci 0000:02:05.0: PME# supported from D0 D3hot D3cold
[    0.783771] pci 0000:02:05.0: PME# disabled
[    0.783995] pci 0000:02:08.0: [1022:57a4] type 01 class 0x060400
[    0.789860] pci 0000:02:08.0: enabling Extended Tags
[    0.794923] pci 0000:02:08.0: PME# supported from D0 D3hot D3cold
[    0.800771] pci 0000:02:08.0: PME# disabled
[    0.800918] pci 0000:02:09.0: [1022:57a4] type 01 class 0x060400
[    0.807824] pci 0000:02:09.0: enabling Extended Tags
[    0.812922] pci 0000:02:09.0: PME# supported from D0 D3hot D3cold
[    0.818771] pci 0000:02:09.0: PME# disabled
[    0.818914] pci 0000:02:0a.0: [1022:57a4] type 01 class 0x060400
[    0.824860] pci 0000:02:0a.0: enabling Extended Tags
[    0.829942] pci 0000:02:0a.0: PME# supported from D0 D3hot D3cold
[    0.835771] pci 0000:02:0a.0: PME# disabled
[    0.835939] pci_bus 0000:02: fixups for bus
[    0.835940] pci 0000:01:00.0: PCI bridge to [bus 02-07]
[    0.841774] pci 0000:01:00.0:   bridge window [io  0xe000-0xffff]
[    0.847771] pci 0000:01:00.0:   bridge window [mem 0xf6000000-0xf76fffff]
[    0.854773] pci 0000:01:00.0:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    0.861770] pci 0000:02:04.0: scanning [bus 03-03] behind bridge, pass 0
[    0.861838] pci_bus 0000:03: scanning bus
[    0.861856] pci 0000:03:00.0: [10de:128b] type 00 class 0x030000
[    0.867803] pci 0000:03:00.0: reg 0x10: [mem 0xf6000000-0xf6ffffff]
[    0.874787] pci 0000:03:00.0: reg 0x14: [mem 0xe0000000-0xe7ffffff 64bit pref]
[    0.881787] pci 0000:03:00.0: reg 0x1c: [mem 0xe8000000-0xe9ffffff 64bit pref]
[    0.888780] pci 0000:03:00.0: reg 0x24: [io  0xf000-0xf07f]
[    0.894780] pci 0000:03:00.0: reg 0x30: [mem 0xf7000000-0xf707ffff pref]
[    0.900778] pci 0000:03:00.0: enabling Extended Tags
[    0.905906] pci 0000:03:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0000:02:04.0 (capable of 32.000 Gb/s with 5.0 GT/s PCIe x8 link)
[    0.920814] pci 0000:03:00.1: [10de:0e0f] type 00 class 0x040300
[    0.927771] pci 0000:03:00.1: reg 0x10: [mem 0xf7080000-0xf7083fff]
[    0.933848] pci 0000:03:00.1: enabling Extended Tags
[    0.938915] pci_bus 0000:03: fixups for bus
[    0.938916] pci 0000:02:04.0: PCI bridge to [bus 03]
[    0.943773] pci 0000:02:04.0:   bridge window [io  0xf000-0xffff]
[    0.949771] pci 0000:02:04.0:   bridge window [mem 0xf6000000-0xf70fffff]
[    0.956773] pci 0000:02:04.0:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    0.964769] pci_bus 0000:03: bus scan returning with max=03
[    0.964772] pci 0000:02:05.0: scanning [bus 04-04] behind bridge, pass 0
[    0.964841] pci_bus 0000:04: scanning bus
[    0.964861] pci 0000:04:00.0: [10ec:8168] type 00 class 0x020000
[    0.970808] pci 0000:04:00.0: reg 0x10: [io  0xe000-0xe0ff]
[    0.975803] pci 0000:04:00.0: reg 0x18: [mem 0xf7604000-0xf7604fff 64bit]
[    0.982789] pci 0000:04:00.0: reg 0x20: [mem 0xf7600000-0xf7603fff 64bit]
[    0.989906] pci 0000:04:00.0: supports D1 D2
[    0.993768] pci 0000:04:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    1.000772] pci 0000:04:00.0: PME# disabled
[    1.000960] pci_bus 0000:04: fixups for bus
[    1.000960] pci 0000:02:05.0: PCI bridge to [bus 04]
[    1.005773] pci 0000:02:05.0:   bridge window [io  0xe000-0xefff]
[    1.011771] pci 0000:02:05.0:   bridge window [mem 0xf7600000-0xf76fffff]
[    1.018773] pci_bus 0000:04: bus scan returning with max=04
[    1.018777] pci 0000:02:08.0: scanning [bus 05-05] behind bridge, pass 0
[    1.018845] pci_bus 0000:05: scanning bus
[    1.018860] pci 0000:05:00.0: [1022:1485] type 00 class 0x130000
[    1.024869] pci 0000:05:00.0: enabling Extended Tags
[    1.029909] pci 0000:05:00.0: 63.012 Gb/s available PCIe bandwidth, limited by 16.0 GT/s PCIe x4 link at 0000:00:01.2 (capable of 252.048 Gb/s with 16.0 GT/s PCIe x16 link)
[    1.045899] pci 0000:05:00.1: [1022:149c] type 00 class 0x0c0330
[    1.052133] pci 0000:05:00.1: reg 0x10: [mem 0xf7300000-0xf73fffff 64bit]
[    1.059874] pci 0000:05:00.1: enabling Extended Tags
[    1.065282] pci 0000:05:00.1: PME# supported from D0 D3hot D3cold
[    1.070807] pci 0000:05:00.1: PME# disabled
[    1.071044] pci 0000:05:00.3: [1022:149c] type 00 class 0x0c0330
[    1.077801] pci 0000:05:00.3: reg 0x10: [mem 0xf7200000-0xf72fffff 64bit]
[    1.083828] pci 0000:05:00.3: enabling Extended Tags
[    1.088842] pci 0000:05:00.3: PME# supported from D0 D3hot D3cold
[    1.095771] pci 0000:05:00.3: PME# disabled
[    1.095879] pci_bus 0000:05: fixups for bus
[    1.095879] pci 0000:02:08.0: PCI bridge to [bus 05]
[    1.100776] pci 0000:02:08.0:   bridge window [mem 0xf7200000-0xf73fffff]
[    1.106774] pci_bus 0000:05: bus scan returning with max=05
[    1.106777] pci 0000:02:09.0: scanning [bus 06-06] behind bridge, pass 0
[    1.106845] pci_bus 0000:06: scanning bus
[    1.106860] pci 0000:06:00.0: [1022:7901] type 00 class 0x010601
[    1.113808] pci 0000:06:00.0: reg 0x24: [mem 0xf7500000-0xf75007ff]
[    1.119787] pci 0000:06:00.0: enabling Extended Tags
[    1.124860] pci 0000:06:00.0: PME# supported from D3hot D3cold
[    1.130771] pci 0000:06:00.0: PME# disabled
[    1.130837] pci 0000:06:00.0: 63.012 Gb/s available PCIe bandwidth, limited by 16.0 GT/s PCIe x4 link at 0000:00:01.2 (capable of 252.048 Gb/s with 16.0 GT/s PCIe x16 link)
[    1.145838] pci_bus 0000:06: fixups for bus
[    1.145839] pci 0000:02:09.0: PCI bridge to [bus 06]
[    1.150776] pci 0000:02:09.0:   bridge window [mem 0xf7500000-0xf75fffff]
[    1.157774] pci_bus 0000:06: bus scan returning with max=06
[    1.157777] pci 0000:02:0a.0: scanning [bus 07-07] behind bridge, pass 0
[    1.157845] pci_bus 0000:07: scanning bus
[    1.157860] pci 0000:07:00.0: [1022:7901] type 00 class 0x010601
[    1.163851] pci 0000:07:00.0: reg 0x24: [mem 0xf7400000-0xf74007ff]
[    1.169787] pci 0000:07:00.0: enabling Extended Tags
[    1.174861] pci 0000:07:00.0: PME# supported from D3hot D3cold
[    1.180771] pci 0000:07:00.0: PME# disabled
[    1.180836] pci 0000:07:00.0: 63.012 Gb/s available PCIe bandwidth, limited by 16.0 GT/s PCIe x4 link at 0000:00:01.2 (capable of 252.048 Gb/s with 16.0 GT/s PCIe x16 link)
[    1.196838] pci_bus 0000:07: fixups for bus
[    1.196839] pci 0000:02:0a.0: PCI bridge to [bus 07]
[    1.201776] pci 0000:02:0a.0:   bridge window [mem 0xf7400000-0xf74fffff]
[    1.208773] pci_bus 0000:07: bus scan returning with max=07
[    1.208777] pci 0000:02:04.0: scanning [bus 03-03] behind bridge, pass 1
[    1.208783] pci 0000:02:05.0: scanning [bus 04-04] behind bridge, pass 1
[    1.208789] pci 0000:02:08.0: scanning [bus 05-05] behind bridge, pass 1
[    1.208795] pci 0000:02:09.0: scanning [bus 06-06] behind bridge, pass 1
[    1.208800] pci 0000:02:0a.0: scanning [bus 07-07] behind bridge, pass 1
[    1.208805] pci_bus 0000:02: bus scan returning with max=07
[    1.208808] pci 0000:01:00.0: scanning [bus 02-07] behind bridge, pass 1
[    1.208813] pci_bus 0000:01: bus scan returning with max=07
[    1.208815] pci 0000:00:03.1: scanning [bus 08-08] behind bridge, pass 0
[    1.208837] pci_bus 0000:08: scanning bus
[    1.208851] pci 0000:08:00.0: [14e4:5e87] type 00 class 0x120000
[    1.214798] pci 0000:08:00.0: reg 0x10: [mem 0xf0800000-0xf0807fff 64bit pref]
[    1.221780] pci 0000:08:00.0: reg 0x18: [mem 0xf0000000-0xf07fffff 64bit pref]
[    1.228780] pci 0000:08:00.0: reg 0x20: [mem 0xec000000-0xefffffff 64bit pref]
[    1.235859] pci 0000:08:00.0: PME# supported from D0 D3hot D3cold
[    1.242770] pci 0000:08:00.0: PME# disabled
[    1.242868] pci_bus 0000:08: fixups for bus
[    1.242869] pci 0000:00:03.1: PCI bridge to [bus 08]
[    1.247775] pci 0000:00:03.1:   bridge window [mem 0xec000000-0xf08fffff 64bit pref]
[    1.254768] pci_bus 0000:08: bus scan returning with max=08
[    1.254770] pci 0000:00:07.1: scanning [bus 09-09] behind bridge, pass 0
[    1.254789] pci_bus 0000:09: scanning bus
[    1.254796] pci 0000:09:00.0: [1022:148a] type 00 class 0x130000
[    1.260810] pci 0000:09:00.0: enabling Extended Tags
[    1.265866] pci_bus 0000:09: fixups for bus
[    1.265866] pci 0000:00:07.1: PCI bridge to [bus 09]
[    1.271774] pci_bus 0000:09: bus scan returning with max=09
[    1.271775] pci 0000:00:08.1: scanning [bus 0a-0a] behind bridge, pass 0
[    1.271796] pci_bus 0000:0a: scanning bus
[    1.271804] pci 0000:0a:00.0: [1022:1485] type 00 class 0x130000
[    1.277805] pci 0000:0a:00.0: enabling Extended Tags
[    1.282860] pci 0000:0a:00.1: [1022:1486] type 00 class 0x108000
[    1.288794] pci 0000:0a:00.1: reg 0x18: [mem 0xf7900000-0xf79fffff]
[    1.294783] pci 0000:0a:00.1: reg 0x24: [mem 0xf7a08000-0xf7a09fff]
[    1.300777] pci 0000:0a:00.1: enabling Extended Tags
[    1.305850] pci 0000:0a:00.3: [1022:149c] type 00 class 0x0c0330
[    1.311786] pci 0000:0a:00.3: reg 0x10: [mem 0xf7800000-0xf78fffff 64bit]
[    1.318797] pci 0000:0a:00.3: enabling Extended Tags
[    1.323813] pci 0000:0a:00.3: PME# supported from D0 D3hot D3cold
[    1.329769] pci 0000:0a:00.3: PME# disabled
[    1.329820] pci 0000:0a:00.4: [1022:1487] type 00 class 0x040300
[    1.335783] pci 0000:0a:00.4: reg 0x10: [mem 0xf7a00000-0xf7a07fff]
[    1.342793] pci 0000:0a:00.4: enabling Extended Tags
[    1.347800] pci 0000:0a:00.4: PME# supported from D0 D3hot D3cold
[    1.353769] pci 0000:0a:00.4: PME# disabled
[    1.353846] pci_bus 0000:0a: fixups for bus
[    1.353846] pci 0000:00:08.1: PCI bridge to [bus 0a]
[    1.358772] pci 0000:00:08.1:   bridge window [mem 0xf7800000-0xf7afffff]
[    1.365770] pci_bus 0000:0a: bus scan returning with max=0a
[    1.365772] pci 0000:00:08.2: scanning [bus 0b-0b] behind bridge, pass 0
[    1.365793] pci_bus 0000:0b: scanning bus
[    1.365801] pci 0000:0b:00.0: [1022:7901] type 00 class 0x010601
[    1.371801] pci 0000:0b:00.0: reg 0x24: [mem 0xf7c00000-0xf7c007ff]
[    1.377777] pci 0000:0b:00.0: enabling Extended Tags
[    1.382822] pci 0000:0b:00.0: PME# supported from D3hot D3cold
[    1.388769] pci 0000:0b:00.0: PME# disabled
[    1.388846] pci_bus 0000:0b: fixups for bus
[    1.388847] pci 0000:00:08.2: PCI bridge to [bus 0b]
[    1.393772] pci 0000:00:08.2:   bridge window [mem 0xf7c00000-0xf7cfffff]
[    1.400770] pci_bus 0000:0b: bus scan returning with max=0b
[    1.400772] pci 0000:00:08.3: scanning [bus 0c-0c] behind bridge, pass 0
[    1.400781] pci_bus 0000:0c: scanning bus
[    1.400789] pci 0000:0c:00.0: [1022:7901] type 00 class 0x010601
[    1.406811] pci 0000:0c:00.0: reg 0x24: [mem 0xf7b00000-0xf7b007ff]
[    1.412777] pci 0000:0c:00.0: enabling Extended Tags
[    1.417821] pci 0000:0c:00.0: PME# supported from D3hot D3cold
[    1.423769] pci 0000:0c:00.0: PME# disabled
[    1.423848] pci_bus 0000:0c: fixups for bus
[    1.423848] pci 0000:00:08.3: PCI bridge to [bus 0c]
[    1.428771] pci 0000:00:08.3:   bridge window [mem 0xf7b00000-0xf7bfffff]
[    1.435770] pci_bus 0000:0c: bus scan returning with max=0c
[    1.435772] pci 0000:00:01.2: scanning [bus 01-07] behind bridge, pass 1
[    1.435777] pci 0000:00:03.1: scanning [bus 08-08] behind bridge, pass 1
[    1.435782] pci 0000:00:07.1: scanning [bus 09-09] behind bridge, pass 1
[    1.435787] pci 0000:00:08.1: scanning [bus 0a-0a] behind bridge, pass 1
[    1.435791] pci 0000:00:08.2: scanning [bus 0b-0b] behind bridge, pass 1
[    1.435796] pci 0000:00:08.3: scanning [bus 0c-0c] behind bridge, pass 1
[    1.435800] pci_bus 0000:00: bus scan returning with max=0c
[    1.435999] ACPI: PCI Interrupt Link [LNKA] (IRQs 4 5 7 10 11 14 15) *0
[    1.441795] ACPI: PCI Interrupt Link [LNKB] (IRQs 4 5 7 10 11 14 15) *0
[    1.448791] ACPI: PCI Interrupt Link [LNKC] (IRQs 4 5 7 10 11 14 15) *0
[    1.455796] ACPI: PCI Interrupt Link [LNKD] (IRQs 4 5 7 10 11 14 15) *0
[    1.461793] ACPI: PCI Interrupt Link [LNKE] (IRQs 4 5 7 10 11 14 15) *0
[    1.468789] ACPI: PCI Interrupt Link [LNKF] (IRQs 4 5 7 10 11 14 15) *0
[    1.475789] ACPI: PCI Interrupt Link [LNKG] (IRQs 4 5 7 10 11 14 15) *0
[    1.481789] ACPI: PCI Interrupt Link [LNKH] (IRQs 4 5 7 10 11 14 15) *0
[    1.489015] iommu: Default domain type: Translated 
[    1.493779] pci 0000:03:00.0: vgaarb: setting as boot VGA device
[    1.494767] pci 0000:03:00.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none
[    1.508769] pci 0000:03:00.0: vgaarb: bridge control possible
[    1.513768] vgaarb: loaded
[    1.516800] SCSI subsystem initialized
[    1.520781] libata version 3.00 loaded.
[    1.520785] ACPI: bus type USB registered
[    1.524774] usbcore: registered new interface driver usbfs
[    1.529771] usbcore: registered new interface driver hub
[    1.535793] usbcore: registered new device driver usb
[    1.540773] mc: Linux media interface: v0.10
[    1.544770] videodev: Linux video capture interface: v2.00
[    1.549770] pps_core: LinuxPPS API ver. 1 registered
[    1.554768] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.564769] PTP clock support registered
[    1.568805] Advanced Linux Sound Architecture Driver Initialized.
[    1.574833] NetLabel: Initializing
[    1.577768] NetLabel:  domain hash size = 128
[    1.581768] NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
[    1.587774] NetLabel:  unlabeled traffic allowed by default
[    1.593773] PCI: Using ACPI for IRQ routing
[    1.599775] PCI: pci_cache_line_size set to 64 bytes
[    1.599785] pci 0000:03:00.0: BAR 0: reserving [mem 0xf6000000-0xf6ffffff flags 0x40200] (d=0, p=0)
[    1.599786] pci 0000:03:00.0: BAR 1: reserving [mem 0xe0000000-0xe7ffffff flags 0x14220c] (d=0, p=0)
[    1.599787] pci 0000:03:00.0: BAR 3: reserving [mem 0xe8000000-0xe9ffffff flags 0x14220c] (d=0, p=0)
[    1.599788] pci 0000:03:00.0: BAR 5: reserving [io  0xf000-0xf07f flags 0x40101] (d=0, p=0)
[    1.599790] pci 0000:03:00.1: BAR 0: reserving [mem 0xf7080000-0xf7083fff flags 0x40200] (d=0, p=0)
[    1.599795] pci 0000:04:00.0: BAR 0: reserving [io  0xe000-0xe0ff flags 0x40101] (d=0, p=0)
[    1.599795] pci 0000:04:00.0: BAR 2: reserving [mem 0xf7604000-0xf7604fff flags 0x140204] (d=0, p=0)
[    1.599796] pci 0000:04:00.0: BAR 4: reserving [mem 0xf7600000-0xf7603fff flags 0x140204] (d=0, p=0)
[    1.599811] pci 0000:05:00.1: BAR 0: reserving [mem 0xf7300000-0xf73fffff flags 0x140204] (d=0, p=0)
[    1.599813] pci 0000:05:00.3: BAR 0: reserving [mem 0xf7200000-0xf72fffff flags 0x140204] (d=0, p=0)
[    1.599816] pci 0000:06:00.0: BAR 5: reserving [mem 0xf7500000-0xf75007ff flags 0x40200] (d=0, p=0)
[    1.599820] pci 0000:07:00.0: BAR 5: reserving [mem 0xf7400000-0xf74007ff flags 0x40200] (d=0, p=0)
[    1.599823] pci 0000:08:00.0: BAR 0: reserving [mem 0xf0800000-0xf0807fff flags 0x14220c] (d=0, p=0)
[    1.599824] pci 0000:08:00.0: BAR 2: reserving [mem 0xf0000000-0xf07fffff flags 0x14220c] (d=0, p=0)
[    1.599825] pci 0000:08:00.0: BAR 4: reserving [mem 0xec000000-0xefffffff flags 0x14220c] (d=0, p=0)
[    1.599831] pci 0000:0a:00.1: BAR 2: reserving [mem 0xf7900000-0xf79fffff flags 0x40200] (d=0, p=0)
[    1.599832] pci 0000:0a:00.1: BAR 5: reserving [mem 0xf7a08000-0xf7a09fff flags 0x40200] (d=0, p=0)
[    1.599833] pci 0000:0a:00.3: BAR 0: reserving [mem 0xf7800000-0xf78fffff flags 0x140204] (d=0, p=0)
[    1.599834] pci 0000:0a:00.4: BAR 0: reserving [mem 0xf7a00000-0xf7a07fff flags 0x40200] (d=0, p=0)
[    1.599836] pci 0000:0b:00.0: BAR 5: reserving [mem 0xf7c00000-0xf7c007ff flags 0x40200] (d=0, p=0)
[    1.599838] pci 0000:0c:00.0: BAR 5: reserving [mem 0xf7b00000-0xf7b007ff flags 0x40200] (d=0, p=0)
[    1.599894] e820: reserve RAM buffer [mem 0x0009d400-0x0009ffff]
[    1.599894] e820: reserve RAM buffer [mem 0x09d02000-0x0bffffff]
[    1.599895] e820: reserve RAM buffer [mem 0x0a200000-0x0bffffff]
[    1.599895] e820: reserve RAM buffer [mem 0xd8984000-0xdbffffff]
[    1.599895] e820: reserve RAM buffer [mem 0xdd000000-0xdfffffff]
[    1.599896] e820: reserve RAM buffer [mem 0x41f380000-0x41fffffff]
[    1.599909] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
[    1.604768] hpet0: 3 comparators, 32-bit 14.318180 MHz counter
[    1.611791] clocksource: Switched to clocksource tsc-early
[    1.691597] VFS: Disk quotas dquot_6.6.0
[    1.695533] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.702432] pnp: PnP ACPI init
[    1.705537] system 00:00: [mem 0xf8000000-0xfbffffff] has been reserved
[    1.712152] system 00:00: Plug and Play ACPI device, IDs PNP0c01 (active)
[    1.712193] system 00:01: [mem 0xfd000000-0xfd0fffff] has been reserved
[    1.718802] system 00:01: Plug and Play ACPI device, IDs PNP0c02 (active)
[    1.718821] pnp 00:02: Plug and Play ACPI device, IDs PNP0b00 (active)
[    1.718888] system 00:03: [io  0x0290-0x029f] has been reserved
[    1.724810] system 00:03: [io  0x0200-0x021f] has been reserved
[    1.730730] system 00:03: Plug and Play ACPI device, IDs PNP0c02 (active)
[    1.730863] pnp 00:04: [dma 0 disabled]
[    1.730879] pnp 00:04: Plug and Play ACPI device, IDs PNP0501 (active)
[    1.731002] system 00:05: [io  0x04d0-0x04d1] has been reserved
[    1.736922] system 00:05: [io  0x040b] has been reserved
[    1.742234] system 00:05: [io  0x04d6] has been reserved
[    1.747542] system 00:05: [io  0x0c00-0x0c01] has been reserved
[    1.753464] system 00:05: [io  0x0c14] has been reserved
[    1.758776] system 00:05: [io  0x0c50-0x0c51] has been reserved
[    1.764691] system 00:05: [io  0x0c52] has been reserved
[    1.770003] system 00:05: [io  0x0c6c] has been reserved
[    1.775311] system 00:05: [io  0x0c6f] has been reserved
[    1.780624] system 00:05: [io  0x0cd0-0x0cd1] has been reserved
[    1.786537] system 00:05: [io  0x0cd2-0x0cd3] has been reserved
[    1.792450] system 00:05: [io  0x0cd4-0x0cd5] has been reserved
[    1.798363] system 00:05: [io  0x0cd6-0x0cd7] has been reserved
[    1.804277] system 00:05: [io  0x0cd8-0x0cdf] has been reserved
[    1.810199] system 00:05: [io  0x0800-0x089f] has been reserved
[    1.816118] system 00:05: [io  0x0b00-0x0b0f] has been reserved
[    1.822031] system 00:05: [io  0x0b20-0x0b3f] has been reserved
[    1.827945] system 00:05: [io  0x0900-0x090f] has been reserved
[    1.833866] system 00:05: [io  0x0910-0x091f] has been reserved
[    1.839777] system 00:05: [mem 0xfec00000-0xfec00fff] could not be reserved
[    1.846732] system 00:05: [mem 0xfec01000-0xfec01fff] could not be reserved
[    1.853694] system 00:05: [mem 0xfedc0000-0xfedc0fff] has been reserved
[    1.860308] system 00:05: [mem 0xfee00000-0xfee00fff] has been reserved
[    1.866915] system 00:05: [mem 0xfed80000-0xfed8ffff] could not be reserved
[    1.873868] system 00:05: [mem 0xfec10000-0xfec10fff] has been reserved
[    1.880484] system 00:05: [mem 0xff000000-0xffffffff] has been reserved
[    1.887099] system 00:05: Plug and Play ACPI device, IDs PNP0c02 (active)
[    1.887292] pnp: PnP ACPI: found 6 devices
[    1.896607] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    1.905488] NET: Registered protocol family 2
[    1.909990] tcp_listen_portaddr_hash hash table entries: 8192 (order: 5, 131072 bytes, linear)
[    1.918610] TCP established hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    1.926800] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes, linear)
[    1.934305] TCP: Hash tables configured (established 131072 bind 65536)
[    1.940959] UDP hash table entries: 8192 (order: 6, 262144 bytes, linear)
[    1.947773] UDP-Lite hash table entries: 8192 (order: 6, 262144 bytes, linear)
[    1.955052] NET: Registered protocol family 1
[    1.959506] RPC: Registered named UNIX socket transport module.
[    1.965420] RPC: Registered udp transport module.
[    1.970120] RPC: Registered tcp transport module.
[    1.974828] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    1.981334] pci 0000:02:04.0: PCI bridge to [bus 03]
[    1.986298] pci 0000:02:04.0:   bridge window [io  0xf000-0xffff]
[    1.992395] pci 0000:02:04.0:   bridge window [mem 0xf6000000-0xf70fffff]
[    1.999183] pci 0000:02:04.0:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.006927] pci 0000:02:05.0: PCI bridge to [bus 04]
[    2.011892] pci 0000:02:05.0:   bridge window [io  0xe000-0xefff]
[    2.017987] pci 0000:02:05.0:   bridge window [mem 0xf7600000-0xf76fffff]
[    2.024781] pci 0000:02:08.0: PCI bridge to [bus 05]
[    2.029751] pci 0000:02:08.0:   bridge window [mem 0xf7200000-0xf73fffff]
[    2.036545] pci 0000:02:09.0: PCI bridge to [bus 06]
[    2.041517] pci 0000:02:09.0:   bridge window [mem 0xf7500000-0xf75fffff]
[    2.048307] pci 0000:02:0a.0: PCI bridge to [bus 07]
[    2.053272] pci 0000:02:0a.0:   bridge window [mem 0xf7400000-0xf74fffff]
[    2.060064] pci 0000:01:00.0: PCI bridge to [bus 02-07]
[    2.065286] pci 0000:01:00.0:   bridge window [io  0xe000-0xffff]
[    2.071382] pci 0000:01:00.0:   bridge window [mem 0xf6000000-0xf76fffff]
[    2.078171] pci 0000:01:00.0:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.085914] pci 0000:00:01.2: PCI bridge to [bus 01-07]
[    2.091137] pci 0000:00:01.2:   bridge window [io  0xe000-0xffff]
[    2.097234] pci 0000:00:01.2:   bridge window [mem 0xf6000000-0xf76fffff]
[    2.104021] pci 0000:00:01.2:   bridge window [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.111764] pci 0000:00:03.1: PCI bridge to [bus 08]
[    2.116733] pci 0000:00:03.1:   bridge window [mem 0xec000000-0xf08fffff 64bit pref]
[    2.124474] pci 0000:00:07.1: PCI bridge to [bus 09]
[    2.129445] pci 0000:00:08.1: PCI bridge to [bus 0a]
[    2.134408] pci 0000:00:08.1:   bridge window [mem 0xf7800000-0xf7afffff]
[    2.141198] pci 0000:00:08.2: PCI bridge to [bus 0b]
[    2.146164] pci 0000:00:08.2:   bridge window [mem 0xf7c00000-0xf7cfffff]
[    2.152953] pci 0000:00:08.3: PCI bridge to [bus 0c]
[    2.157920] pci 0000:00:08.3:   bridge window [mem 0xf7b00000-0xf7bfffff]
[    2.164710] pci_bus 0000:00: resource 4 [io  0x0000-0x03af window]
[    2.170885] pci_bus 0000:00: resource 5 [io  0x03e0-0x0cf7 window]
[    2.177060] pci_bus 0000:00: resource 6 [io  0x03b0-0x03df window]
[    2.183242] pci_bus 0000:00: resource 7 [io  0x0d00-0xffff window]
[    2.189422] pci_bus 0000:00: resource 8 [mem 0x000a0000-0x000bffff window]
[    2.196290] pci_bus 0000:00: resource 9 [mem 0x000c0000-0x000dffff window]
[    2.203165] pci_bus 0000:00: resource 10 [mem 0xe0000000-0xf7ffffff window]
[    2.210126] pci_bus 0000:01: resource 0 [io  0xe000-0xffff]
[    2.215700] pci_bus 0000:01: resource 1 [mem 0xf6000000-0xf76fffff]
[    2.221968] pci_bus 0000:01: resource 2 [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.229181] pci_bus 0000:02: resource 0 [io  0xe000-0xffff]
[    2.234748] pci_bus 0000:02: resource 1 [mem 0xf6000000-0xf76fffff]
[    2.241016] pci_bus 0000:02: resource 2 [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.248237] pci_bus 0000:03: resource 0 [io  0xf000-0xffff]
[    2.253803] pci_bus 0000:03: resource 1 [mem 0xf6000000-0xf70fffff]
[    2.260069] pci_bus 0000:03: resource 2 [mem 0xe0000000-0xe9ffffff 64bit pref]
[    2.267285] pci_bus 0000:04: resource 0 [io  0xe000-0xefff]
[    2.272857] pci_bus 0000:04: resource 1 [mem 0xf7600000-0xf76fffff]
[    2.279118] pci_bus 0000:05: resource 1 [mem 0xf7200000-0xf73fffff]
[    2.285385] pci_bus 0000:06: resource 1 [mem 0xf7500000-0xf75fffff]
[    2.291644] pci_bus 0000:07: resource 1 [mem 0xf7400000-0xf74fffff]
[    2.297905] pci_bus 0000:08: resource 2 [mem 0xec000000-0xf08fffff 64bit pref]
[    2.305126] pci_bus 0000:0a: resource 1 [mem 0xf7800000-0xf7afffff]
[    2.311385] pci_bus 0000:0b: resource 1 [mem 0xf7c00000-0xf7cfffff]
[    2.317645] pci_bus 0000:0c: resource 1 [mem 0xf7b00000-0xf7bfffff]
[    2.323989] pci 0000:03:00.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
[    2.332346] pci 0000:03:00.1: D0 power state depends on 0000:03:00.0
[    2.338725] pci 0000:03:00.1: saving config space at offset 0x0 (reading 0xe0f10de)
[    2.338728] pci 0000:03:00.1: saving config space at offset 0x4 (reading 0x100006)
[    2.338730] pci 0000:03:00.1: saving config space at offset 0x8 (reading 0x40300a1)
[    2.338732] pci 0000:03:00.1: saving config space at offset 0xc (reading 0x800010)
[    2.338734] pci 0000:03:00.1: saving config space at offset 0x10 (reading 0xf7080000)
[    2.338737] pci 0000:03:00.1: saving config space at offset 0x14 (reading 0x0)
[    2.338739] pci 0000:03:00.1: saving config space at offset 0x18 (reading 0x0)
[    2.338741] pci 0000:03:00.1: saving config space at offset 0x1c (reading 0x0)
[    2.338743] pci 0000:03:00.1: saving config space at offset 0x20 (reading 0x0)
[    2.338745] pci 0000:03:00.1: saving config space at offset 0x24 (reading 0x0)
[    2.338747] pci 0000:03:00.1: saving config space at offset 0x28 (reading 0x0)
[    2.338749] pci 0000:03:00.1: saving config space at offset 0x2c (reading 0x536019da)
[    2.338751] pci 0000:03:00.1: saving config space at offset 0x30 (reading 0x0)
[    2.338754] pci 0000:03:00.1: saving config space at offset 0x34 (reading 0x60)
[    2.338756] pci 0000:03:00.1: saving config space at offset 0x38 (reading 0x0)
[    2.338758] pci 0000:03:00.1: saving config space at offset 0x3c (reading 0x2ff)
[    2.339072] PCI: CLS 64 bytes, default 64
[    2.662928] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    2.669821] pci 0000:00:01.0: Adding to iommu group 0
[    2.674880] pci 0000:00:01.2: Adding to iommu group 1
[    2.679941] pci 0000:00:02.0: Adding to iommu group 2
[    2.684997] pci 0000:00:03.0: Adding to iommu group 3
[    2.690058] pci 0000:00:03.1: Adding to iommu group 4
[    2.695120] pci 0000:00:04.0: Adding to iommu group 5
[    2.700172] pci 0000:00:05.0: Adding to iommu group 6
[    2.705231] pci 0000:00:07.0: Adding to iommu group 7
[    2.710291] pci 0000:00:07.1: Adding to iommu group 8
[    2.715352] pci 0000:00:08.0: Adding to iommu group 9
[    2.720408] pci 0000:00:08.1: Adding to iommu group 10
[    2.725555] pci 0000:00:08.2: Adding to iommu group 11
[    2.730697] pci 0000:00:08.3: Adding to iommu group 12
[    2.735841] pci 0000:00:14.0: Adding to iommu group 13
[    2.740984] pci 0000:00:14.3: Adding to iommu group 13
[    2.746143] pci 0000:00:18.0: Adding to iommu group 14
[    2.751283] pci 0000:00:18.1: Adding to iommu group 14
[    2.756424] pci 0000:00:18.2: Adding to iommu group 14
[    2.761566] pci 0000:00:18.3: Adding to iommu group 14
[    2.766705] pci 0000:00:18.4: Adding to iommu group 14
[    2.771845] pci 0000:00:18.5: Adding to iommu group 14
[    2.776985] pci 0000:00:18.6: Adding to iommu group 14
[    2.782128] pci 0000:00:18.7: Adding to iommu group 14
[    2.787272] pci 0000:01:00.0: Adding to iommu group 15
[    2.792446] pci 0000:02:04.0: Adding to iommu group 16
[    2.797613] pci 0000:02:05.0: Adding to iommu group 17
[    2.802761] pci 0000:02:08.0: Adding to iommu group 18
[    2.807910] pci 0000:02:09.0: Adding to iommu group 19
[    2.813058] pci 0000:02:0a.0: Adding to iommu group 20
[    2.818238] pci 0000:03:00.0: Adding to iommu group 21
[    2.823417] pci 0000:03:00.1: Adding to iommu group 21
[    2.828586] pci 0000:04:00.0: Adding to iommu group 22
[    2.833726] pci 0000:05:00.0: Adding to iommu group 18
[    2.838867] pci 0000:05:00.1: Adding to iommu group 18
[    2.844006] pci 0000:05:00.3: Adding to iommu group 18
[    2.849146] pci 0000:06:00.0: Adding to iommu group 19
[    2.854288] pci 0000:07:00.0: Adding to iommu group 20
[    2.859428] pci 0000:08:00.0: Adding to iommu group 23
[    2.864566] pci 0000:09:00.0: Adding to iommu group 24
[    2.869712] pci 0000:0a:00.0: Adding to iommu group 25
[    2.874861] pci 0000:0a:00.1: Adding to iommu group 26
[    2.880010] pci 0000:0a:00.3: Adding to iommu group 27
[    2.885159] pci 0000:0a:00.4: Adding to iommu group 28
[    2.890306] pci 0000:0b:00.0: Adding to iommu group 29
[    2.895455] pci 0000:0c:00.0: Adding to iommu group 30
[    2.904637] pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40
[    2.910124] pci 0000:00:00.2: AMD-Vi: Extended features (0x58f77ef22294ade):
[    2.917168]  PPR X2APIC NX GT IA GA PC GA_vAPIC
[    2.921813] AMD-Vi: Lazy IO/TLB flushing enabled
[    2.927312] RAPL PMU: API unit is 2^-32 Joules, 1 fixed counters, 163840 ms ovfl timer
[    2.935217] RAPL PMU: hw unit of domain package 2^-16 Joules
[    2.940875] amd_uncore: AMD NB counters detected
[    2.945492] amd_uncore: AMD LLC counters detected
[    2.950485] LVT offset 0 assigned for vector 0x400
[    2.955510] perf: AMD IBS detected (0x000003ff)
[    2.960042] perf/amd_iommu: Detected AMD IOMMU #0 (2 banks, 4 counters/bank).
[    2.967957] check: Scanning for low memory corruption every 60 seconds
[    2.974811] Initialise system trusted keyrings
[    2.979319] workingset: timestamp_bits=56 max_order=22 bucket_order=0
[    2.986456] NFS: Registering the id_resolver key type
[    2.991512] Key type id_resolver registered
[    2.995691] Key type id_legacy registered
[    3.002504] Key type asymmetric registered
[    3.006599] Asymmetric key parser 'x509' registered
[    3.011481] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
[    3.018875] io scheduler mq-deadline registered
[    3.023408] io scheduler kyber registered
[    3.027429] test_firmware: interface ready
[    3.031765] pcieport 0000:00:01.2: runtime IRQ mapping not provided by arch
[    3.031798] pcieport 0000:00:01.2: saving config space at offset 0x0 (reading 0x14831022)
[    3.031799] pcieport 0000:00:01.2: saving config space at offset 0x4 (reading 0x100407)
[    3.031800] pcieport 0000:00:01.2: saving config space at offset 0x8 (reading 0x6040000)
[    3.031801] pcieport 0000:00:01.2: saving config space at offset 0xc (reading 0x810010)
[    3.031802] pcieport 0000:00:01.2: saving config space at offset 0x10 (reading 0x0)
[    3.031803] pcieport 0000:00:01.2: saving config space at offset 0x14 (reading 0x0)
[    3.031804] pcieport 0000:00:01.2: saving config space at offset 0x18 (reading 0x70100)
[    3.031805] pcieport 0000:00:01.2: saving config space at offset 0x1c (reading 0x2000f1e1)
[    3.031806] pcieport 0000:00:01.2: saving config space at offset 0x20 (reading 0xf760f600)
[    3.031807] pcieport 0000:00:01.2: saving config space at offset 0x24 (reading 0xe9f1e001)
[    3.031808] pcieport 0000:00:01.2: saving config space at offset 0x28 (reading 0x0)
[    3.031809] pcieport 0000:00:01.2: saving config space at offset 0x2c (reading 0x0)
[    3.031810] pcieport 0000:00:01.2: saving config space at offset 0x30 (reading 0x0)
[    3.031812] pcieport 0000:00:01.2: saving config space at offset 0x34 (reading 0x50)
[    3.031813] pcieport 0000:00:01.2: saving config space at offset 0x38 (reading 0x0)
[    3.031814] pcieport 0000:00:01.2: saving config space at offset 0x3c (reading 0x1a00ff)
[    3.031845] pcieport 0000:00:03.1: runtime IRQ mapping not provided by arch
[    3.031872] pcieport 0000:00:03.1: saving config space at offset 0x0 (reading 0x14831022)
[    3.031873] pcieport 0000:00:03.1: saving config space at offset 0x4 (reading 0x100407)
[    3.031874] pcieport 0000:00:03.1: saving config space at offset 0x8 (reading 0x6040000)
[    3.031876] pcieport 0000:00:03.1: saving config space at offset 0xc (reading 0x810010)
[    3.031877] pcieport 0000:00:03.1: saving config space at offset 0x10 (reading 0x0)
[    3.031878] pcieport 0000:00:03.1: saving config space at offset 0x14 (reading 0x0)
[    3.031879] pcieport 0000:00:03.1: saving config space at offset 0x18 (reading 0x80800)
[    3.031880] pcieport 0000:00:03.1: saving config space at offset 0x1c (reading 0x1f1)
[    3.031881] pcieport 0000:00:03.1: saving config space at offset 0x20 (reading 0xfff0)
[    3.031882] pcieport 0000:00:03.1: saving config space at offset 0x24 (reading 0xf081ec01)
[    3.031883] pcieport 0000:00:03.1: saving config space at offset 0x28 (reading 0x0)
[    3.031885] pcieport 0000:00:03.1: saving config space at offset 0x2c (reading 0x0)
[    3.031886] pcieport 0000:00:03.1: saving config space at offset 0x30 (reading 0x0)
[    3.031887] pcieport 0000:00:03.1: saving config space at offset 0x34 (reading 0x50)
[    3.031888] pcieport 0000:00:03.1: saving config space at offset 0x38 (reading 0x0)
[    3.031889] pcieport 0000:00:03.1: saving config space at offset 0x3c (reading 0x1200ff)
[    3.031921] pcieport 0000:00:07.1: runtime IRQ mapping not provided by arch
[    3.031992] pcieport 0000:00:07.1: saving config space at offset 0x0 (reading 0x14841022)
[    3.031993] pcieport 0000:00:07.1: saving config space at offset 0x4 (reading 0x100407)
[    3.031994] pcieport 0000:00:07.1: saving config space at offset 0x8 (reading 0x6040000)
[    3.031995] pcieport 0000:00:07.1: saving config space at offset 0xc (reading 0x810010)
[    3.031996] pcieport 0000:00:07.1: saving config space at offset 0x10 (reading 0x0)
[    3.031997] pcieport 0000:00:07.1: saving config space at offset 0x14 (reading 0x0)
[    3.031998] pcieport 0000:00:07.1: saving config space at offset 0x18 (reading 0x90900)
[    3.031999] pcieport 0000:00:07.1: saving config space at offset 0x1c (reading 0x1f1)
[    3.032000] pcieport 0000:00:07.1: saving config space at offset 0x20 (reading 0xfff0)
[    3.032001] pcieport 0000:00:07.1: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032002] pcieport 0000:00:07.1: saving config space at offset 0x28 (reading 0x0)
[    3.032003] pcieport 0000:00:07.1: saving config space at offset 0x2c (reading 0x0)
[    3.032004] pcieport 0000:00:07.1: saving config space at offset 0x30 (reading 0x0)
[    3.032005] pcieport 0000:00:07.1: saving config space at offset 0x34 (reading 0x50)
[    3.032006] pcieport 0000:00:07.1: saving config space at offset 0x38 (reading 0x0)
[    3.032007] pcieport 0000:00:07.1: saving config space at offset 0x3c (reading 0x1201ff)
[    3.032029] pcieport 0000:00:08.1: runtime IRQ mapping not provided by arch
[    3.032051] pcieport 0000:00:08.1: saving config space at offset 0x0 (reading 0x14841022)
[    3.032052] pcieport 0000:00:08.1: saving config space at offset 0x4 (reading 0x100407)
[    3.032053] pcieport 0000:00:08.1: saving config space at offset 0x8 (reading 0x6040000)
[    3.032054] pcieport 0000:00:08.1: saving config space at offset 0xc (reading 0x810010)
[    3.032055] pcieport 0000:00:08.1: saving config space at offset 0x10 (reading 0x0)
[    3.032056] pcieport 0000:00:08.1: saving config space at offset 0x14 (reading 0x0)
[    3.032057] pcieport 0000:00:08.1: saving config space at offset 0x18 (reading 0xa0a00)
[    3.032058] pcieport 0000:00:08.1: saving config space at offset 0x1c (reading 0x1f1)
[    3.032059] pcieport 0000:00:08.1: saving config space at offset 0x20 (reading 0xf7a0f780)
[    3.032061] pcieport 0000:00:08.1: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032062] pcieport 0000:00:08.1: saving config space at offset 0x28 (reading 0x0)
[    3.032063] pcieport 0000:00:08.1: saving config space at offset 0x2c (reading 0x0)
[    3.032064] pcieport 0000:00:08.1: saving config space at offset 0x30 (reading 0x0)
[    3.032065] pcieport 0000:00:08.1: saving config space at offset 0x34 (reading 0x50)
[    3.032066] pcieport 0000:00:08.1: saving config space at offset 0x38 (reading 0x0)
[    3.032067] pcieport 0000:00:08.1: saving config space at offset 0x3c (reading 0x1201ff)
[    3.032090] pcieport 0000:00:08.2: runtime IRQ mapping not provided by arch
[    3.032133] pcieport 0000:00:08.2: saving config space at offset 0x0 (reading 0x14841022)
[    3.032134] pcieport 0000:00:08.2: saving config space at offset 0x4 (reading 0x100407)
[    3.032135] pcieport 0000:00:08.2: saving config space at offset 0x8 (reading 0x6040000)
[    3.032136] pcieport 0000:00:08.2: saving config space at offset 0xc (reading 0x810010)
[    3.032137] pcieport 0000:00:08.2: saving config space at offset 0x10 (reading 0x0)
[    3.032138] pcieport 0000:00:08.2: saving config space at offset 0x14 (reading 0x0)
[    3.032139] pcieport 0000:00:08.2: saving config space at offset 0x18 (reading 0xb0b00)
[    3.032140] pcieport 0000:00:08.2: saving config space at offset 0x1c (reading 0x1f1)
[    3.032141] pcieport 0000:00:08.2: saving config space at offset 0x20 (reading 0xf7c0f7c0)
[    3.032142] pcieport 0000:00:08.2: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032143] pcieport 0000:00:08.2: saving config space at offset 0x28 (reading 0x0)
[    3.032144] pcieport 0000:00:08.2: saving config space at offset 0x2c (reading 0x0)
[    3.032145] pcieport 0000:00:08.2: saving config space at offset 0x30 (reading 0x0)
[    3.032146] pcieport 0000:00:08.2: saving config space at offset 0x34 (reading 0x50)
[    3.032147] pcieport 0000:00:08.2: saving config space at offset 0x38 (reading 0x0)
[    3.032148] pcieport 0000:00:08.2: saving config space at offset 0x3c (reading 0x1201ff)
[    3.032172] pcieport 0000:00:08.3: runtime IRQ mapping not provided by arch
[    3.032211] pcieport 0000:00:08.3: saving config space at offset 0x0 (reading 0x14841022)
[    3.032213] pcieport 0000:00:08.3: saving config space at offset 0x4 (reading 0x100407)
[    3.032214] pcieport 0000:00:08.3: saving config space at offset 0x8 (reading 0x6040000)
[    3.032215] pcieport 0000:00:08.3: saving config space at offset 0xc (reading 0x810010)
[    3.032216] pcieport 0000:00:08.3: saving config space at offset 0x10 (reading 0x0)
[    3.032217] pcieport 0000:00:08.3: saving config space at offset 0x14 (reading 0x0)
[    3.032218] pcieport 0000:00:08.3: saving config space at offset 0x18 (reading 0xc0c00)
[    3.032219] pcieport 0000:00:08.3: saving config space at offset 0x1c (reading 0x1f1)
[    3.032220] pcieport 0000:00:08.3: saving config space at offset 0x20 (reading 0xf7b0f7b0)
[    3.032221] pcieport 0000:00:08.3: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032222] pcieport 0000:00:08.3: saving config space at offset 0x28 (reading 0x0)
[    3.032223] pcieport 0000:00:08.3: saving config space at offset 0x2c (reading 0x0)
[    3.032224] pcieport 0000:00:08.3: saving config space at offset 0x30 (reading 0x0)
[    3.032225] pcieport 0000:00:08.3: saving config space at offset 0x34 (reading 0x50)
[    3.032226] pcieport 0000:00:08.3: saving config space at offset 0x38 (reading 0x0)
[    3.032227] pcieport 0000:00:08.3: saving config space at offset 0x3c (reading 0x1201ff)
[    3.032252] pcieport 0000:01:00.0: runtime IRQ mapping not provided by arch
[    3.032263] pcieport 0000:01:00.0: saving config space at offset 0x0 (reading 0x57ad1022)
[    3.032265] pcieport 0000:01:00.0: saving config space at offset 0x4 (reading 0x100007)
[    3.032267] pcieport 0000:01:00.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.032269] pcieport 0000:01:00.0: saving config space at offset 0xc (reading 0x10010)
[    3.032270] pcieport 0000:01:00.0: saving config space at offset 0x10 (reading 0x0)
[    3.032272] pcieport 0000:01:00.0: saving config space at offset 0x14 (reading 0x0)
[    3.032274] pcieport 0000:01:00.0: saving config space at offset 0x18 (reading 0x70201)
[    3.032276] pcieport 0000:01:00.0: saving config space at offset 0x1c (reading 0xf1e1)
[    3.032278] pcieport 0000:01:00.0: saving config space at offset 0x20 (reading 0xf760f600)
[    3.032280] pcieport 0000:01:00.0: saving config space at offset 0x24 (reading 0xe9f1e001)
[    3.032282] pcieport 0000:01:00.0: saving config space at offset 0x28 (reading 0x0)
[    3.032283] pcieport 0000:01:00.0: saving config space at offset 0x2c (reading 0x0)
[    3.032285] pcieport 0000:01:00.0: saving config space at offset 0x30 (reading 0x0)
[    3.032287] pcieport 0000:01:00.0: saving config space at offset 0x34 (reading 0x50)
[    3.032289] pcieport 0000:01:00.0: saving config space at offset 0x38 (reading 0x0)
[    3.032290] pcieport 0000:01:00.0: saving config space at offset 0x3c (reading 0x1a010b)
[    3.032335] pcieport 0000:02:04.0: runtime IRQ mapping not provided by arch
[    3.032401] pcieport 0000:02:04.0: saving config space at offset 0x0 (reading 0x57a31022)
[    3.032403] pcieport 0000:02:04.0: saving config space at offset 0x4 (reading 0x100407)
[    3.032404] pcieport 0000:02:04.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.032406] pcieport 0000:02:04.0: saving config space at offset 0xc (reading 0x810010)
[    3.032408] pcieport 0000:02:04.0: saving config space at offset 0x10 (reading 0x0)
[    3.032410] pcieport 0000:02:04.0: saving config space at offset 0x14 (reading 0x0)
[    3.032412] pcieport 0000:02:04.0: saving config space at offset 0x18 (reading 0x30302)
[    3.032413] pcieport 0000:02:04.0: saving config space at offset 0x1c (reading 0x2000f1f1)
[    3.032415] pcieport 0000:02:04.0: saving config space at offset 0x20 (reading 0xf700f600)
[    3.032417] pcieport 0000:02:04.0: saving config space at offset 0x24 (reading 0xe9f1e001)
[    3.032419] pcieport 0000:02:04.0: saving config space at offset 0x28 (reading 0x0)
[    3.032420] pcieport 0000:02:04.0: saving config space at offset 0x2c (reading 0x0)
[    3.032422] pcieport 0000:02:04.0: saving config space at offset 0x30 (reading 0x0)
[    3.032424] pcieport 0000:02:04.0: saving config space at offset 0x34 (reading 0x50)
[    3.032426] pcieport 0000:02:04.0: saving config space at offset 0x38 (reading 0x0)
[    3.032428] pcieport 0000:02:04.0: saving config space at offset 0x3c (reading 0x1a00ff)
[    3.032511] pcieport 0000:02:05.0: runtime IRQ mapping not provided by arch
[    3.032577] pcieport 0000:02:05.0: saving config space at offset 0x0 (reading 0x57a31022)
[    3.032579] pcieport 0000:02:05.0: saving config space at offset 0x4 (reading 0x100407)
[    3.032581] pcieport 0000:02:05.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.032583] pcieport 0000:02:05.0: saving config space at offset 0xc (reading 0x810010)
[    3.032585] pcieport 0000:02:05.0: saving config space at offset 0x10 (reading 0x0)
[    3.032586] pcieport 0000:02:05.0: saving config space at offset 0x14 (reading 0x0)
[    3.032588] pcieport 0000:02:05.0: saving config space at offset 0x18 (reading 0x40402)
[    3.032590] pcieport 0000:02:05.0: saving config space at offset 0x1c (reading 0xe1e1)
[    3.032592] pcieport 0000:02:05.0: saving config space at offset 0x20 (reading 0xf760f760)
[    3.032593] pcieport 0000:02:05.0: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032595] pcieport 0000:02:05.0: saving config space at offset 0x28 (reading 0x0)
[    3.032597] pcieport 0000:02:05.0: saving config space at offset 0x2c (reading 0x0)
[    3.032599] pcieport 0000:02:05.0: saving config space at offset 0x30 (reading 0x0)
[    3.032601] pcieport 0000:02:05.0: saving config space at offset 0x34 (reading 0x50)
[    3.032602] pcieport 0000:02:05.0: saving config space at offset 0x38 (reading 0x0)
[    3.032604] pcieport 0000:02:05.0: saving config space at offset 0x3c (reading 0x1200ff)
[    3.032687] pcieport 0000:02:08.0: runtime IRQ mapping not provided by arch
[    3.032744] pcieport 0000:02:08.0: saving config space at offset 0x0 (reading 0x57a41022)
[    3.032746] pcieport 0000:02:08.0: saving config space at offset 0x4 (reading 0x100407)
[    3.032748] pcieport 0000:02:08.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.032750] pcieport 0000:02:08.0: saving config space at offset 0xc (reading 0x810010)
[    3.032752] pcieport 0000:02:08.0: saving config space at offset 0x10 (reading 0x0)
[    3.032753] pcieport 0000:02:08.0: saving config space at offset 0x14 (reading 0x0)
[    3.032755] pcieport 0000:02:08.0: saving config space at offset 0x18 (reading 0x50502)
[    3.032757] pcieport 0000:02:08.0: saving config space at offset 0x1c (reading 0x1f1)
[    3.032759] pcieport 0000:02:08.0: saving config space at offset 0x20 (reading 0xf730f720)
[    3.032760] pcieport 0000:02:08.0: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032762] pcieport 0000:02:08.0: saving config space at offset 0x28 (reading 0x0)
[    3.032764] pcieport 0000:02:08.0: saving config space at offset 0x2c (reading 0x0)
[    3.032766] pcieport 0000:02:08.0: saving config space at offset 0x30 (reading 0x0)
[    3.032770] pcieport 0000:02:08.0: saving config space at offset 0x34 (reading 0x50)
[    3.032771] pcieport 0000:02:08.0: saving config space at offset 0x38 (reading 0x0)
[    3.032773] pcieport 0000:02:08.0: saving config space at offset 0x3c (reading 0x12010b)
[    3.032836] pcieport 0000:02:09.0: runtime IRQ mapping not provided by arch
[    3.032913] pcieport 0000:02:09.0: saving config space at offset 0x0 (reading 0x57a41022)
[    3.032915] pcieport 0000:02:09.0: saving config space at offset 0x4 (reading 0x100407)
[    3.032916] pcieport 0000:02:09.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.032918] pcieport 0000:02:09.0: saving config space at offset 0xc (reading 0x810010)
[    3.032920] pcieport 0000:02:09.0: saving config space at offset 0x10 (reading 0x0)
[    3.032922] pcieport 0000:02:09.0: saving config space at offset 0x14 (reading 0x0)
[    3.032924] pcieport 0000:02:09.0: saving config space at offset 0x18 (reading 0x60602)
[    3.032925] pcieport 0000:02:09.0: saving config space at offset 0x1c (reading 0x1f1)
[    3.032927] pcieport 0000:02:09.0: saving config space at offset 0x20 (reading 0xf750f750)
[    3.032929] pcieport 0000:02:09.0: saving config space at offset 0x24 (reading 0x1fff1)
[    3.032931] pcieport 0000:02:09.0: saving config space at offset 0x28 (reading 0x0)
[    3.032932] pcieport 0000:02:09.0: saving config space at offset 0x2c (reading 0x0)
[    3.032934] pcieport 0000:02:09.0: saving config space at offset 0x30 (reading 0x0)
[    3.032936] pcieport 0000:02:09.0: saving config space at offset 0x34 (reading 0x50)
[    3.032938] pcieport 0000:02:09.0: saving config space at offset 0x38 (reading 0x0)
[    3.032940] pcieport 0000:02:09.0: saving config space at offset 0x3c (reading 0x12010a)
[    3.033002] pcieport 0000:02:0a.0: runtime IRQ mapping not provided by arch
[    3.033075] pcieport 0000:02:0a.0: saving config space at offset 0x0 (reading 0x57a41022)
[    3.033077] pcieport 0000:02:0a.0: saving config space at offset 0x4 (reading 0x100407)
[    3.033078] pcieport 0000:02:0a.0: saving config space at offset 0x8 (reading 0x6040000)
[    3.033080] pcieport 0000:02:0a.0: saving config space at offset 0xc (reading 0x810010)
[    3.033082] pcieport 0000:02:0a.0: saving config space at offset 0x10 (reading 0x0)
[    3.033084] pcieport 0000:02:0a.0: saving config space at offset 0x14 (reading 0x0)
[    3.033086] pcieport 0000:02:0a.0: saving config space at offset 0x18 (reading 0x70702)
[    3.033087] pcieport 0000:02:0a.0: saving config space at offset 0x1c (reading 0x1f1)
[    3.033089] pcieport 0000:02:0a.0: saving config space at offset 0x20 (reading 0xf740f740)
[    3.033091] pcieport 0000:02:0a.0: saving config space at offset 0x24 (reading 0x1fff1)
[    3.033093] pcieport 0000:02:0a.0: saving config space at offset 0x28 (reading 0x0)
[    3.033095] pcieport 0000:02:0a.0: saving config space at offset 0x2c (reading 0x0)
[    3.033096] pcieport 0000:02:0a.0: saving config space at offset 0x30 (reading 0x0)
[    3.033098] pcieport 0000:02:0a.0: saving config space at offset 0x34 (reading 0x50)
[    3.033100] pcieport 0000:02:0a.0: saving config space at offset 0x38 (reading 0x0)
[    3.033102] pcieport 0000:02:0a.0: saving config space at offset 0x3c (reading 0x12010f)
[    3.033260] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
[    3.041618] ACPI: Power Button [PWRB]
[    3.045293] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input1
[    3.052702] ACPI: Power Button [PWRF]
[    3.056436] Monitor-Mwait will be used to enter C-1 state
[    3.056443] ACPI: \_PR_.C000: Found 2 idle states
[    3.061305] ACPI: \_PR_.C002: Found 2 idle states
[    3.066145] ACPI: \_PR_.C004: Found 2 idle states
[    3.070891] ACPI: \_PR_.C006: Found 2 idle states
[    3.075648] ACPI: \_PR_.C008: Found 2 idle states
[    3.080419] ACPI: \_PR_.C00A: Found 2 idle states
[    3.085224] ACPI: \_PR_.C001: Found 2 idle states
[    3.090030] ACPI: \_PR_.C003: Found 2 idle states
[    3.094793] ACPI: \_PR_.C005: Found 2 idle states
[    3.099543] ACPI: \_PR_.C007: Found 2 idle states
[    3.104298] ACPI: \_PR_.C009: Found 2 idle states
[    3.109059] ACPI: \_PR_.C00B: Found 2 idle states
[    3.113921] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    3.120234] 00:04: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    3.127772] Non-volatile memory driver v1.3
[    3.131969] Linux agpgart interface v0.103
[    3.136073] agpgart-amd64 0000:00:00.0: runtime IRQ mapping not provided by arch
[    3.136078] agpgart-amd64 0000:00:01.0: runtime IRQ mapping not provided by arch
[    3.136081] agpgart-amd64 0000:00:02.0: runtime IRQ mapping not provided by arch
[    3.136084] agpgart-amd64 0000:00:03.0: runtime IRQ mapping not provided by arch
[    3.136087] agpgart-amd64 0000:00:04.0: runtime IRQ mapping not provided by arch
[    3.136090] agpgart-amd64 0000:00:05.0: runtime IRQ mapping not provided by arch
[    3.136092] agpgart-amd64 0000:00:07.0: runtime IRQ mapping not provided by arch
[    3.136095] agpgart-amd64 0000:00:08.0: runtime IRQ mapping not provided by arch
[    3.136099] agpgart-amd64 0000:00:14.0: runtime IRQ mapping not provided by arch
[    3.136102] agpgart-amd64 0000:00:14.3: runtime IRQ mapping not provided by arch
[    3.136106] agpgart-amd64 0000:00:18.0: runtime IRQ mapping not provided by arch
[    3.136108] agpgart-amd64 0000:00:18.1: runtime IRQ mapping not provided by arch
[    3.136110] agpgart-amd64 0000:00:18.2: runtime IRQ mapping not provided by arch
[    3.136113] agpgart-amd64 0000:00:18.3: runtime IRQ mapping not provided by arch
[    3.136115] agpgart-amd64 0000:00:18.4: runtime IRQ mapping not provided by arch
[    3.136117] agpgart-amd64 0000:00:18.5: runtime IRQ mapping not provided by arch
[    3.136120] agpgart-amd64 0000:00:18.6: runtime IRQ mapping not provided by arch
[    3.136122] agpgart-amd64 0000:00:18.7: runtime IRQ mapping not provided by arch
[    3.136125] agpgart-amd64 0000:03:00.0: runtime IRQ mapping not provided by arch
[    3.136137] agpgart-amd64 0000:03:00.1: runtime IRQ mapping not provided by arch
[    3.136207] agpgart-amd64 0000:03:00.1: saving config space at offset 0x0 (reading 0xe0f10de)
[    3.136209] agpgart-amd64 0000:03:00.1: saving config space at offset 0x4 (reading 0x100006)
[    3.136211] agpgart-amd64 0000:03:00.1: saving config space at offset 0x8 (reading 0x40300a1)
[    3.136213] agpgart-amd64 0000:03:00.1: saving config space at offset 0xc (reading 0x800010)
[    3.136215] agpgart-amd64 0000:03:00.1: saving config space at offset 0x10 (reading 0xf7080000)
[    3.136217] agpgart-amd64 0000:03:00.1: saving config space at offset 0x14 (reading 0x0)
[    3.136220] agpgart-amd64 0000:03:00.1: saving config space at offset 0x18 (reading 0x0)
[    3.136222] agpgart-amd64 0000:03:00.1: saving config space at offset 0x1c (reading 0x0)
[    3.136224] agpgart-amd64 0000:03:00.1: saving config space at offset 0x20 (reading 0x0)
[    3.136226] agpgart-amd64 0000:03:00.1: saving config space at offset 0x24 (reading 0x0)
[    3.136228] agpgart-amd64 0000:03:00.1: saving config space at offset 0x28 (reading 0x0)
[    3.136230] agpgart-amd64 0000:03:00.1: saving config space at offset 0x2c (reading 0x536019da)
[    3.136233] agpgart-amd64 0000:03:00.1: saving config space at offset 0x30 (reading 0x0)
[    3.136235] agpgart-amd64 0000:03:00.1: saving config space at offset 0x34 (reading 0x60)
[    3.136237] agpgart-amd64 0000:03:00.1: saving config space at offset 0x38 (reading 0x0)
[    3.136239] agpgart-amd64 0000:03:00.1: saving config space at offset 0x3c (reading 0x2ff)
[    3.136263] agpgart-amd64 0000:04:00.0: runtime IRQ mapping not provided by arch
[    3.136277] agpgart-amd64 0000:05:00.0: runtime IRQ mapping not provided by arch
[    3.136286] agpgart-amd64 0000:05:00.1: runtime IRQ mapping not provided by arch
[    3.136353] agpgart-amd64 0000:05:00.3: runtime IRQ mapping not provided by arch
[    3.136366] agpgart-amd64 0000:06:00.0: runtime IRQ mapping not provided by arch
[    3.136378] agpgart-amd64 0000:07:00.0: runtime IRQ mapping not provided by arch
[    3.136390] agpgart-amd64 0000:08:00.0: runtime IRQ mapping not provided by arch
[    3.136400] agpgart-amd64 0000:09:00.0: runtime IRQ mapping not provided by arch
[    3.136405] agpgart-amd64 0000:0a:00.0: runtime IRQ mapping not provided by arch
[    3.136411] agpgart-amd64 0000:0a:00.1: runtime IRQ mapping not provided by arch
[    3.136418] agpgart-amd64 0000:0a:00.3: runtime IRQ mapping not provided by arch
[    3.136426] agpgart-amd64 0000:0a:00.4: runtime IRQ mapping not provided by arch
[    3.136432] agpgart-amd64 0000:0b:00.0: runtime IRQ mapping not provided by arch
[    3.136439] agpgart-amd64 0000:0c:00.0: runtime IRQ mapping not provided by arch
[    3.138646] loop: module loaded
[    3.141909] ahci 0000:06:00.0: runtime IRQ mapping not provided by arch
[    3.141911] ahci 0000:06:00.0: version 3.0
[    3.142016] ahci 0000:06:00.0: AHCI 0001.0301 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[    3.150102] ahci 0000:06:00.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part 
[    3.159000] scsi host0: ahci
[    3.161912] ata1: SATA max UDMA/133 abar m2048@0xf7500000 port 0xf7500100 irq 41
[    3.169310] ahci 0000:07:00.0: runtime IRQ mapping not provided by arch
[    3.169413] ahci 0000:07:00.0: AHCI 0001.0301 32 slots 1 ports 6 Gbps 0x2 impl SATA mode
[    3.177497] ahci 0000:07:00.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part 
[    3.186405] scsi host1: ahci
[    3.189351] scsi host2: ahci
[    3.192250] ata2: DUMMY
[    3.194697] ata3: SATA max UDMA/133 abar m2048@0xf7400000 port 0xf7400180 irq 42
[    3.202097] ahci 0000:0b:00.0: runtime IRQ mapping not provided by arch
[    3.202167] ahci 0000:0b:00.0: AHCI 0001.0301 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[    3.210250] ahci 0000:0b:00.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part 
[    3.219130] scsi host3: ahci
[    3.222030] ata4: SATA max UDMA/133 abar m2048@0xf7c00000 port 0xf7c00100 irq 44
[    3.229422] ahci 0000:0c:00.0: runtime IRQ mapping not provided by arch
[    3.229489] ahci 0000:0c:00.0: AHCI 0001.0301 32 slots 1 ports 6 Gbps 0x1 impl SATA mode
[    3.237578] ahci 0000:0c:00.0: flags: 64bit ncq sntf ilck pm led clo only pmp fbs pio slum part 
[    3.246483] scsi host4: ahci
[    3.249384] ata5: SATA max UDMA/133 abar m2048@0xf7b00000 port 0xf7b00100 irq 46
[    3.256903] e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
[    3.262994] e100: Copyright(c) 1999-2006 Intel Corporation
[    3.268478] e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI
[    3.275521] e1000: Copyright (c) 1999-2006 Intel Corporation.
[    3.281267] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    3.287096] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    3.293026] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.6.0-k
[    3.299988] igb: Copyright (c) 2007-2014 Intel Corporation.
[    3.305566] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
[    3.313389] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
[    3.319306] sky2: driver version 1.30
[    3.323004] r8169 0000:04:00.0: runtime IRQ mapping not provided by arch
[    3.323033] r8169 0000:04:00.0: enabling Mem-Wr-Inval
[    3.330132] kworker/u64:5 (145) used greatest stack depth: 14576 bytes left
[    3.330220] libphy: r8169: probed
[    3.340490] r8169 0000:04:00.0 eth0: RTL8168h/8111h, a8:5e:45:e7:e4:72, XID 541, IRQ 47
[    3.348487] r8169 0000:04:00.0 eth0: jumbo features [frames: 9194 bytes, tx checksumming: ko]
[    3.357014] PPP generic driver version 2.4.2
[    3.361302] usbcore: registered new interface driver r8152
[    3.366789] usbcore: registered new interface driver asix
[    3.372189] usbcore: registered new interface driver ax88179_178a
[    3.378282] usbcore: registered new interface driver cdc_ether
[    3.384117] usbcore: registered new interface driver net1080
[    3.389780] usbcore: registered new interface driver cdc_subset
[    3.395699] usbcore: registered new interface driver zaurus
[    3.401276] usbcore: registered new interface driver cdc_ncm
[    3.406964] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    3.413488] ehci-pci: EHCI PCI platform driver
[    3.417941] ehci-platform: EHCI generic platform driver
[    3.423167] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    3.429344] ohci-pci: OHCI PCI platform driver
[    3.433795] ohci-platform: OHCI generic platform driver
[    3.439021] uhci_hcd: USB Universal Host Controller Interface driver
[    3.445384] xhci_hcd 0000:05:00.1: runtime IRQ mapping not provided by arch
[    3.445467] xhci_hcd 0000:05:00.1: enabling bus mastering
[    3.445760] xhci_hcd 0000:05:00.1: xHCI Host Controller
[    3.451004] xhci_hcd 0000:05:00.1: new USB bus registered, assigned bus number 1
[    3.458547] xhci_hcd 0000:05:00.1: hcc params 0x0278ffe5 hci version 0x110 quirks 0x0000000000000410
[    3.467694] xhci_hcd 0000:05:00.1: enabling Mem-Wr-Inval
[    3.468354] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.08
[    3.474115] ata1: SATA link down (SStatus 0 SControl 300)
[    3.476611] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.489233] usb usb1: Product: xHCI Host Controller
[    3.494112] usb usb1: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.499765] usb usb1: SerialNumber: 0000:05:00.1
[    3.504447] hub 1-0:1.0: USB hub found
[    3.508208] hub 1-0:1.0: 6 ports detected
[    3.512489] xhci_hcd 0000:05:00.1: xHCI Host Controller
[    3.517729] xhci_hcd 0000:05:00.1: new USB bus registered, assigned bus number 2
[    3.525125] xhci_hcd 0000:05:00.1: Host supports USB 3.1 Enhanced SuperSpeed
[    3.532179] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
[    3.537122] ata4: SATA link down (SStatus 0 SControl 300)
[    3.540268] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.08
[    3.553924] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.561146] usb usb2: Product: xHCI Host Controller
[    3.561168] ata5: SATA link down (SStatus 0 SControl 300)
[    3.566027] usb usb2: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.566027] usb usb2: SerialNumber: 0000:05:00.1
[    3.566553] hub 2-0:1.0: USB hub found
[    3.585452] hub 2-0:1.0: 4 ports detected
[    3.589655] xhci_hcd 0000:05:00.3: runtime IRQ mapping not provided by arch
[    3.589680] xhci_hcd 0000:05:00.3: enabling bus mastering
[    3.589682] xhci_hcd 0000:05:00.3: xHCI Host Controller
[    3.594934] xhci_hcd 0000:05:00.3: new USB bus registered, assigned bus number 3
[    3.602473] xhci_hcd 0000:05:00.3: hcc params 0x0278ffe5 hci version 0x110 quirks 0x0000000000000410
[    3.611605] xhci_hcd 0000:05:00.3: enabling Mem-Wr-Inval
[    3.611790] usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.08
[    3.620045] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.627268] usb usb3: Product: xHCI Host Controller
[    3.632150] usb usb3: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.637808] usb usb3: SerialNumber: 0000:05:00.3
[    3.642491] hub 3-0:1.0: USB hub found
[    3.646256] hub 3-0:1.0: 6 ports detected
[    3.650540] xhci_hcd 0000:05:00.3: xHCI Host Controller
[    3.655795] xhci_hcd 0000:05:00.3: new USB bus registered, assigned bus number 4
[    3.663184] xhci_hcd 0000:05:00.3: Host supports USB 3.1 Enhanced SuperSpeed
[    3.667810] ata3: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[    3.670242] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[    3.677597] ata3.00: ATA-11: WDC  WDS100T2B0A-00SM50, 401020WD, max UDMA/133
[    3.684509] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.08
[    3.691542] ata3.00: 1953525168 sectors, multi 1: LBA48 NCQ (depth 32), AA
[    3.693790] ata3.00: configured for UDMA/133
[    3.699813] usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.699814] usb usb4: Product: xHCI Host Controller
[    3.706765] scsi 2:0:0:0: Direct-Access     ATA      WDC  WDS100T2B0A 20WD PQ: 0 ANSI: 5
[    3.710962] usb usb4: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.710962] usb usb4: SerialNumber: 0000:05:00.3
[    3.711018] hub 4-0:1.0: USB hub found
[    3.718296] sd 2:0:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/932 GiB)
[    3.718628] sd 2:0:0:0: Attached scsi generic sg0 type 0
[    3.723074] hub 4-0:1.0: 4 ports detected
[    3.731159] sd 2:0:0:0: [sda] Write Protect is off
[    3.737019] xhci_hcd 0000:0a:00.3: runtime IRQ mapping not provided by arch
[    3.741436] sd 2:0:0:0: [sda] Mode Sense: 00 3a 00 00
[    3.745208] xhci_hcd 0000:0a:00.3: enabling bus mastering
[    3.752874] sd 2:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[    3.758176] xhci_hcd 0000:0a:00.3: xHCI Host Controller
[    3.781331] xhci_hcd 0000:0a:00.3: new USB bus registered, assigned bus number 5
[    3.781710] sd 2:0:0:0: [sda] Attached SCSI disk
[    3.788865] xhci_hcd 0000:0a:00.3: hcc params 0x0278ffe5 hci version 0x110 quirks 0x0000000000000410
[    3.802468] xhci_hcd 0000:0a:00.3: enabling Mem-Wr-Inval
[    3.802618] usb usb5: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.08
[    3.810878] usb usb5: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.818096] usb usb5: Product: xHCI Host Controller
[    3.822969] usb usb5: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.828623] usb usb5: SerialNumber: 0000:0a:00.3
[    3.833513] hub 5-0:1.0: USB hub found
[    3.837268] hub 5-0:1.0: 4 ports detected
[    3.841399] xhci_hcd 0000:0a:00.3: xHCI Host Controller
[    3.847068] xhci_hcd 0000:0a:00.3: new USB bus registered, assigned bus number 6
[    3.854458] xhci_hcd 0000:0a:00.3: Host supports USB 3.1 Enhanced SuperSpeed
[    3.861515] usb usb6: We don't know the algorithms for LPM for this host, disabling LPM.
[    3.861772] usb 1-1: new low-speed USB device number 2 using xhci_hcd
[    3.869652] usb usb6: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.08
[    3.884304] usb usb6: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[    3.891538] usb usb6: Product: xHCI Host Controller
[    3.896416] usb usb6: Manufacturer: Linux 5.8.0-rc6 xhci-hcd
[    3.902077] usb usb6: SerialNumber: 0000:0a:00.3
[    3.906748] hub 6-0:1.0: USB hub found
[    3.910497] hub 6-0:1.0: 4 ports detected
[    3.914619] usbcore: registered new interface driver cdc_acm
[    3.920281] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[    3.928284] usbcore: registered new interface driver usblp
[    3.933785] usbcore: registered new interface driver usb-storage
[    3.939793] usbcore: registered new interface driver ftdi_sio
[    3.945544] usbserial: USB Serial support registered for FTDI USB Serial Device
[    3.952933] usbcore: registered new interface driver pl2303
[    3.958511] usbserial: USB Serial support registered for pl2303
[    3.964439] i8042: PNP: No PS/2 controller found.
[    3.969204] rtc_cmos 00:02: RTC can wake from S4
[    3.973956] rtc_cmos 00:02: registered as rtc0
[    3.978403] rtc_cmos 00:02: alarms up to one month, y3k, 114 bytes nvram, hpet irqs
[    3.986051] usb 3-6: new full-speed USB device number 2 using xhci_hcd
[    3.989798] i2c /dev entries driver
[    3.995777] tsc: Refined TSC clocksource calibration: 3792.873 MHz
[    3.996117] usbcore: registered new interface driver uvcvideo
[    4.002257] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6d5818a734c, max_idle_ns: 881590694765 ns
[    4.008003] USB Video Class driver (1.1.1)
[    4.022104] usb 1-1: New USB device found, idVendor=413c, idProduct=301a, bcdDevice= 1.00
[    4.022105] clocksource: Switched to clocksource tsc
[    4.022155] device-mapper: ioctl: 4.42.0-ioctl (2020-02-27) initialised: dm-devel@redhat.com
[    4.022162] hid: raw HID events driver (C) Jiri Kosina
[    4.022220] usbcore: registered new interface driver usbhid
[    4.022220] usbhid: USB HID core driver
[    4.022280] snd_hda_intel 0000:03:00.1: runtime IRQ mapping not provided by arch
[    4.022412] snd_hda_intel 0000:03:00.1: Disabling MSI
[    4.022470] snd_hda_intel 0000:0a:00.4: runtime IRQ mapping not provided by arch
[    4.022559] GACT probability on
[    4.022561] Mirror/redirect action on
[    4.022564] Simple TC action Loaded
[    4.022567] u32 classifier
[    4.022567]     Performance counters on
[    4.022567]     input device check on
[    4.022567]     Actions configured
[    4.030274] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    4.054397] Initializing XFRM netlink socket
[    4.057762] hdaudio hdaudioC0D0: Unable to bind the codec
[    4.058231] usb 1-1: Product: Dell MS116 USB Optical Mouse
[    4.058231] usb 1-1: Manufacturer: PixArt
[    4.060182] random: fast init done
[    4.063333] NET: Registered protocol family 10
[    4.067564] hdaudio hdaudioC1D0: Unable to bind the codec
[    4.070272] Segment Routing with IPv6
[    4.074336] input: PixArt Dell MS116 USB Optical Mouse as /devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:05:00.1/usb1/1-1/1-1:1.0/0003:413C:301A.0001/input/input2
[    4.098641] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    4.104061] hid-generic 0003:413C:301A.0001: input,hidraw0: USB HID v1.11 Mouse [PixArt Dell MS116 USB Optical Mouse] on usb-0000:05:00.1-1/input0
[    4.109576] NET: Registered protocol family 17
[    4.133545] usb 3-6: config 1 has an invalid interface number: 2 but max is 1
[    4.146445] Key type dns_resolver registered
[    4.152327] usb 3-6: config 1 has no interface number 1
[    4.163281] usb 3-6: New USB device found, idVendor=0b05, idProduct=18f3, bcdDevice= 1.00
[    4.194702] usb 3-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    4.201836] usb 3-6: Product: AURA LED Controller
[    4.206542] usb 3-6: Manufacturer: AsusTek Computer Inc.
[    4.211856] usb 3-6: SerialNumber: 9876543210
[    4.216266] microcode: CPU0: patch_level=0x08701013
[    4.221398] microcode: CPU1: patch_level=0x08701013
[    4.226287] microcode: CPU2: patch_level=0x08701013
[    4.226773] usb 1-2: new low-speed USB device number 3 using xhci_hcd
[    4.231167] microcode: CPU3: patch_level=0x08701013
[    4.231359] hid-generic 0003:0B05:18F3.0002: hiddev96,hidraw1: USB HID v1.11 Device [AsusTek Computer Inc. AURA LED Controller] on usb-0000:05:00.3-6/input2
[    4.256449] microcode: CPU4: patch_level=0x08701013
[    4.261331] microcode: CPU5: patch_level=0x08701013
[    4.266213] microcode: CPU6: patch_level=0x08701013
[    4.271314] microcode: CPU7: patch_level=0x08701013
[    4.276202] microcode: CPU8: patch_level=0x08701013
[    4.281078] microcode: CPU9: patch_level=0x08701013
[    4.285963] microcode: CPU10: patch_level=0x08701013
[    4.290927] microcode: CPU11: patch_level=0x08701013
[    4.295894] microcode: Microcode Update Driver: v2.2.
[    4.295896] IPI shorthand broadcast: enabled
[    4.305219] sched_clock: Marking stable (4308444624, -3232330)->(4631337036, -326124742)
[    4.313706] registered taskstats version 1
[    4.317804] Loading compiled-in X.509 certificates
[    4.322742] Key type encrypted registered
[    4.326764] ima: No TPM chip found, activating TPM-bypass!
[    4.332252] ima: Allocated hash algorithm: sha1
[    4.336791] ima: No architecture policies found
[    4.341323] evm: Initialising EVM extended attributes:
[    4.346459] evm: security.selinux
[    4.349771] evm: security.ima
[    4.352743] evm: security.capability
[    4.356316] evm: HMAC attrs: 0x1
[    4.359753] PM:   Magic number: 12:356:231
[    4.363877] acpi device:4b: hash matches
[    4.367803] printk: console [netcon0] enabled
[    4.372157] netconsole: network logging started
[    4.376980] acpi_cpufreq: overriding BIOS provided _PSD data
[    4.380267] usb 1-2: New USB device found, idVendor=413c, idProduct=2107, bcdDevice= 1.78
[    4.390813] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    4.397948] usb 1-2: Product: Dell USB Entry Keyboard
[    4.398489] r8169 0000:04:00.0: Direct firmware load for rtl_nic/rtl8168h-2.fw failed with error -2
[    4.403000] usb 1-2: Manufacturer: DELL
[    4.415886] r8169 0000:04:00.0: Unable to load firmware rtl_nic/rtl8168h-2.fw (-2)
[    4.427374] input: DELL Dell USB Entry Keyboard as /devices/pci0000:00/0000:00:01.2/0000:01:00.0/0000:02:08.0/0000:05:00.1/usb1/1-2/1-2:1.0/0003:413C:2107.0003/input/input3
[    4.444773] Generic FE-GE Realtek PHY r8169-400:00: attached PHY driver [Generic FE-GE Realtek PHY] (mii_bus:phy_addr=r8169-400:00, irq=IGNORE)
[    4.493827] hid-generic 0003:413C:2107.0003: input,hidraw2: USB HID v1.10 Keyboard [DELL Dell USB Entry Keyboard] on usb-0000:05:00.1-2/input0
[    4.554840] r8169 0000:04:00.0 eth0: Link is Down
[    8.117235] r8169 0000:04:00.0 eth0: Link is Up - 1Gbps/Full - flow control rx/tx
[    8.119802] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[    8.131772] Sending DHCP requests .., OK
[   10.949721] IP-Config: Got DHCP answer from 192.168.1.100, my address is 192.168.1.103
[   10.957636] IP-Config: Complete:
[   10.960869]      device=eth0, hwaddr=a8:5e:45:e7:e4:72, ipaddr=192.168.1.103, mask=255.255.255.0, gw=192.168.1.254
[   10.971211]      host=192.168.1.103, domain=broadcom.com, nis-domain=(none)
[   10.978163]      bootserver=192.168.1.100, rootserver=192.168.1.100, rootpath=
[   10.978164]      nameserver0=192.168.1.100, nameserver1=192.168.1.1
[   10.991680] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[   10.999797] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[   11.006331] ALSA device list:
[   11.009298]   No soundcards found.
[   11.012727] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[   11.021332] cfg80211: failed to load regulatory.db
[   11.026245] md: Skipping autodetection of RAID arrays. (raid=autodetect will force)
[   11.034044] nfs: Deprecated parameter 'intr'
[   11.048021] VFS: Mounted root (nfs filesystem) readonly on device 0:18.
[   11.054840] devtmpfs: mounted
[   11.058967] Freeing unused kernel image (initmem) memory: 1604K
[   11.074789] Write protecting the kernel read-only data: 24576k
[   11.081156] Freeing unused kernel image (text/rodata gap) memory: 2040K
[   11.088198] Freeing unused kernel image (rodata/data gap) memory: 2000K
[   11.094912] Run /sbin/init as init process
[   11.099079]   with arguments:
[   11.099080]     /sbin/init
[   11.099080]     nfsrootdebug
[   11.099080]   with environment:
[   11.099080]     HOME=/
[   11.099081]     TERM=linux
[   11.099081]     BOOT_IMAGE=/bzImage
[   11.187823] mount (167) used greatest stack depth: 12712 bytes left
[   11.209514] ls (174) used greatest stack depth: 12392 bytes left
[   11.241429] random: crng init done
[   11.260123] udevd[196]: starting version 3.2.9
[   11.283940] udevd[197]: starting eudev-3.2.9
[   11.331177] piix4_smbus 0000:00:14.0: runtime IRQ mapping not provided by arch
[   11.331217] piix4_smbus 0000:00:14.0: SMBus Host Controller at 0xb00, revision 0
[   11.338750] piix4_smbus 0000:00:14.0: Using register 0x02 for SMBus port selection
[   11.346697] piix4_smbus 0000:00:14.0: Auxiliary SMBus Host Controller at 0xb20
[   11.354193] bcm-vk 0000:08:00.0: runtime IRQ mapping not provided by arch
[   11.354372] bcm-vk 0000:08:00.0: Number of IRQs 6 allocated - requested(6).
[   11.361537] bcm-vk 0000:08:00.0: BAR1 msgq marker not initialized.
[   11.367943] bcm-vk 0000:08:00.0: create sysfs group for bcm-vk
[   11.374328] bcm-vk 0000:08:00.0: BCM-VK:0 created, 0x00000000a8ec69cf
[   11.374329] bcm-vk 0000:08:00.0: Load All for device 0
[   11.374335] bcm-vk 0000:08:00.0: boot-status value for next image: 0x10006 : fw-status 0x0
[   11.397492] bcm-vk 0000:08:00.0: size=0x32230
[   11.402652] bcm-vk 0000:08:00.0: Signaling 0x400001 to 0x400
[   13.079988] bcm-vk 0000:08:00.0: Auto load vk-boot1.bin, ret 0
[   13.085872] bcm-vk 0000:08:00.0: boot-status value for next image: 0x20006 : fw-status 0x0
[   13.095774] bcm-vk 0000:08:00.0: loading /lib/firmware/vk-boot2.bin failed with error -13
[   13.103988] bcm-vk 0000:08:00.0: Direct firmware load for vk-boot2.bin failed with error -13
[   13.112464] bcm-vk 0000:08:00.0: Error -13 requesting firmware file: vk-boot2.bin
[   13.120003] bcm-vk 0000:08:00.0: Auto load vk-boot2.bin, ret -13
[   13.126048] bcm-vk 0000:08:00.0: Error loading default vk-boot2.bin
[  136.357639] test_firmware: loading 'test-firmware.bin'
[  136.363006] test_firmware: loaded: 8
[  136.368117] test_firmware: loading 'test-firmware.bin'
[  136.374629] misc test_firmware: Direct firmware load for test-firmware.bin failed with error -2
[  136.384782] test_firmware: load of 'test-firmware.bin' failed: -2
[  136.446576] test_firmware: loading ''
[  136.450303] test_firmware: load of '' failed: -22
[  136.455075] test_firmware: loading ''
[  136.458769] test_firmware: failed to async load firmware
[  136.464155] test_firmware: loading 'nope-test-firmware.bin'
[  136.470362] misc test_firmware: Direct firmware load for nope-test-firmware.bin failed with error -2
[  136.479609] Ignoring firmware sysfs fallback due to sysctl knob
[  136.485588] test_firmware: load of 'nope-test-firmware.bin' failed: -2
[  136.495207] test_firmware: loading 'test-firmware.bin'
[  136.500440] test_firmware: loaded: 9
[  136.504882] test_firmware: loading 'test-firmware.bin'
[  136.511430] test_firmware: loaded: 9
[  136.519547] test_firmware: reset
[  136.523702] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  136.532910] test_firmware: #0: batched sync loaded 9
[  136.532913] test_firmware: #1: batched sync loaded 9
[  136.532935] test_firmware: #2: batched sync loaded 9
[  136.532943] test_firmware: #3: batched sync loaded 9
[  136.558571] test_firmware: #0: loaded 9
[  136.564651] test_firmware: #1: loaded 9
[  136.569908] test_firmware: #2: loaded 9
[  136.575046] test_firmware: #3: loaded 9
[  136.579661] test_firmware: reset
[  136.584225] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  136.593428] test_firmware: #0: batched sync loaded 9
[  136.593446] test_firmware: #1: batched sync loaded 9
[  136.593467] test_firmware: #2: batched sync loaded 9
[  136.593489] test_firmware: #3: batched sync loaded 9
[  136.617591] test_firmware: #0: loaded 9
[  136.622437] test_firmware: #1: loaded 9
[  136.627237] test_firmware: #2: loaded 9
[  136.631959] test_firmware: #3: loaded 9
[  136.635947] test_firmware: reset
[  136.639547] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  136.648764] test_firmware: #0: batched sync loaded 9
[  136.648775] test_firmware: #1: batched sync loaded 9
[  136.648791] test_firmware: #2: batched sync loaded 9
[  136.648804] test_firmware: #3: batched sync loaded 9
[  136.672384] test_firmware: #0: loaded 9
[  136.677331] test_firmware: #1: loaded 9
[  136.682217] test_firmware: #2: loaded 9
[  136.687178] test_firmware: #3: loaded 9
[  136.691187] test_firmware: reset
[  136.694773] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  136.703977] test_firmware: #0: batched sync loaded 9
[  136.703993] test_firmware: #1: batched sync loaded 9
[  136.704019] test_firmware: #2: batched sync loaded 9
[  136.704041] test_firmware: #3: batched sync loaded 9
[  136.727925] test_firmware: #0: loaded 9
[  136.732526] test_firmware: #1: loaded 9
[  136.737208] test_firmware: #2: loaded 9
[  136.742227] test_firmware: #3: loaded 9
[  136.746210] test_firmware: reset
[  136.749819] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  136.759100] test_firmware: #0: batched sync loaded 9
[  136.759111] test_firmware: #1: batched sync loaded 9
[  136.759130] test_firmware: #2: batched sync loaded 9
[  136.759150] test_firmware: #3: batched sync loaded 9
[  136.784720] test_firmware: #0: loaded 9
[  136.789574] test_firmware: #1: loaded 9
[  136.794337] test_firmware: #2: loaded 9
[  136.799054] test_firmware: #3: loaded 9
[  136.803849] test_firmware: reset
[  136.808521] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  136.818547] test_firmware: #0: batched sync loaded 9
[  136.818573] test_firmware: #1: batched sync loaded 9
[  136.818598] test_firmware: #2: batched sync loaded 9
[  136.818620] test_firmware: #3: batched sync loaded 9
[  136.843317] test_firmware: #0: loaded 9
[  136.848118] test_firmware: #1: loaded 9
[  136.852718] test_firmware: #2: loaded 9
[  136.857405] test_firmware: #3: loaded 9
[  136.861395] test_firmware: reset
[  136.864997] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  136.874994] test_firmware: #0: batched sync loaded 9
[  136.875006] test_firmware: #1: batched sync loaded 9
[  136.875024] test_firmware: #2: batched sync loaded 9
[  136.875035] test_firmware: #3: batched sync loaded 9
[  136.900275] test_firmware: #0: loaded 9
[  136.905224] test_firmware: #1: loaded 9
[  136.910055] test_firmware: #2: loaded 9
[  136.915076] test_firmware: #3: loaded 9
[  136.919078] test_firmware: reset
[  136.922745] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  136.932734] test_firmware: #0: batched sync loaded 9
[  136.932741] test_firmware: #1: batched sync loaded 9
[  136.932760] test_firmware: #2: batched sync loaded 9
[  136.932778] test_firmware: #3: batched sync loaded 9
[  136.957999] test_firmware: #0: loaded 9
[  136.962567] test_firmware: #1: loaded 9
[  136.967274] test_firmware: #2: loaded 9
[  136.971985] test_firmware: #3: loaded 9
[  136.976012] test_firmware: reset
[  136.979634] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  136.989700] test_firmware: #0: batched sync loaded 9
[  136.989714] test_firmware: #1: batched sync loaded 9
[  136.989742] test_firmware: #2: batched sync loaded 9
[  136.989763] test_firmware: #3: batched sync loaded 9
[  137.015020] test_firmware: #0: loaded 9
[  137.019616] test_firmware: #1: loaded 9
[  137.024321] test_firmware: #2: loaded 9
[  137.029242] test_firmware: #3: loaded 9
[  137.033251] test_firmware: reset
[  137.036876] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  137.046928] test_firmware: #0: batched sync loaded 9
[  137.046939] test_firmware: #1: batched sync loaded 9
[  137.046959] test_firmware: #2: batched sync loaded 9
[  137.046974] test_firmware: #3: batched sync loaded 9
[  137.071777] test_firmware: #0: loaded 9
[  137.076753] test_firmware: #1: loaded 9
[  137.081799] test_firmware: #2: loaded 9
[  137.086571] test_firmware: #3: loaded 9
[  137.091486] test_firmware: reset
[  137.096167] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  137.105387] test_firmware: #0: batched sync loaded 9
[  137.105409] test_firmware: #1: batched sync loaded 9
[  137.105428] test_firmware: #2: batched sync loaded 9
[  137.105455] test_firmware: #3: batched sync loaded 9
[  137.126974] test_firmware: reset
[  137.130627] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  137.139872] test_firmware: #0: batched sync loaded 9
[  137.139892] test_firmware: #1: batched sync loaded 9
[  137.139909] test_firmware: #2: batched sync loaded 9
[  137.139927] test_firmware: #3: batched sync loaded 9
[  137.161393] test_firmware: reset
[  137.166030] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  137.175460] test_firmware: #0: batched sync loaded 9
[  137.175482] test_firmware: #1: batched sync loaded 9
[  137.175499] test_firmware: #2: batched sync loaded 9
[  137.175515] test_firmware: #3: batched sync loaded 9
[  137.198294] test_firmware: reset
[  137.202049] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  137.211302] test_firmware: #0: batched sync loaded 9
[  137.211322] test_firmware: #1: batched sync loaded 9
[  137.211338] test_firmware: #2: batched sync loaded 9
[  137.211364] test_firmware: #3: batched sync loaded 9
[  137.232888] test_firmware: reset
[  137.237538] test_firmware: batched sync firmware loading 'test-firmware.bin' 4 times
[  137.246860] test_firmware: #0: batched sync loaded 9
[  137.246877] test_firmware: #1: batched sync loaded 9
[  137.246895] test_firmware: #2: batched sync loaded 9
[  137.246913] test_firmware: #3: batched sync loaded 9
[  137.271100] test_firmware: reset
[  137.275788] test_firmware: batched loading 'test-firmware.bin' custom fallback mechanism 4 times
[  139.292329] test_firmware: reset
[  139.297007] test_firmware: batched loading 'test-firmware.bin' custom fallback mechanism 4 times
[  141.340417] test_firmware: reset
[  141.345093] test_firmware: batched loading 'test-firmware.bin' custom fallback mechanism 4 times
[  143.388283] test_firmware: reset
[  143.392943] test_firmware: batched loading 'test-firmware.bin' custom fallback mechanism 4 times
[  145.436322] test_firmware: reset
[  145.441016] test_firmware: batched loading 'test-firmware.bin' custom fallback mechanism 4 times
[  147.486797] test_firmware: reset
[  147.495651] test_firmware: batched loading 'tmp.Vq9nh3BvWk' custom fallback mechanism 4 times
[  149.532308] test_firmware: reset
[  149.540097] test_firmware: batched loading 'tmp.1tobhfvFNK' custom fallback mechanism 4 times
[  151.580326] test_firmware: reset
[  151.587989] test_firmware: batched loading 'tmp.LbGOGkRdof' custom fallback mechanism 4 times
[  153.628306] test_firmware: reset
[  153.636620] test_firmware: batched loading 'tmp.a5iR0kSKpb' custom fallback mechanism 4 times
[  155.676304] test_firmware: reset
[  155.683611] test_firmware: batched loading 'tmp.9xBJ0EVxCB' custom fallback mechanism 4 times
[  157.724756] test_firmware: reset
[  157.729481] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  157.739580] test_firmware: #0: batched sync loaded 9
[  157.739595] test_firmware: #1: batched sync loaded 9
[  157.739662] test_firmware: #2: batched sync loaded 9
[  157.739932] test_firmware: #3: batched sync loaded 9
[  157.765840] test_firmware: #0: loaded 9
[  157.770578] test_firmware: #1: loaded 9
[  157.775407] test_firmware: #2: loaded 9
[  157.780184] test_firmware: #3: loaded 9
[  157.784231] test_firmware: reset
[  157.787898] test_firmware: batched sync firmware loading 'test-firmware-into-buf.bin' 4 times
[  157.797871] misc test_firmware: loading /tmp/tmp.qUu5FcrDRC/test-firmware-into-buf.bin failed with error -13
[  157.797897] misc test_firmware: loading /tmp/tmp.qUu5FcrDRC/test-firmware-into-buf.bin failed with error -13
[  157.797918] misc test_firmware: loading /tmp/tmp.qUu5FcrDRC/test-firmware-into-buf.bin failed with error -13
[  157.797939] misc test_firmware: loading /tmp/tmp.qUu5FcrDRC/test-firmware-into-buf.bin failed with error -13
[  157.809251] misc test_firmware: Direct firmware load for test-firmware-into-buf.bin failed with error -2
[  157.809252] misc test_firmware: Direct firmware load for test-firmware-into-buf.bin failed with error -2
[  157.809253] misc test_firmware: Direct firmware load for test-firmware-into-buf.bin failed with error -2
[  157.809253] test_firmware: #2: batched sync load failed: -2
[  157.809254] test_firmware: #3: batched sync load failed: -2
[  157.820578] misc test_firmware: Direct firmware load for test-firmware-into-buf.bin failed with error -2
[  157.830483] test_firmware: #0: batched sync load failed: -2
[  157.840417] test_firmware: #1: batched sync load failed: -2
[  157.905204] test_firmware: #0: failed to async load firmware

[-- Attachment #3: Type: text/plain, Size: 143 bytes --]

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-23 19:17       ` Kees Cook
@ 2020-07-24  5:46         ` Scott Branden
  0 siblings, 0 replies; 38+ messages in thread
From: Scott Branden @ 2020-07-24  5:46 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann



On 2020-07-23 12:17 p.m., Kees Cook wrote:
> On Wed, Jul 22, 2020 at 11:23:43PM -0700, Scott Branden wrote:
>> I made an adjustment in the logic of the driver with use of
>> request_partial_firmware_into_buf and now everything is working.
> Excellent! Was there something wrong with how I ported the
> request_partial_firmware_into_buf() changes? (Should the behavior be
> changed in some way? I didn't change the self-tests, so I thought the
> behavior matched your original series.)
The change in behaviour is fw->fw_size used to indicate the position in 
the file after the partial read completes.
Your version has fw->fw_size indicate the amount of data read.
No need for you to change anything.  I just need a local variable now to 
keep track of where I left off in the file.
>
>> So only issue I find with this entire patch series is the problem
>> of security failing without the workaround below.
> Yup; I'm trying to reproduce this now too...
I replied in the other email with details and the dmesg log.
>


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-24  5:41       ` Scott Branden
@ 2020-07-24 18:23         ` Kees Cook
  2020-07-24 18:39           ` Kees Cook
  0 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-24 18:23 UTC (permalink / raw)
  To: Scott Branden
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Thu, Jul 23, 2020 at 10:41:07PM -0700, Scott Branden wrote:
> 
> 
> On 2020-07-23 12:15 p.m., Kees Cook wrote:
> > On Wed, Jul 22, 2020 at 03:29:26PM -0700, Scott Branden wrote:
> > > These changes don't pass the kernel-selftest for partial reads I added
> > > (which are at the end of this patch v2 series).
> > Oh, interesting. Is there any feedback in dmesg? I wonder if I have the
> > LSMs configured differently than you?
> I have no LSMs configured that I know of.
> Yes, there is failure in dmesg which is how I determined to add my
> workaround.
> Without workaround, dmesg log attached after booting and running
> fw_run_tests.h
> > > See change below added for temp workaround for issue.
> > > > [...]
> > > > +
> > > > +	whole_file = (offset == 0 && i_size <= buf_size);
> > > A hack to get this passing I added which probably breaks some security?
> > > if (whole_file) {
> > > > +	ret = security_kernel_read_file(file, id, whole_file);
> > > > +	if (ret)
> > > > +		goto out;
> > > > +
> > > }
> > This would imply I did something wrong in the LSM hook refactoring (i.e.
> > some LSM is rejecting the !whole_file case, but if the entire call to
> > the hooks are skipped, it's okay).
> > 
> > What does this return on your test system:
> > 
> > 	echo $(cat /sys/kernel/security/lsm)
> ima kernel configs are enabled but I don't enable security policies
> on the kernel command line.
> 
> echo $(cat /sys/kernel/security/lsm)
> cat: /sys/kernel/security/lsm: No such file or directory

Oh, er... CONFIG_SECURITYFS is missing?

Can you send me your .config?

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-24 18:23         ` Kees Cook
@ 2020-07-24 18:39           ` Kees Cook
  2020-07-24 19:03             ` Scott Branden
  0 siblings, 1 reply; 38+ messages in thread
From: Kees Cook @ 2020-07-24 18:39 UTC (permalink / raw)
  To: Scott Branden
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Fri, Jul 24, 2020 at 11:23:37AM -0700, Kees Cook wrote:
> On Thu, Jul 23, 2020 at 10:41:07PM -0700, Scott Branden wrote:
> > 
> > 
> > On 2020-07-23 12:15 p.m., Kees Cook wrote:
> > > On Wed, Jul 22, 2020 at 03:29:26PM -0700, Scott Branden wrote:
> > > > These changes don't pass the kernel-selftest for partial reads I added
> > > > (which are at the end of this patch v2 series).
> > > Oh, interesting. Is there any feedback in dmesg? I wonder if I have the
> > > LSMs configured differently than you?
> > I have no LSMs configured that I know of.
> > Yes, there is failure in dmesg which is how I determined to add my
> > workaround.
> > Without workaround, dmesg log attached after booting and running
> > fw_run_tests.h
> > > > See change below added for temp workaround for issue.
> > > > > [...]
> > > > > +
> > > > > +	whole_file = (offset == 0 && i_size <= buf_size);
> > > > A hack to get this passing I added which probably breaks some security?
> > > > if (whole_file) {
> > > > > +	ret = security_kernel_read_file(file, id, whole_file);
> > > > > +	if (ret)
> > > > > +		goto out;
> > > > > +
> > > > }
> > > This would imply I did something wrong in the LSM hook refactoring (i.e.
> > > some LSM is rejecting the !whole_file case, but if the entire call to
> > > the hooks are skipped, it's okay).
> > > 
> > > What does this return on your test system:
> > > 
> > > 	echo $(cat /sys/kernel/security/lsm)
> > ima kernel configs are enabled but I don't enable security policies
> > on the kernel command line.
> > 
> > echo $(cat /sys/kernel/security/lsm)
> > cat: /sys/kernel/security/lsm: No such file or directory
> 
> Oh, er... CONFIG_SECURITYFS is missing?
> 
> Can you send me your .config?

Ah, nevermind, I found my config mistake. I thought I had the right
setting, but I'd missed CONFIG_IMA_APPRAISE=y. With that enabled, the
firmware tests _correctly_ fail, since IMA can't appraise partial reads.

So, this doesn't look like a bug to me.

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-24 18:39           ` Kees Cook
@ 2020-07-24 19:03             ` Scott Branden
  2020-07-24 19:26               ` Kees Cook
  0 siblings, 1 reply; 38+ messages in thread
From: Scott Branden @ 2020-07-24 19:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Aaron Goidel, Serge E. Hallyn,
	Wenwen Wang, selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel,
	Luis Chamberlain, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

Hi Kees,

On 2020-07-24 11:39 a.m., Kees Cook wrote:
> On Fri, Jul 24, 2020 at 11:23:37AM -0700, Kees Cook wrote:
>> On Thu, Jul 23, 2020 at 10:41:07PM -0700, Scott Branden wrote:
>>>
>>> On 2020-07-23 12:15 p.m., Kees Cook wrote:
>>>> On Wed, Jul 22, 2020 at 03:29:26PM -0700, Scott Branden wrote:
>>>>> These changes don't pass the kernel-selftest for partial reads I added
>>>>> (which are at the end of this patch v2 series).
>>>> Oh, interesting. Is there any feedback in dmesg? I wonder if I have the
>>>> LSMs configured differently than you?
>>> I have no LSMs configured that I know of.
>>> Yes, there is failure in dmesg which is how I determined to add my
>>> workaround.
>>> Without workaround, dmesg log attached after booting and running
>>> fw_run_tests.h
>>>>> See change below added for temp workaround for issue.
>>>>>> [...]
>>>>>> +
>>>>>> +	whole_file = (offset == 0 && i_size <= buf_size);
>>>>> A hack to get this passing I added which probably breaks some security?
>>>>> if (whole_file) {
>>>>>> +	ret = security_kernel_read_file(file, id, whole_file);
>>>>>> +	if (ret)
>>>>>> +		goto out;
>>>>>> +
>>>>> }
>>>> This would imply I did something wrong in the LSM hook refactoring (i.e.
>>>> some LSM is rejecting the !whole_file case, but if the entire call to
>>>> the hooks are skipped, it's okay).
>>>>
>>>> What does this return on your test system:
>>>>
>>>> 	echo $(cat /sys/kernel/security/lsm)
>>> ima kernel configs are enabled but I don't enable security policies
>>> on the kernel command line.
>>>
>>> echo $(cat /sys/kernel/security/lsm)
>>> cat: /sys/kernel/security/lsm: No such file or directory
>> Oh, er... CONFIG_SECURITYFS is missing?
>>
>> Can you send me your .config?
> Ah, nevermind, I found my config mistake. I thought I had the right
> setting, but I'd missed CONFIG_IMA_APPRAISE=y. With that enabled, the
> firmware tests _correctly_ fail, since IMA can't appraise partial reads.
>
> So, this doesn't look like a bug to me.
>
Now I'm confused.  The original patch series I made with IMA additions 
under Mimi's direction
passed the kernel selftests with partial read.  And 
request_partial_firmware_into_buf therefore worked.
Your changes don't work with CONFIG_IMA_APPRAISE=y on?  Is there a way 
to make IMA ignore this file to make things work then?
Seems like another change is needed for IMA to ignore partial reads if 
it can't appraise them?


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads
  2020-07-24 19:03             ` Scott Branden
@ 2020-07-24 19:26               ` Kees Cook
  0 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-07-24 19:26 UTC (permalink / raw)
  To: Scott Branden, Mimi Zohar
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Aaron Goidel, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, linux-security-module,
	Anders Roxell, Paul Moore, Mauro Carvalho Chehab,
	Michael Ellerman, Nayna Jain, Matthew Garrett, James Morris,
	Lakshmi Ramasubramanian, Serge E. Hallyn, Wenwen Wang, selinux,
	Jessica Yu, Hans de Goede, Alexander Viro, Matthieu Baerts,
	KP Singh, Eric Paris, linux-integrity, Florent Revest,
	Andrea Righi, Greg Kroah-Hartman, Stephen Smalley, Randy Dunlap,
	kexec, linux-kernel, Luis Chamberlain, Eric Biederman,
	Dave Olsthoorn, Dmitry Kasatkin, Casey Schaufler, Joe Perches,
	Andrew Morton, Thiago Jung Bauermann

On Fri, Jul 24, 2020 at 12:03:36PM -0700, Scott Branden wrote:
> Now I'm confused.  The original patch series I made with IMA additions under
> Mimi's direction
> passed the kernel selftests with partial read.  And
> request_partial_firmware_into_buf therefore worked.
> Your changes don't work with CONFIG_IMA_APPRAISE=y on?  Is there a way to
> make IMA ignore this file to make things work then?
> Seems like another change is needed for IMA to ignore partial reads if it
> can't appraise them?

Ah yes, I missed this in porting your series[1] (i.e. calling
process_measurement() with a valid "file" and NULL "buf" is handled
correctly -- I misunderstood these changes). I will send a corrected
patch.

-Kees

[1] https://lore.kernel.org/lkml/20200706232309.12010-10-scott.branden@broadcom.com/

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems
  2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
  2020-07-23 17:32   ` Scott Branden
@ 2020-07-29  0:48   ` Luis Chamberlain
  2020-09-09 22:18     ` Kees Cook
  1 sibling, 1 reply; 38+ messages in thread
From: Luis Chamberlain @ 2020-07-29  0:48 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, Anders Roxell,
	Paul Moore, Mauro Carvalho Chehab, Michael Ellerman, Nayna Jain,
	Matthew Garrett, James Morris, Lakshmi Ramasubramanian,
	Aaron Goidel, Serge E. Hallyn, Wenwen Wang, Scott Branden,
	selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	linux-security-module, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Wed, Jul 22, 2020 at 12:30:03PM -0700, Kees Cook wrote:
> On non-EFI systems, it wasn't possible to test the platform firmware
> loader because it will have never set "checked_fw" during __init.
> Instead, allow the test code to override this check. Additionally split
> the declarations into a private header file so it there is greater
> enforcement of the symbol visibility.
> 
> Fixes: 548193cba2a7 ("test_firmware: add support for firmware_request_platform")
> Cc: stable@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

A *clearly* private symbol namespace would seem cleaner, example the existing:

EXPORT_SYMBOL_NS_GPL(fw_fallback_config, FIRMWARE_LOADER_PRIVATE);

  Luis

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems
  2020-07-29  0:48   ` Luis Chamberlain
@ 2020-09-09 22:18     ` Kees Cook
  0 siblings, 0 replies; 38+ messages in thread
From: Kees Cook @ 2020-09-09 22:18 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: linux-efi, Rafael J. Wysocki, Peter Zijlstra, linux-fsdevel,
	Stephen Boyd, SeongJae Park, Mimi Zohar, David Howells,
	Tushar Sugandhi, Peter Jones, linux-kselftest,
	Joel Fernandes (Google),
	Shuah Khan, Ard Biesheuvel, Thomas Cedeno, Anders Roxell,
	Paul Moore, Mauro Carvalho Chehab, Michael Ellerman, Nayna Jain,
	Matthew Garrett, James Morris, Lakshmi Ramasubramanian,
	Aaron Goidel, Serge E. Hallyn, Wenwen Wang, Scott Branden,
	selinux, Jessica Yu, Hans de Goede, Alexander Viro,
	Matthieu Baerts, KP Singh, Eric Paris, linux-integrity,
	Florent Revest, Andrea Righi, Greg Kroah-Hartman,
	Stephen Smalley, Randy Dunlap, kexec, linux-kernel, stable,
	linux-security-module, Eric Biederman, Dave Olsthoorn,
	Dmitry Kasatkin, Casey Schaufler, Joe Perches, Andrew Morton,
	Thiago Jung Bauermann

On Wed, Jul 29, 2020 at 12:48:06AM +0000, Luis Chamberlain wrote:
> On Wed, Jul 22, 2020 at 12:30:03PM -0700, Kees Cook wrote:
> > On non-EFI systems, it wasn't possible to test the platform firmware
> > loader because it will have never set "checked_fw" during __init.
> > Instead, allow the test code to override this check. Additionally split
> > the declarations into a private header file so it there is greater
> > enforcement of the symbol visibility.
> > 
> > Fixes: 548193cba2a7 ("test_firmware: add support for firmware_request_platform")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> 
> A *clearly* private symbol namespace would seem cleaner, example the existing:
> 
> EXPORT_SYMBOL_NS_GPL(fw_fallback_config, FIRMWARE_LOADER_PRIVATE);

I'm respinning this now. It doesn't solve in-kernel visibility, but it
does solve module visibility, I guess. It's a simpler patch, and I think
gets the point across. Will send after build testing...

-- 
Kees Cook

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2020-09-09 22:19 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-22 19:30 [PATCH v2 00/18] Introduce partial kernel_read_file() support Kees Cook
2020-07-22 19:30 ` [PATCH v2 01/18] test_firmware: Test platform fw loading on non-EFI systems Kees Cook
2020-07-23 17:32   ` Scott Branden
2020-07-29  0:48   ` Luis Chamberlain
2020-09-09 22:18     ` Kees Cook
2020-07-22 19:30 ` [PATCH v2 02/18] selftest/firmware: Add selftest timeout in settings Kees Cook
2020-07-23  6:38   ` SeongJae Park
2020-07-23 17:34   ` Scott Branden
2020-07-22 19:30 ` [PATCH v2 03/18] firmware_loader: EFI firmware loader must handle pre-allocated buffer Kees Cook
2020-07-22 19:30 ` [PATCH v2 04/18] fs/kernel_read_file: Remove FIRMWARE_PREALLOC_BUFFER enum Kees Cook
2020-07-22 19:30 ` [PATCH v2 05/18] fs/kernel_read_file: Remove FIRMWARE_EFI_EMBEDDED enum Kees Cook
2020-07-22 19:30 ` [PATCH v2 06/18] fs/kernel_read_file: Split into separate include file Kees Cook
2020-07-22 19:30 ` [PATCH v2 07/18] fs/kernel_read_file: Split into separate source file Kees Cook
2020-07-22 19:30 ` [PATCH v2 08/18] fs/kernel_read_file: Remove redundant size argument Kees Cook
2020-07-23 17:35   ` Scott Branden
2020-07-22 19:30 ` [PATCH v2 09/18] fs/kernel_read_file: Switch buffer size arg to size_t Kees Cook
2020-07-23 17:36   ` Scott Branden
2020-07-22 19:30 ` [PATCH v2 10/18] fs/kernel_read_file: Add file_size output argument Kees Cook
2020-07-23 17:36   ` Scott Branden
2020-07-22 19:30 ` [PATCH v2 11/18] LSM: Introduce kernel_post_load_data() hook Kees Cook
2020-07-23 17:39   ` Scott Branden
2020-07-22 19:30 ` [PATCH v2 12/18] firmware_loader: Use security_post_load_data() Kees Cook
2020-07-22 19:30 ` [PATCH v2 13/18] module: Call security_kernel_post_load_data() Kees Cook
2020-07-22 19:30 ` [PATCH v2 14/18] LSM: Add "contents" flag to kernel_read_file hook Kees Cook
2020-07-22 19:30 ` [PATCH v2 15/18] fs/kernel_file_read: Add "offset" arg for partial reads Kees Cook
2020-07-22 22:29   ` Scott Branden
2020-07-23  6:23     ` Scott Branden
2020-07-23 19:17       ` Kees Cook
2020-07-24  5:46         ` Scott Branden
2020-07-23 19:15     ` Kees Cook
2020-07-24  5:41       ` Scott Branden
2020-07-24 18:23         ` Kees Cook
2020-07-24 18:39           ` Kees Cook
2020-07-24 19:03             ` Scott Branden
2020-07-24 19:26               ` Kees Cook
2020-07-22 19:30 ` [PATCH v2 16/18] firmware: Store opt_flags in fw_priv Kees Cook
2020-07-22 19:30 ` [PATCH v2 17/18] firmware: Add request_partial_firmware_into_buf() Kees Cook
2020-07-22 19:30 ` [PATCH v2 18/18] test_firmware: Test partial read support Kees Cook

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.