Skip to content

Commit

Permalink
integrity: prevent deadlock during digsig verification.
Browse files Browse the repository at this point in the history
This patch aimed to prevent deadlock during digsig verification.The point
of issue - user space utility modprobe and/or it's dependencies (ld-*.so,
libz.so.*, libc-*.so and /lib/modules/ files) that could be used for
kernel modules load during digsig verification and could be signed by
digsig in the same time.

First at all, look at crypto_alloc_tfm() work algorithm:
crypto_alloc_tfm() will first attempt to locate an already loaded
algorithm. If that fails and the kernel supports dynamically loadable
modules, it will then attempt to load a module of the same name or alias.
If that fails it will send a query to any loaded crypto manager to
construct an algorithm on the fly.

We have situation, when public_key_verify_signature() in case of RSA
algorithm use alg_name to store internal information in order to construct
an algorithm on the fly, but crypto_larval_lookup() will try to use
alg_name in order to load kernel module with same name.

1) we can't do anything with crypto module work, since it designed to work
exactly in this way;
2) we can't globally filter module requests for modprobe, since it
designed to work with any requests.

In this patch, I propose add an exception for "crypto-pkcs1pad(rsa,*)"
module requests only in case of enabled integrity asymmetric keys support.
Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules for
sure, we are safe to fail such module request from crypto_larval_lookup().
In this way we prevent modprobe execution during digsig verification and
avoid possible deadlock if modprobe and/or it's dependencies also signed
with digsig.

Requested "crypto-pkcs1pad(rsa,*)" kernel module name formed by:
1) "pkcs1pad(rsa,%s)" in public_key_verify_signature();
2) "crypto-%s" / "crypto-%s-all" in crypto_larval_lookup().
"crypto-pkcs1pad(rsa," part of request is a constant and unique and could
be used as filter.

Signed-off-by: Mikhail Kurinnoi <viewizard@viewizard.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

 include/linux/integrity.h              | 13 +++++++++++++
 security/integrity/digsig_asymmetric.c | 23 +++++++++++++++++++++++
 security/security.c                    |  7 ++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)
  • Loading branch information
Mikhail Kurinnoi authored and Mimi Zohar committed Jul 18, 2018
1 parent 5feeb61 commit 6eb864c
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
13 changes: 13 additions & 0 deletions include/linux/integrity.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,17 @@ static inline void integrity_load_keys(void)
}
#endif /* CONFIG_INTEGRITY */

#ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS

extern int integrity_kernel_module_request(char *kmod_name);

#else

static inline int integrity_kernel_module_request(char *kmod_name)
{
return 0;
}

#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */

#endif /* _LINUX_INTEGRITY_H */
23 changes: 23 additions & 0 deletions security/integrity/digsig_asymmetric.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,26 @@ int asymmetric_verify(struct key *keyring, const char *sig,
pr_debug("%s() = %d\n", __func__, ret);
return ret;
}

/**
* integrity_kernel_module_request - prevent crypto-pkcs1pad(rsa,*) requests
* @kmod_name: kernel module name
*
* We have situation, when public_key_verify_signature() in case of RSA
* algorithm use alg_name to store internal information in order to
* construct an algorithm on the fly, but crypto_larval_lookup() will try
* to use alg_name in order to load kernel module with same name.
* Since we don't have any real "crypto-pkcs1pad(rsa,*)" kernel modules,
* we are safe to fail such module request from crypto_larval_lookup().
*
* In this way we prevent modprobe execution during digsig verification
* and avoid possible deadlock if modprobe and/or it's dependencies
* also signed with digsig.
*/
int integrity_kernel_module_request(char *kmod_name)
{
if (strncmp(kmod_name, "crypto-pkcs1pad(rsa,", 20) == 0)
return -EINVAL;

return 0;
}
7 changes: 6 additions & 1 deletion security/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,12 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)

int security_kernel_module_request(char *kmod_name)
{
return call_int_hook(kernel_module_request, 0, kmod_name);
int ret;

ret = call_int_hook(kernel_module_request, 0, kmod_name);
if (ret)
return ret;
return integrity_kernel_module_request(kmod_name);
}

int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
Expand Down

0 comments on commit 6eb864c

Please sign in to comment.