crypto: ccp - Fix the INIT_EX data file open failure
There are 2 common cases when INIT_EX data file might not be
opened successfully and fail the sev initialization:
1. In user namespaces, normal user tasks (e.g. VMM) can change their
current->fs->root to point to arbitrary directories. While
init_ex_path is provided as a module param related to root file
system. Solution: use the root directory of init_task to avoid
accessing the wrong file.
2. Normal user tasks (e.g. VMM) don't have the privilege to access
the INIT_EX data file. Solution: open the file as root and
restore permissions immediately.
Fixes: 3d725965f8
("crypto: ccp - Add SEV_INIT_EX support")
Signed-off-by: Jacky Li <jackyli@google.com>
Reviewed-by: Peter Gonda <pgonda@google.com>
Acked-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
c6d3ffae0d
commit
05def5cacf
|
@ -23,6 +23,7 @@
|
|||
#include <linux/gfp.h>
|
||||
#include <linux/cpufeature.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
||||
#include <asm/smp.h>
|
||||
|
||||
|
@ -170,6 +171,31 @@ static void *sev_fw_alloc(unsigned long len)
|
|||
return page_address(page);
|
||||
}
|
||||
|
||||
static struct file *open_file_as_root(const char *filename, int flags, umode_t mode)
|
||||
{
|
||||
struct file *fp;
|
||||
struct path root;
|
||||
struct cred *cred;
|
||||
const struct cred *old_cred;
|
||||
|
||||
task_lock(&init_task);
|
||||
get_fs_root(init_task.fs, &root);
|
||||
task_unlock(&init_task);
|
||||
|
||||
cred = prepare_creds();
|
||||
if (!cred)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
cred->fsuid = GLOBAL_ROOT_UID;
|
||||
old_cred = override_creds(cred);
|
||||
|
||||
fp = file_open_root(&root, filename, flags, mode);
|
||||
path_put(&root);
|
||||
|
||||
revert_creds(old_cred);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static int sev_read_init_ex_file(void)
|
||||
{
|
||||
struct sev_device *sev = psp_master->sev_data;
|
||||
|
@ -181,7 +207,7 @@ static int sev_read_init_ex_file(void)
|
|||
if (!sev_init_ex_buffer)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
fp = filp_open(init_ex_path, O_RDONLY, 0);
|
||||
fp = open_file_as_root(init_ex_path, O_RDONLY, 0);
|
||||
if (IS_ERR(fp)) {
|
||||
int ret = PTR_ERR(fp);
|
||||
|
||||
|
@ -217,7 +243,7 @@ static void sev_write_init_ex_file(void)
|
|||
if (!sev_init_ex_buffer)
|
||||
return;
|
||||
|
||||
fp = filp_open(init_ex_path, O_CREAT | O_WRONLY, 0600);
|
||||
fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600);
|
||||
if (IS_ERR(fp)) {
|
||||
dev_err(sev->dev,
|
||||
"SEV: could not open file for write, error %ld\n",
|
||||
|
|
Loading…
Reference in New Issue