@@ -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;
@@ -25,6 +25,11 @@ int firmware_fallback_platform(struct fw_priv *fw_priv, u32 opt_flags)
if (rc)
return rc; /* rc == -ENOENT when the fw was not found */
+ rc = security_kernel_post_read_file(NULL, (char *)data, size,
+ READING_FIRMWARE);
+ if (rc)
+ return rc;
+
if (fw_priv->data && size > fw_priv->allocated_size)
return -ENOMEM;
if (!fw_priv->data)
@@ -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) \
@@ -633,15 +633,19 @@
* @kmod_name name of the module requested by the kernel
* Return 0 if successful.
* @kernel_load_data:
- * Load data provided by userspace.
+ * Load data provided by a non-file source (usually userspace buffer).
* @id kernel load data identifier
* Return 0 if permission is granted.
+ * This may be paired with a kernel_post_read_file() with a NULL
+ * @file, but contains the actual data loaded.
* @kernel_read_file:
* Read a file specified by userspace.
* @file contains the file structure pointing to the file being read
* by the kernel.
* @id kernel read file identifier
* Return 0 if permission is granted.
+ * This must be paired with a kernel_post_read_file(), which contains
+ * the actual data read from @file.
* @kernel_post_read_file:
* Read a file specified by userspace.
* @file contains the file structure pointing to the file being read
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. Add call to security_kernel_post_read_file() so the contents can be measured/verified, just as the firmware sysfs fallback does. This would allow for IMA (or other LSMs) to validate known-good EFI firmware images. Fixes: e4c2c0ff00ec ("firmware: Add new platform fallback mechanism and firmware_request_platform()") Signed-off-by: Kees Cook <keescook@chromium.org> --- drivers/base/firmware_loader/fallback_platform.c | 7 ++++++- include/linux/fs.h | 3 +-- include/linux/lsm_hooks.h | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-)