Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'bounds-fixes-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull bounds fixes from Kees Cook:
"These are a handful of buffer and array bounds fixes that I've been
carrying in preparation for the coming memcpy improvements and the
enabling of '-Warray-bounds' globally.

There are additional similar fixes in other maintainer's trees, but
these ended up getting carried by me. :)"

* tag 'bounds-fixes-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
media: omap3isp: Use struct_group() for memcpy() region
tpm: vtpm_proxy: Check length to avoid compiler warning
alpha: Silence -Warray-bounds warnings
m68k: cmpxchg: Dereference matching size
intel_th: msu: Use memset_startat() for clearing hw header
KVM: x86: Replace memset() "optimization" with normal per-field writes

+33 -29
+3 -3
arch/alpha/mm/init.c
··· 76 76 pmd_t * 77 77 __bad_pagetable(void) 78 78 { 79 - memset((void *) EMPTY_PGT, 0, PAGE_SIZE); 79 + memset(absolute_pointer(EMPTY_PGT), 0, PAGE_SIZE); 80 80 return (pmd_t *) EMPTY_PGT; 81 81 } 82 82 83 83 pte_t 84 84 __bad_page(void) 85 85 { 86 - memset((void *) EMPTY_PGE, 0, PAGE_SIZE); 86 + memset(absolute_pointer(EMPTY_PGE), 0, PAGE_SIZE); 87 87 return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE), PAGE_SHARED)); 88 88 } 89 89 ··· 253 253 free_area_init(max_zone_pfn); 254 254 255 255 /* Initialize the kernel's ZERO_PGE. */ 256 - memset((void *)ZERO_PGE, 0, PAGE_SIZE); 256 + memset(absolute_pointer(ZERO_PGE), 0, PAGE_SIZE); 257 257 } 258 258 259 259 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
+4 -5
arch/m68k/include/asm/cmpxchg.h
··· 4 4 5 5 #include <linux/irqflags.h> 6 6 7 - struct __xchg_dummy { unsigned long a[100]; }; 8 - #define __xg(x) ((volatile struct __xchg_dummy *)(x)) 7 + #define __xg(type, x) ((volatile type *)(x)) 9 8 10 9 extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int); 11 10 ··· 49 50 "1:\n\t" 50 51 "casb %0,%1,%2\n\t" 51 52 "jne 1b" 52 - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); 53 + : "=&d" (x) : "d" (x), "m" (*__xg(u8, ptr)) : "memory"); 53 54 break; 54 55 case 2: 55 56 __asm__ __volatile__ ··· 57 58 "1:\n\t" 58 59 "casw %0,%1,%2\n\t" 59 60 "jne 1b" 60 - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); 61 + : "=&d" (x) : "d" (x), "m" (*__xg(u16, ptr)) : "memory"); 61 62 break; 62 63 case 4: 63 64 __asm__ __volatile__ ··· 65 66 "1:\n\t" 66 67 "casl %0,%1,%2\n\t" 67 68 "jne 1b" 68 - : "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory"); 69 + : "=&d" (x) : "d" (x), "m" (*__xg(u32, ptr)) : "memory"); 69 70 break; 70 71 default: 71 72 x = __invalid_xchg_size(x, ptr, size);
+7 -2
arch/x86/kvm/emulate.c
··· 5395 5395 5396 5396 void init_decode_cache(struct x86_emulate_ctxt *ctxt) 5397 5397 { 5398 - memset(&ctxt->rip_relative, 0, 5399 - (void *)&ctxt->modrm - (void *)&ctxt->rip_relative); 5398 + /* Clear fields that are set conditionally but read without a guard. */ 5399 + ctxt->rip_relative = false; 5400 + ctxt->rex_prefix = 0; 5401 + ctxt->lock_prefix = 0; 5402 + ctxt->rep_prefix = 0; 5403 + ctxt->regs_valid = 0; 5404 + ctxt->regs_dirty = 0; 5400 5405 5401 5406 ctxt->io_read.pos = 0; 5402 5407 ctxt->io_read.end = 0;
+1 -5
arch/x86/kvm/kvm_emulate.h
··· 336 336 fastop_t fop; 337 337 }; 338 338 int (*check_perm)(struct x86_emulate_ctxt *ctxt); 339 - /* 340 - * The following six fields are cleared together, 341 - * the rest are initialized unconditionally in x86_decode_insn 342 - * or elsewhere 343 - */ 339 + 344 340 bool rip_relative; 345 341 u8 rex_prefix; 346 342 u8 lock_prefix;
+1 -1
drivers/char/tpm/tpm_vtpm_proxy.c
··· 91 91 92 92 len = proxy_dev->req_len; 93 93 94 - if (count < len) { 94 + if (count < len || len > sizeof(proxy_dev->buffer)) { 95 95 mutex_unlock(&proxy_dev->buf_lock); 96 96 pr_debug("Invalid size in recv: count=%zd, req_len=%zd\n", 97 97 count, len);
+1 -3
drivers/hwtracing/intel_th/msu.c
··· 658 658 659 659 list_for_each_entry(win, &msc->win_list, entry) { 660 660 unsigned int blk; 661 - size_t hw_sz = sizeof(struct msc_block_desc) - 662 - offsetof(struct msc_block_desc, hw_tag); 663 661 664 662 for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { 665 663 struct msc_block_desc *bdesc = sg_virt(sg); 666 664 667 - memset(&bdesc->hw_tag, 0, hw_sz); 665 + memset_startat(bdesc, 0, hw_tag); 668 666 } 669 667 } 670 668 }
+3 -2
drivers/media/platform/omap3isp/ispstat.c
··· 512 512 int omap3isp_stat_request_statistics_time32(struct ispstat *stat, 513 513 struct omap3isp_stat_data_time32 *data) 514 514 { 515 - struct omap3isp_stat_data data64; 515 + struct omap3isp_stat_data data64 = { }; 516 516 int ret; 517 517 518 518 ret = omap3isp_stat_request_statistics(stat, &data64); ··· 521 521 522 522 data->ts.tv_sec = data64.ts.tv_sec; 523 523 data->ts.tv_usec = data64.ts.tv_usec; 524 - memcpy(&data->buf, &data64.buf, sizeof(*data) - sizeof(data->ts)); 524 + data->buf = (uintptr_t)data64.buf; 525 + memcpy(&data->frame, &data64.frame, sizeof(data->frame)); 525 526 526 527 return 0; 527 528 }
+13 -8
include/uapi/linux/omap3isp.h
··· 162 162 * struct omap3isp_stat_data - Statistic data sent to or received from user 163 163 * @ts: Timestamp of returned framestats. 164 164 * @buf: Pointer to pass to user. 165 + * @buf_size: Size of buffer. 165 166 * @frame_number: Frame number of requested stats. 166 167 * @cur_frame: Current frame number being processed. 167 168 * @config_counter: Number of the configuration associated with the data. ··· 177 176 struct timeval ts; 178 177 #endif 179 178 void __user *buf; 180 - __u32 buf_size; 181 - __u16 frame_number; 182 - __u16 cur_frame; 183 - __u16 config_counter; 179 + __struct_group(/* no tag */, frame, /* no attrs */, 180 + __u32 buf_size; 181 + __u16 frame_number; 182 + __u16 cur_frame; 183 + __u16 config_counter; 184 + ); 184 185 }; 185 186 186 187 #ifdef __KERNEL__ ··· 192 189 __s32 tv_usec; 193 190 } ts; 194 191 __u32 buf; 195 - __u32 buf_size; 196 - __u16 frame_number; 197 - __u16 cur_frame; 198 - __u16 config_counter; 192 + __struct_group(/* no tag */, frame, /* no attrs */, 193 + __u32 buf_size; 194 + __u16 frame_number; 195 + __u16 cur_frame; 196 + __u16 config_counter; 197 + ); 199 198 }; 200 199 #endif 201 200