Merge branch 'android11-5.4' into android11-5.4-lts
Sync up with android11-5.4 for the following commits:f95ca5bb23UPSTREAM: ipvlan:Fix out-of-bounds caused by unclear skb->cb6e030b7606UPSTREAM: net/sched: cls_u32: Fix reference counter leak leading to overflow9de197d0e5UPSTREAM: memstick: r592: Fix UAF bug in r592_remove due to race conditionbf85112393BACKPORT: btrfs: unset reloc control if transaction commit fails in prepare_to_relocate()6165e57aa0ANDROID: HID: Only utilise UHID provided exports if UHID is enabled60c1a0beb5UPSTREAM: bluetooth: Perform careful capability checks in hci_sock_ioctl()e699d543bbANDROID: HID; Over-ride default maximum buffer size when using UHID8047bf5f22Revert "ANDROID: AVB error handler to invalidate vbmeta partition."6841a56b34UPSTREAM: mailbox: mailbox-test: fix a locking issue in mbox_test_message_write()229c9edd62UPSTREAM: mailbox: mailbox-test: Fix potential double-free in mbox_test_message_write()431c9e5d6dUPSTREAM: efi: rt-wrapper: Add missing include0c867c1589BACKPORT: arm64: efi: Execute runtime services from a dedicated stackbffea4e72dUPSTREAM: io_uring: have io_kill_timeout() honor the request references87ed28db7dUPSTREAM: io_uring: don't drop completion lock before timer is fully initializedce6a504d69UPSTREAM: io_uring: always grab lock in io_cancel_async_work()d4fabc5cbbUPSTREAM: net: cdc_ncm: Deal with too low values of dwNtbOutMaxSizea9515e06cbUPSTREAM: cdc_ncm: Fix the build warninge8448852f1UPSTREAM: cdc_ncm: Implement the 32-bit version of NCM Transfer Block25dcbf92d4Merge "Merge tag 'android11-5.4.242_r00' into android11-5.4" into android11-5.4 Change-Id: I7042914bcf95863ba444f5f395faac36dedd6af4 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
874e208e9b
12 changed files with 58 additions and 261 deletions
|
|
@ -266,7 +266,6 @@ CONFIG_DM_DEFAULT_KEY=y
|
|||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_AVB=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
|
|
|
|||
|
|
@ -217,7 +217,6 @@ CONFIG_BLK_DEV_DM=y
|
|||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_AVB=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
|
|||
({ \
|
||||
efi_virtmap_load(); \
|
||||
__efi_fpsimd_begin(); \
|
||||
spin_lock(&efi_rt_lock); \
|
||||
})
|
||||
|
||||
#define arch_efi_call_virt(p, f, args...) \
|
||||
|
|
@ -36,10 +37,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
|
|||
|
||||
#define arch_efi_call_virt_teardown() \
|
||||
({ \
|
||||
spin_unlock(&efi_rt_lock); \
|
||||
__efi_fpsimd_end(); \
|
||||
efi_virtmap_unload(); \
|
||||
})
|
||||
|
||||
extern spinlock_t efi_rt_lock;
|
||||
efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
|
||||
|
||||
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
ENTRY(__efi_rt_asm_wrapper)
|
||||
stp x29, x30, [sp, #-32]!
|
||||
|
|
@ -16,6 +17,12 @@ ENTRY(__efi_rt_asm_wrapper)
|
|||
*/
|
||||
stp x1, x18, [sp, #16]
|
||||
|
||||
ldr_l x16, efi_rt_stack_top
|
||||
mov sp, x16
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
str x18, [sp, #-16]!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are lucky enough that no EFI runtime services take more than
|
||||
* 5 arguments, so all are passed in registers rather than via the
|
||||
|
|
@ -29,19 +36,22 @@ ENTRY(__efi_rt_asm_wrapper)
|
|||
mov x4, x6
|
||||
blr x8
|
||||
|
||||
mov sp, x29
|
||||
ldp x1, x2, [sp, #16]
|
||||
cmp x2, x18
|
||||
ldp x29, x30, [sp], #32
|
||||
b.ne 0f
|
||||
ret
|
||||
0:
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
/*
|
||||
* Restore x18 before returning to instrumented code. This is
|
||||
* safe because the wrapper is called with preemption disabled and
|
||||
* a separate shadow stack is used for interrupts.
|
||||
*/
|
||||
mov x18, x2
|
||||
#ifdef CONFIG_SHADOW_CALL_STACK
|
||||
ldr_l x18, efi_rt_stack_top
|
||||
ldr x18, [x18, #-16]
|
||||
#endif
|
||||
|
||||
b efi_handle_corrupted_x18 // tail call
|
||||
ENDPROC(__efi_rt_asm_wrapper)
|
||||
|
|
|
|||
|
|
@ -143,3 +143,31 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
|
|||
pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f);
|
||||
return s;
|
||||
}
|
||||
|
||||
DEFINE_SPINLOCK(efi_rt_lock);
|
||||
|
||||
asmlinkage u64 *efi_rt_stack_top __ro_after_init;
|
||||
|
||||
/* EFI requires 8 KiB of stack space for runtime services */
|
||||
static_assert(THREAD_SIZE >= SZ_8K);
|
||||
|
||||
static int __init arm64_efi_rt_init(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
return 0;
|
||||
|
||||
p = __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, VMALLOC_START,
|
||||
VMALLOC_END, GFP_KERNEL, PAGE_KERNEL, 0,
|
||||
NUMA_NO_NODE, &&l);
|
||||
l: if (!p) {
|
||||
pr_warn("Failed to allocate EFI runtime stack\n");
|
||||
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
efi_rt_stack_top = p + THREAD_SIZE;
|
||||
return 0;
|
||||
}
|
||||
core_initcall(arm64_efi_rt_init);
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ CONFIG_DM_DEFAULT_KEY=y
|
|||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_AVB=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <linux/hiddev.h>
|
||||
#include <linux/hid-debug.h>
|
||||
#include <linux/hidraw.h>
|
||||
#include <linux/uhid.h>
|
||||
|
||||
#include "hid-ids.h"
|
||||
|
||||
|
|
@ -258,6 +259,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
|
|||
{
|
||||
struct hid_report *report;
|
||||
struct hid_field *field;
|
||||
unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
unsigned int usages;
|
||||
unsigned int offset;
|
||||
unsigned int i;
|
||||
|
|
@ -288,8 +290,11 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
|
|||
offset = report->size;
|
||||
report->size += parser->global.report_size * parser->global.report_count;
|
||||
|
||||
if (IS_ENABLED(CONFIG_UHID) && parser->device->ll_driver == &uhid_hid_driver)
|
||||
max_buffer_size = UHID_DATA_MAX;
|
||||
|
||||
/* Total size check: Allow for possible report index byte */
|
||||
if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) {
|
||||
if (report->size > (max_buffer_size - 1) << 3) {
|
||||
hid_err(parser->device, "report is too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1745,6 +1750,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
|
|||
struct hid_report_enum *report_enum = hid->report_enum + type;
|
||||
struct hid_report *report;
|
||||
struct hid_driver *hdrv;
|
||||
int max_buffer_size = HID_MAX_BUFFER_SIZE;
|
||||
unsigned int a;
|
||||
u32 rsize, csize = size;
|
||||
u8 *cdata = data;
|
||||
|
|
@ -1761,10 +1767,13 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
|
|||
|
||||
rsize = hid_compute_report_size(report);
|
||||
|
||||
if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)
|
||||
rsize = HID_MAX_BUFFER_SIZE - 1;
|
||||
else if (rsize > HID_MAX_BUFFER_SIZE)
|
||||
rsize = HID_MAX_BUFFER_SIZE;
|
||||
if (IS_ENABLED(CONFIG_UHID) && hid->ll_driver == &uhid_hid_driver)
|
||||
max_buffer_size = UHID_DATA_MAX;
|
||||
|
||||
if (report_enum->numbered && rsize >= max_buffer_size)
|
||||
rsize = max_buffer_size - 1;
|
||||
else if (rsize > max_buffer_size)
|
||||
rsize = max_buffer_size;
|
||||
|
||||
if (csize < rsize) {
|
||||
dbg_hid("report %d is too short, (%d < %d)\n", report->id,
|
||||
|
|
|
|||
|
|
@ -538,17 +538,6 @@ config DM_VERITY_VERIFY_ROOTHASH_SIG
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_VERITY_AVB
|
||||
tristate "Support AVB specific verity error behavior"
|
||||
depends on DM_VERITY
|
||||
---help---
|
||||
Enables Android Verified Boot platform-specific error
|
||||
behavior. In particular, it will modify the vbmeta partition
|
||||
specified on the kernel command-line when non-transient error
|
||||
occurs (followed by a panic).
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config DM_VERITY_FEC
|
||||
bool "Verity forward error correction support"
|
||||
depends on DM_VERITY
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ ifeq ($(CONFIG_DM_UEVENT),y)
|
|||
dm-mod-objs += dm-uevent.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DM_VERITY_AVB),y)
|
||||
dm-verity-objs += dm-verity-avb.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DM_VERITY_FEC),y)
|
||||
dm-verity-objs += dm-verity-fec.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,229 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Google.
|
||||
*
|
||||
* This file is released under the GPLv2.
|
||||
*
|
||||
* Based on drivers/md/dm-verity-chromeos.c
|
||||
*/
|
||||
|
||||
#include <linux/device-mapper.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
#define DM_MSG_PREFIX "verity-avb"
|
||||
|
||||
/* Set via module parameters. */
|
||||
static char avb_vbmeta_device[64];
|
||||
static char avb_invalidate_on_error[4];
|
||||
|
||||
static void invalidate_vbmeta_endio(struct bio *bio)
|
||||
{
|
||||
if (bio->bi_status)
|
||||
DMERR("invalidate_vbmeta_endio: error %d", bio->bi_status);
|
||||
complete(bio->bi_private);
|
||||
}
|
||||
|
||||
static int invalidate_vbmeta_submit(struct bio *bio,
|
||||
struct block_device *bdev,
|
||||
int op, int access_last_sector,
|
||||
struct page *page)
|
||||
{
|
||||
DECLARE_COMPLETION_ONSTACK(wait);
|
||||
|
||||
bio->bi_private = &wait;
|
||||
bio->bi_end_io = invalidate_vbmeta_endio;
|
||||
bio_set_dev(bio, bdev);
|
||||
bio_set_op_attrs(bio, op, REQ_SYNC);
|
||||
|
||||
bio->bi_iter.bi_sector = 0;
|
||||
if (access_last_sector) {
|
||||
sector_t last_sector;
|
||||
|
||||
last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1;
|
||||
bio->bi_iter.bi_sector = last_sector;
|
||||
}
|
||||
if (!bio_add_page(bio, page, PAGE_SIZE, 0)) {
|
||||
DMERR("invalidate_vbmeta_submit: bio_add_page error");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
submit_bio(bio);
|
||||
/* Wait up to 2 seconds for completion or fail. */
|
||||
if (!wait_for_completion_timeout(&wait, msecs_to_jiffies(2000)))
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int invalidate_vbmeta(dev_t vbmeta_devt)
|
||||
{
|
||||
int ret = 0;
|
||||
struct block_device *bdev;
|
||||
struct bio *bio;
|
||||
struct page *page;
|
||||
fmode_t dev_mode;
|
||||
/* Ensure we do synchronous unblocked I/O. We may also need
|
||||
* sync_bdev() on completion, but it really shouldn't.
|
||||
*/
|
||||
int access_last_sector = 0;
|
||||
|
||||
DMINFO("invalidate_vbmeta: acting on device %d:%d",
|
||||
MAJOR(vbmeta_devt), MINOR(vbmeta_devt));
|
||||
|
||||
/* First we open the device for reading. */
|
||||
dev_mode = FMODE_READ | FMODE_EXCL;
|
||||
bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode,
|
||||
invalidate_vbmeta);
|
||||
if (IS_ERR(bdev)) {
|
||||
DMERR("invalidate_kernel: could not open device for reading");
|
||||
dev_mode = 0;
|
||||
ret = -ENOENT;
|
||||
goto failed_to_read;
|
||||
}
|
||||
|
||||
bio = bio_alloc(GFP_NOIO, 1);
|
||||
if (!bio) {
|
||||
ret = -ENOMEM;
|
||||
goto failed_bio_alloc;
|
||||
}
|
||||
|
||||
page = alloc_page(GFP_NOIO);
|
||||
if (!page) {
|
||||
ret = -ENOMEM;
|
||||
goto failed_to_alloc_page;
|
||||
}
|
||||
|
||||
access_last_sector = 0;
|
||||
ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_READ,
|
||||
access_last_sector, page);
|
||||
if (ret) {
|
||||
DMERR("invalidate_vbmeta: error reading");
|
||||
goto failed_to_submit_read;
|
||||
}
|
||||
|
||||
/* We have a page. Let's make sure it looks right. */
|
||||
if (memcmp("AVB0", page_address(page), 4) == 0) {
|
||||
/* Stamp it. */
|
||||
memcpy(page_address(page), "AVE0", 4);
|
||||
DMINFO("invalidate_vbmeta: found vbmeta partition");
|
||||
} else {
|
||||
/* Could be this is on a AVB footer, check. Also, since the
|
||||
* AVB footer is in the last 64 bytes, adjust for the fact that
|
||||
* we're dealing with 512-byte sectors.
|
||||
*/
|
||||
size_t offset = (1<<SECTOR_SHIFT) - 64;
|
||||
|
||||
access_last_sector = 1;
|
||||
ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_READ,
|
||||
access_last_sector, page);
|
||||
if (ret) {
|
||||
DMERR("invalidate_vbmeta: error reading");
|
||||
goto failed_to_submit_read;
|
||||
}
|
||||
if (memcmp("AVBf", page_address(page) + offset, 4) != 0) {
|
||||
DMERR("invalidate_vbmeta on non-vbmeta partition");
|
||||
ret = -EINVAL;
|
||||
goto invalid_header;
|
||||
}
|
||||
/* Stamp it. */
|
||||
memcpy(page_address(page) + offset, "AVE0", 4);
|
||||
DMINFO("invalidate_vbmeta: found vbmeta footer partition");
|
||||
}
|
||||
|
||||
/* Now rewrite the changed page - the block dev was being
|
||||
* changed on read. Let's reopen here.
|
||||
*/
|
||||
blkdev_put(bdev, dev_mode);
|
||||
dev_mode = FMODE_WRITE | FMODE_EXCL;
|
||||
bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode,
|
||||
invalidate_vbmeta);
|
||||
if (IS_ERR(bdev)) {
|
||||
DMERR("invalidate_vbmeta: could not open device for writing");
|
||||
dev_mode = 0;
|
||||
ret = -ENOENT;
|
||||
goto failed_to_write;
|
||||
}
|
||||
|
||||
/* We re-use the same bio to do the write after the read. Need to reset
|
||||
* it to initialize bio->bi_remaining.
|
||||
*/
|
||||
bio_reset(bio);
|
||||
|
||||
ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_WRITE,
|
||||
access_last_sector, page);
|
||||
if (ret) {
|
||||
DMERR("invalidate_vbmeta: error writing");
|
||||
goto failed_to_submit_write;
|
||||
}
|
||||
|
||||
DMERR("invalidate_vbmeta: completed.");
|
||||
ret = 0;
|
||||
failed_to_submit_write:
|
||||
failed_to_write:
|
||||
invalid_header:
|
||||
__free_page(page);
|
||||
failed_to_submit_read:
|
||||
/* Technically, we'll leak a page with the pending bio, but
|
||||
* we're about to reboot anyway.
|
||||
*/
|
||||
failed_to_alloc_page:
|
||||
bio_put(bio);
|
||||
failed_bio_alloc:
|
||||
if (dev_mode)
|
||||
blkdev_put(bdev, dev_mode);
|
||||
failed_to_read:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dm_verity_avb_error_handler(void)
|
||||
{
|
||||
dev_t dev;
|
||||
|
||||
DMINFO("AVB error handler called for %s", avb_vbmeta_device);
|
||||
|
||||
if (strcmp(avb_invalidate_on_error, "yes") != 0) {
|
||||
DMINFO("Not configured to invalidate");
|
||||
return;
|
||||
}
|
||||
|
||||
if (avb_vbmeta_device[0] == '\0') {
|
||||
DMERR("avb_vbmeta_device parameter not set");
|
||||
goto fail_no_dev;
|
||||
}
|
||||
|
||||
dev = name_to_dev_t(avb_vbmeta_device);
|
||||
if (!dev) {
|
||||
DMERR("No matching partition for device: %s",
|
||||
avb_vbmeta_device);
|
||||
goto fail_no_dev;
|
||||
}
|
||||
|
||||
invalidate_vbmeta(dev);
|
||||
|
||||
fail_no_dev:
|
||||
;
|
||||
}
|
||||
|
||||
static int __init dm_verity_avb_init(void)
|
||||
{
|
||||
DMINFO("AVB error handler initialized with vbmeta device: %s",
|
||||
avb_vbmeta_device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit dm_verity_avb_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(dm_verity_avb_init);
|
||||
module_exit(dm_verity_avb_exit);
|
||||
|
||||
MODULE_AUTHOR("David Zeuthen <zeuthen@google.com>");
|
||||
MODULE_DESCRIPTION("AVB-specific error handler for dm-verity");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Declare parameter with no module prefix */
|
||||
#undef MODULE_PARAM_PREFIX
|
||||
#define MODULE_PARAM_PREFIX "androidboot.vbmeta."
|
||||
module_param_string(device, avb_vbmeta_device, sizeof(avb_vbmeta_device), 0);
|
||||
module_param_string(invalidate_on_error, avb_invalidate_on_error,
|
||||
sizeof(avb_invalidate_on_error), 0);
|
||||
|
|
@ -251,12 +251,8 @@ out:
|
|||
if (v->mode == DM_VERITY_MODE_LOGGING)
|
||||
return 0;
|
||||
|
||||
if (v->mode == DM_VERITY_MODE_RESTART) {
|
||||
#ifdef CONFIG_DM_VERITY_AVB
|
||||
dm_verity_avb_error_handler();
|
||||
#endif
|
||||
if (v->mode == DM_VERITY_MODE_RESTART)
|
||||
kernel_restart("dm-verity device corrupted");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,6 +128,4 @@ extern int verity_hash(struct dm_verity *v, struct ahash_request *req,
|
|||
extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
|
||||
sector_t block, u8 *digest, bool *is_zero);
|
||||
|
||||
extern void dm_verity_avb_error_handler(void);
|
||||
|
||||
#endif /* DM_VERITY_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue