diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index d00780648a9b..8bf016c14af1 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -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 diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig index d1b563def73b..6a4a3e6fc516 100644 --- a/arch/arm64/configs/rockpi4_defconfig +++ b/arch/arm64/configs/rockpi4_defconfig @@ -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 diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index b54d3a86c444..743a1d30bae2 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -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) diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S index 62f0260f5c17..806059c7a7c5 100644 --- a/arch/arm64/kernel/efi-rt-wrapper.S +++ b/arch/arm64/kernel/efi-rt-wrapper.S @@ -4,6 +4,7 @@ */ #include +#include 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) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 14b7352bc05e..ba5358f52e58 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -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); diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 569af6740408..bb30c0d8816c 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -240,7 +240,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 diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 77fdbcc8c1b2..917b61931d07 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -32,6 +32,7 @@ #include #include #include +#include #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, diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c index 4555d678fadd..abcee58e851c 100644 --- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ struct mbox_test_device { char *signal; char *message; spinlock_t lock; + struct mutex mutex; wait_queue_head_t waitq; struct fasync_struct *async_queue; struct dentry *root_debugfs_dir; @@ -95,6 +97,7 @@ static ssize_t mbox_test_message_write(struct file *filp, size_t count, loff_t *ppos) { struct mbox_test_device *tdev = filp->private_data; + char *message; void *data; int ret; @@ -110,10 +113,13 @@ static ssize_t mbox_test_message_write(struct file *filp, return -EINVAL; } - tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); - if (!tdev->message) + message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); + if (!message) return -ENOMEM; + mutex_lock(&tdev->mutex); + + tdev->message = message; ret = copy_from_user(tdev->message, userbuf, count); if (ret) { ret = -EFAULT; @@ -144,6 +150,8 @@ out: kfree(tdev->message); tdev->signal = NULL; + mutex_unlock(&tdev->mutex); + return ret < 0 ? ret : count; } @@ -392,6 +400,7 @@ static int mbox_test_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tdev); spin_lock_init(&tdev->lock); + mutex_init(&tdev->mutex); if (tdev->rx_channel) { tdev->rx_buffer = devm_kzalloc(&pdev->dev, diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 8fb82a5b8f5b..3d86c111e7cf 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -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 diff --git a/drivers/md/Makefile b/drivers/md/Makefile index bfc808c9e393..329f1826d9ae 100644 --- a/drivers/md/Makefile +++ b/drivers/md/Makefile @@ -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 diff --git a/drivers/md/dm-verity-avb.c b/drivers/md/dm-verity-avb.c deleted file mode 100644 index a9f102aa379e..000000000000 --- a/drivers/md/dm-verity-avb.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2017 Google. - * - * This file is released under the GPLv2. - * - * Based on drivers/md/dm-verity-chromeos.c - */ - -#include -#include -#include - -#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<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 "); -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); diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 6f92514214bf..8327c169cf37 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -273,12 +273,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; } diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h index adbd64fde481..641b9e3a399b 100644 --- a/drivers/md/dm-verity.h +++ b/drivers/md/dm-verity.h @@ -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 */ diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index eaa2a94d18be..dd06c18495eb 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -828,7 +828,7 @@ static void r592_remove(struct pci_dev *pdev) /* Stop the processing thread. That ensures that we won't take any more requests */ kthread_stop(dev->io_thread); - + del_timer_sync(&dev->detect_timer); r592_enable_device(dev, false); while (!error && dev->req) { diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index a33149ee0ddc..0a5b5ff597c6 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c @@ -437,6 +437,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) goto err; } skb_dst_set(skb, &rt->dst); + + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); + err = ip_local_out(net, skb->sk, skb); if (unlikely(net_xmit_eval(err))) dev->stats.tx_errors++; @@ -475,6 +478,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) goto err; } skb_dst_set(skb, dst); + + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + err = ip6_local_out(net, skb->sk, skb); if (unlikely(net_xmit_eval(err))) dev->stats.tx_errors++; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index ba68b0b41dff..2f7fa6c5f2a8 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -4102,8 +4102,12 @@ int prepare_to_relocate(struct reloc_control *rc) */ return PTR_ERR(trans); } - btrfs_commit_transaction(trans); - return 0; + + ret = btrfs_commit_transaction(trans); + if (ret) + unset_reloc_control(rc); + + return ret; } static noinline_for_stack int relocate_block_group(struct reloc_control *rc) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index a5205dc95e8f..4f8f5204ae7a 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -989,7 +989,14 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, if (hci_sock_gen_cookie(sk)) { struct sk_buff *skb; - if (capable(CAP_NET_ADMIN)) + /* Perform careful checks before setting the HCI_SOCK_TRUSTED + * flag. Make sure that not only the current task but also + * the socket opener has the required capability, since + * privileged programs can be tricked into making ioctl calls + * on HCI sockets, and the socket should not be marked as + * trusted simply because the ioctl caller is privileged. + */ + if (sk_capable(sk, CAP_NET_ADMIN)) hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); /* Send event to monitor */ diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index ed8d26e6468c..e5cc2b4d38d5 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -716,12 +716,18 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, struct nlattr *est, bool ovr, struct netlink_ext_ack *extack) { - int err; + int err, ifindex = -1; err = tcf_exts_validate(net, tp, tb, est, &n->exts, ovr, true, extack); if (err < 0) return err; + if (tb[TCA_U32_INDEV]) { + ifindex = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); + if (ifindex < 0) + return -EINVAL; + } + if (tb[TCA_U32_LINK]) { u32 handle = nla_get_u32(tb[TCA_U32_LINK]); struct tc_u_hnode *ht_down = NULL, *ht_old; @@ -756,13 +762,9 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, tcf_bind_filter(tp, &n->res, base); } - if (tb[TCA_U32_INDEV]) { - int ret; - ret = tcf_change_indev(net, tb[TCA_U32_INDEV], extack); - if (ret < 0) - return -EINVAL; - n->ifindex = ret; - } + if (ifindex >= 0) + n->ifindex = ifindex; + return 0; }