efi/capsule-loader: Add write mutex to prevent uaf
PATCH 1/1 efi/capsule-loader: Add write mutex to prevent uaf
If the user calls close() in the middle of copy operation in copy_from_user() of efi_capsule_write(),
the user buffer may be copied to the released page.
This is because ->flush is called unconditionally regardless of f_count, unlike ->release.
This driver is not a security vulnerability, as only root privileges can write to it.
However, it seems to be a good idea to add mutexes to efi_capsule_write() and efi_capsule_flush() as root can accidentally break the page while in use.
Signed-off-by Hyunwoo Kim <[email protected]>
--- drivers/firmware/efi/capsule-loader.c | 12 ++++++++++++ include/linux/efi.h | 1 + 2 files changed, 13 insertions(+)
drivers/firmware/efi/capsule-loader.c +12 -0
@@ -177,6 +177,8 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff,if (count ==0 )return 0 ; +mutex_lock (&cap_info->write_lock); +/* Return error while NO_FURTHER_WRITE_ACTION is flagged */ if (cap_info->index <0 )return -EIO ;
@@ -233,12 +235,16 @@ static ssize_t efi_capsule_write(struct file *file, const char __user *buff, goto failed; } +mutex_unlock (&cap_info->write_lock); +return write_byte; fail_unmap:kunmap (page); failed:efi_free_all_buff_pages (cap_info); +mutex_unlock (&cap_info->write_lock); +return ret; }
@@ -256,12 +262,16 @@ static int efi_capsule_flush(struct file *file, fl_owner_t id)int ret =0 ;struct capsule_info *cap_info = file->private_data; +mutex_lock (&cap_info->write_lock); +if (cap_info->index >0 ) {pr_err ("capsule upload not complete\n" );efi_free_all_buff_pages (cap_info); ret = -ECANCELED ; } +mutex_unlock (&cap_info->write_lock); +return ret; }
@@ -315,6 +325,8 @@ static int efi_capsule_open(struct inode *inode, struct file *file)return -ENOMEM ; } +mutex_init (&cap_info->write_lock); + file->private_data = cap_info;return 0 ;
include/linux/efi.h +1 -0
@@ -204,6 +204,7 @@ struct efi_image_auth {struct capsule_info {efi_capsule_header_t header;efi_capsule_header_t *capsule; +struct mutex write_mutex;int reset_type;long index;size_t count;
Signature · 1 line
2.25.1