Pull misc fixes from Andrew Morton: "17 hotfixes. Eight are for MM and seven are for other parts of the kernel. Seven are cc:stable and eight address post-6.3 issues or were judged unsuitable for -stable backporting" * tag 'mm-hotfixes-stable-2023-03-04-13-12' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mailmap: map Dikshita Agarwal's old address to his current one mailmap: map Vikash Garodia's old address to his current one fs/cramfs/inode.c: initialize file_ra_state fs: hfsplus: fix UAF issue in hfsplus_put_super panic: fix the panic_print NMI backtrace setting lib: parser: update documentation for match_NUMBER functions kasan, x86: don't rename memintrinsics in uninstrumented files kasan: test: fix test for new meminstrinsic instrumentation kasan: treat meminstrinsic as builtins in uninstrumented files kasan: emit different calls for instrumentable memintrinsics ocfs2: fix non-auto defrag path not working issue ocfs2: fix defrag path triggering jbd2 ASSERT mailmap: map Georgi Djakov's old Linaro address to his current one mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON lib/zlib: DFLTCC deflate does not write all available bits for Z_NO_FLUSH mm/damon/paddr: fix missing folio_put() mm/mremap: fix dup_anon_vma() in vma_merge() case 4
Unified · Split
| @@ -121,6 +121,7 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com> · 120 unmodified lines | ||
| 121 | 121 | Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com> |
| 122 | 122 | Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com> |
| 123 | 123 | <dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be> |
| 124 | +Dikshita Agarwal <dikshita@qti.qualcomm.com> <dikshita@codeaurora.org> | |
| 124 | 125 | Dmitry Baryshkov <dbaryshkov@gmail.com> |
| 125 | 126 | Dmitry Baryshkov <dbaryshkov@gmail.com> <[dbaryshkov@gmail.com]> |
| 126 | 127 | Dmitry Baryshkov <dbaryshkov@gmail.com> <dmitry_baryshkov@mentor.com> |
| @@ -150,6 +151,7 @@ Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com> · 23 unmodified lines | ||
| 150 | 151 | Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com> |
| 151 | 152 | Gao Xiang <xiang@kernel.org> <hsiangkao@linux.alibaba.com> |
| 152 | 153 | Gao Xiang <xiang@kernel.org> <hsiangkao@redhat.com> |
| 154 | +Georgi Djakov <djakov@kernel.org> <georgi.djakov@linaro.org> | |
| 153 | 155 | Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com> |
| 154 | 156 | Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com> |
| 155 | 157 | Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com> |
| @@ -441,6 +443,7 @@ Vasily Averin <vasily.averin@linux.dev> <vvs@openvz.org> · 285 unmodified lines | ||
| 441 | 443 | Vasily Averin <vasily.averin@linux.dev> <vvs@parallels.com> |
| 442 | 444 | Vasily Averin <vasily.averin@linux.dev> <vvs@sw.ru> |
| 443 | 445 | Valentin Schneider <vschneid@redhat.com> <valentin.schneider@arm.com> |
| 446 | +Vikash Garodia <quic_vgarodia@quicinc.com> <vgarodia@codeaurora.org> | |
| 444 | 447 | Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com> |
| 445 | 448 | Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com> |
| 446 | 449 | Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org> |
| @@ -85,25 +85,6 @@ char *strcpy(char *dest, const char *src); · 84 unmodified lines | ||
| 85 | 85 | char *strcat(char *dest, const char *src); |
| 86 | 86 | int strcmp(const char *cs, const char *ct); |
| 87 | 87 | |
| 88 | −#if (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)) | |
| 89 | −/* | |
| 90 | − * For files that not instrumented (e.g. mm/slub.c) we | |
| 91 | − * should use not instrumented version of mem* functions. | |
| 92 | − */ | |
| 93 | − | |
| 94 | −#undef memcpy | |
| 95 | −#define memcpy(dst, src, len) __memcpy(dst, src, len) | |
| 96 | −#undef memmove | |
| 97 | −#define memmove(dst, src, len) __memmove(dst, src, len) | |
| 98 | −#undef memset | |
| 99 | −#define memset(s, c, n) __memset(s, c, n) | |
| 100 | − | |
| 101 | −#ifndef __NO_FORTIFY | |
| 102 | −#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ | |
| 103 | −#endif | |
| 104 | − | |
| 105 | −#endif | |
| 106 | − | |
| 107 | 88 | #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE |
| 108 | 89 | #define __HAVE_ARCH_MEMCPY_FLUSHCACHE 1 |
| 109 | 90 | void __memcpy_flushcache(void *dst, const void *src, size_t cnt); |
| @@ -183,7 +183,7 @@ static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset, · 182 unmodified lines | ||
| 183 | 183 | unsigned int len) |
| 184 | 184 | { |
| 185 | 185 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; |
| 186 | − struct file_ra_state ra; | |
| 186 | + struct file_ra_state ra = {}; | |
| 187 | 187 | struct page *pages[BLKS_PER_BUF]; |
| 188 | 188 | unsigned i, blocknr, buffer; |
| 189 | 189 | unsigned long devsize; |
| @@ -295,11 +295,11 @@ static void hfsplus_put_super(struct super_block *sb) · 294 unmodified lines | ||
| 295 | 295 | hfsplus_sync_fs(sb, 1); |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | + iput(sbi->alloc_file); | |
| 299 | + iput(sbi->hidden_dir); | |
| 298 | 300 | hfs_btree_close(sbi->attr_tree); |
| 299 | 301 | hfs_btree_close(sbi->cat_tree); |
| 300 | 302 | hfs_btree_close(sbi->ext_tree); |
| 301 | − iput(sbi->alloc_file); | |
| 302 | − iput(sbi->hidden_dir); | |
| 303 | 303 | kfree(sbi->s_vhdr_buf); |
| 304 | 304 | kfree(sbi->s_backup_vhdr_buf); |
| 305 | 305 | unload_nls(sbi->nls); |
| @@ -105,14 +105,6 @@ static int __ocfs2_move_extent(handle_t *handle, · 104 unmodified lines | ||
| 105 | 105 | */ |
| 106 | 106 | replace_rec.e_flags = ext_flags & ~OCFS2_EXT_REFCOUNTED; |
| 107 | 107 | |
| 108 | − ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), | |
| 109 | − context->et.et_root_bh, | |
| 110 | − OCFS2_JOURNAL_ACCESS_WRITE); | |
| 111 | − if (ret) { | |
| 112 | − mlog_errno(ret); | |
| 113 | − goto out; | |
| 114 | − } | |
| 115 | − | |
| 116 | 108 | ret = ocfs2_split_extent(handle, &context->et, path, index, |
| 117 | 109 | &replace_rec, context->meta_ac, |
| 118 | 110 | &context->dealloc); |
| @@ -121,8 +113,6 @@ static int __ocfs2_move_extent(handle_t *handle, · 2 unmodified lines | ||
| 121 | 113 | goto out; |
| 122 | 114 | } |
| 123 | 115 | |
| 124 | − ocfs2_journal_dirty(handle, context->et.et_root_bh); | |
| 125 | − | |
| 126 | 116 | context->new_phys_cpos = new_p_cpos; |
| 127 | 117 | |
| 128 | 118 | /* |
| @@ -444,7 +434,7 @@ static int ocfs2_find_victim_alloc_group(struct inode *inode, · 315 unmodified lines | ||
| 444 | 434 | bg = (struct ocfs2_group_desc *)gd_bh->b_data; |
| 445 | 435 | |
| 446 | 436 | if (vict_blkno < (le64_to_cpu(bg->bg_blkno) + |
| 447 | − le16_to_cpu(bg->bg_bits))) { | |
| 437 | + (le16_to_cpu(bg->bg_bits) << bits_per_unit))) { | |
| 448 | 438 | |
| 449 | 439 | *ret_bh = gd_bh; |
| 450 | 440 | *vict_bit = (vict_blkno - blkno) >> |
| @@ -559,6 +549,7 @@ static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh, · 108 unmodified lines | ||
| 559 | 549 | last_free_bits++; |
| 560 | 550 | |
| 561 | 551 | if (last_free_bits == move_len) { |
| 552 | + i -= move_len; | |
| 562 | 553 | *goal_bit = i; |
| 563 | 554 | *phys_cpos = base_cpos + i; |
| 564 | 555 | break; |
| @@ -1030,18 +1021,19 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) · 465 unmodified lines | ||
| 1030 | 1021 | |
| 1031 | 1022 | context->range = ⦥ |
| 1032 | 1023 | |
| 1024 | + /* | |
| 1025 | + * ok, the default theshold for the defragmentation | |
| 1026 | + * is 1M, since our maximum clustersize was 1M also. | |
| 1027 | + * any thought? | |
| 1028 | + */ | |
| 1029 | + if (!range.me_threshold) | |
| 1030 | + range.me_threshold = 1024 * 1024; | |
| 1031 | + | |
| 1032 | + if (range.me_threshold > i_size_read(inode)) | |
| 1033 | + range.me_threshold = i_size_read(inode); | |
| 1034 | + | |
| 1033 | 1035 | if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) { |
| 1034 | 1036 | context->auto_defrag = 1; |
| 1035 | − /* | |
| 1036 | − * ok, the default theshold for the defragmentation | |
| 1037 | − * is 1M, since our maximum clustersize was 1M also. | |
| 1038 | − * any thought? | |
| 1039 | − */ | |
| 1040 | − if (!range.me_threshold) | |
| 1041 | − range.me_threshold = 1024 * 1024; | |
| 1042 | − | |
| 1043 | − if (range.me_threshold > i_size_read(inode)) | |
| 1044 | − range.me_threshold = i_size_read(inode); | |
| 1045 | 1037 | |
| 1046 | 1038 | if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG) |
| 1047 | 1039 | context->partial = 1; |
| @@ -94,7 +94,7 @@ enum ttu_flags { · 93 unmodified lines | ||
| 94 | 94 | TTU_SPLIT_HUGE_PMD = 0x4, /* split huge PMD if any */ |
| 95 | 95 | TTU_IGNORE_MLOCK = 0x8, /* ignore mlock */ |
| 96 | 96 | TTU_SYNC = 0x10, /* avoid racy checks with PVMW_SYNC */ |
| 97 | − TTU_IGNORE_HWPOISON = 0x20, /* corrupted page is recoverable */ | |
| 97 | + TTU_HWPOISON = 0x20, /* do convert pte to hwpoison entry */ | |
| 98 | 98 | TTU_BATCH_FLUSH = 0x40, /* Batch TLB flushes where possible |
| 99 | 99 | * and caller guarantees they will |
| 100 | 100 | * do a final flush if necessary */ |
| @@ -212,9 +212,6 @@ static void panic_print_sys_info(bool console_flush) · 211 unmodified lines | ||
| 212 | 212 | return; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | − if (panic_print & PANIC_PRINT_ALL_CPU_BT) | |
| 216 | − trigger_all_cpu_backtrace(); | |
| 217 | − | |
| 218 | 215 | if (panic_print & PANIC_PRINT_TASK_INFO) |
| 219 | 216 | show_state(); |
| 220 | 217 | |
| @@ -244,6 +241,30 @@ void check_panic_on_warn(const char *origin) · 23 unmodified lines | ||
| 244 | 241 | origin, limit); |
| 245 | 242 | } |
| 246 | 243 | |
| 244 | +/* | |
| 245 | + * Helper that triggers the NMI backtrace (if set in panic_print) | |
| 246 | + * and then performs the secondary CPUs shutdown - we cannot have | |
| 247 | + * the NMI backtrace after the CPUs are off! | |
| 248 | + */ | |
| 249 | +static void panic_other_cpus_shutdown(bool crash_kexec) | |
| 250 | +{ | |
| 251 | + if (panic_print & PANIC_PRINT_ALL_CPU_BT) | |
| 252 | + trigger_all_cpu_backtrace(); | |
| 253 | + | |
| 254 | + /* | |
| 255 | + * Note that smp_send_stop() is the usual SMP shutdown function, | |
| 256 | + * which unfortunately may not be hardened to work in a panic | |
| 257 | + * situation. If we want to do crash dump after notifier calls | |
| 258 | + * and kmsg_dump, we will need architecture dependent extra | |
| 259 | + * bits in addition to stopping other CPUs, hence we rely on | |
| 260 | + * crash_smp_send_stop() for that. | |
| 261 | + */ | |
| 262 | + if (!crash_kexec) | |
| 263 | + smp_send_stop(); | |
| 264 | + else | |
| 265 | + crash_smp_send_stop(); | |
| 266 | +} | |
| 267 | + | |
| 247 | 268 | /** |
| 248 | 269 | * panic - halt the system |
| 249 | 270 | * @fmt: The text string to print |
| @@ -334,23 +355,10 @@ void panic(const char *fmt, ...) · 84 unmodified lines | ||
| 334 | 355 | * |
| 335 | 356 | * Bypass the panic_cpu check and call __crash_kexec directly. |
| 336 | 357 | */ |
| 337 | − if (!_crash_kexec_post_notifiers) { | |
| 358 | + if (!_crash_kexec_post_notifiers) | |
| 338 | 359 | __crash_kexec(NULL); |
| 339 | 360 | |
| 340 | − /* | |
| 341 | − * Note smp_send_stop is the usual smp shutdown function, which | |
| 342 | − * unfortunately means it may not be hardened to work in a | |
| 343 | − * panic situation. | |
| 344 | − */ | |
| 345 | − smp_send_stop(); | |
| 346 | − } else { | |
| 347 | − /* | |
| 348 | − * If we want to do crash dump after notifier calls and | |
| 349 | − * kmsg_dump, we will need architecture dependent extra | |
| 350 | − * works in addition to stopping other CPUs. | |
| 351 | − */ | |
| 352 | − crash_smp_send_stop(); | |
| 353 | − } | |
| 361 | + panic_other_cpus_shutdown(_crash_kexec_post_notifiers); | |
| 354 | 362 | |
| 355 | 363 | /* |
| 356 | 364 | * Run any panic handlers, including those that might need to |
| @@ -49,6 +49,15 @@ menuconfig KASAN · 48 unmodified lines | ||
| 49 | 49 | |
| 50 | 50 | if KASAN |
| 51 | 51 | |
| 52 | +config CC_HAS_KASAN_MEMINTRINSIC_PREFIX | |
| 53 | + def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=kernel-address -mllvm -asan-kernel-mem-intrinsic-prefix=1)) || \ | |
| 54 | + (CC_IS_GCC && $(cc-option,-fsanitize=kernel-address --param asan-kernel-mem-intrinsic-prefix=1)) | |
| 55 | + # Don't define it if we don't need it: compilation of the test uses | |
| 56 | + # this variable to decide how the compiler should treat builtins. | |
| 57 | + depends on !KASAN_HW_TAGS | |
| 58 | + help | |
| 59 | + The compiler is able to prefix memintrinsics with __asan or __hwasan. | |
| 60 | + | |
| 52 | 61 | choice |
| 53 | 62 | prompt "KASAN mode" |
| 54 | 63 | default KASAN_GENERIC |
| @@ -133,7 +133,7 @@ EXPORT_SYMBOL(match_token); · 132 unmodified lines | ||
| 133 | 133 | * as a number in that base. |
| 134 | 134 | * |
| 135 | 135 | * Return: On success, sets @result to the integer represented by the |
| 136 | − * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 136 | + * string and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 137 | 137 | */ |
| 138 | 138 | static int match_number(substring_t *s, int *result, int base) |
| 139 | 139 | { |
| @@ -165,7 +165,7 @@ static int match_number(substring_t *s, int *result, int base) · 25 unmodified lines | ||
| 165 | 165 | * as a number in that base. |
| 166 | 166 | * |
| 167 | 167 | * Return: On success, sets @result to the integer represented by the |
| 168 | − * string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 168 | + * string and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 169 | 169 | */ |
| 170 | 170 | static int match_u64int(substring_t *s, u64 *result, int base) |
| 171 | 171 | { |
| @@ -189,7 +189,7 @@ static int match_u64int(substring_t *s, u64 *result, int base) · 17 unmodified lines | ||
| 189 | 189 | * Description: Attempts to parse the &substring_t @s as a decimal integer. |
| 190 | 190 | * |
| 191 | 191 | * Return: On success, sets @result to the integer represented by the string |
| 192 | − * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 192 | + * and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 193 | 193 | */ |
| 194 | 194 | int match_int(substring_t *s, int *result) |
| 195 | 195 | { |
| @@ -205,7 +205,7 @@ EXPORT_SYMBOL(match_int); · 9 unmodified lines | ||
| 205 | 205 | * Description: Attempts to parse the &substring_t @s as a decimal integer. |
| 206 | 206 | * |
| 207 | 207 | * Return: On success, sets @result to the integer represented by the string |
| 208 | − * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 208 | + * and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 209 | 209 | */ |
| 210 | 210 | int match_uint(substring_t *s, unsigned int *result) |
| 211 | 211 | { |
| @@ -228,7 +228,7 @@ EXPORT_SYMBOL(match_uint); · 16 unmodified lines | ||
| 228 | 228 | * integer. |
| 229 | 229 | * |
| 230 | 230 | * Return: On success, sets @result to the integer represented by the string |
| 231 | − * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 231 | + * and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 232 | 232 | */ |
| 233 | 233 | int match_u64(substring_t *s, u64 *result) |
| 234 | 234 | { |
| @@ -244,7 +244,7 @@ EXPORT_SYMBOL(match_u64); · 9 unmodified lines | ||
| 244 | 244 | * Description: Attempts to parse the &substring_t @s as an octal integer. |
| 245 | 245 | * |
| 246 | 246 | * Return: On success, sets @result to the integer represented by the string |
| 247 | − * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 247 | + * and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 248 | 248 | */ |
| 249 | 249 | int match_octal(substring_t *s, int *result) |
| 250 | 250 | { |
| @@ -260,7 +260,7 @@ EXPORT_SYMBOL(match_octal); · 9 unmodified lines | ||
| 260 | 260 | * Description: Attempts to parse the &substring_t @s as a hexadecimal integer. |
| 261 | 261 | * |
| 262 | 262 | * Return: On success, sets @result to the integer represented by the string |
| 263 | − * and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. | |
| 263 | + * and returns 0. Returns -EINVAL or -ERANGE on failure. | |
| 264 | 264 | */ |
| 265 | 265 | int match_hex(substring_t *s, int *result) |
| 266 | 266 | { |
| @@ -420,9 +420,11 @@ static inline void flush_pending( · 419 unmodified lines | ||
| 420 | 420 | z_streamp strm |
| 421 | 421 | ) |
| 422 | 422 | { |
| 423 | + unsigned len; | |
| 423 | 424 | deflate_state *s = (deflate_state *) strm->state; |
| 424 | − unsigned len = s->pending; | |
| 425 | 425 | |
| 426 | + bi_flush(s); | |
| 427 | + len = s->pending; | |
| 426 | 428 | if (len > strm->avail_out) len = strm->avail_out; |
| 427 | 429 | if (len == 0) return; |
| 428 | 430 | |
| @@ -250,12 +250,11 @@ static unsigned long damon_pa_pageout(struct damon_region *r, struct damos *s) · 249 unmodified lines | ||
| 250 | 250 | folio_put(folio); |
| 251 | 251 | continue; |
| 252 | 252 | } |
| 253 | − if (folio_test_unevictable(folio)) { | |
| 253 | + if (folio_test_unevictable(folio)) | |
| 254 | 254 | folio_putback_lru(folio); |
| 255 | − } else { | |
| 255 | + else | |
| 256 | 256 | list_add(&folio->lru, &folio_list); |
| 257 | − folio_put(folio); | |
| 258 | − } | |
| 257 | + folio_put(folio); | |
| 259 | 258 | } |
| 260 | 259 | applied = reclaim_pages(&folio_list); |
| 261 | 260 | cond_resched(); |
| @@ -35,7 +35,14 @@ CFLAGS_shadow.o := $(CC_FLAGS_KASAN_RUNTIME) · 34 unmodified lines | ||
| 35 | 35 | CFLAGS_hw_tags.o := $(CC_FLAGS_KASAN_RUNTIME) |
| 36 | 36 | CFLAGS_sw_tags.o := $(CC_FLAGS_KASAN_RUNTIME) |
| 37 | 37 | |
| 38 | −CFLAGS_KASAN_TEST := $(CFLAGS_KASAN) -fno-builtin $(call cc-disable-warning, vla) | |
| 38 | +CFLAGS_KASAN_TEST := $(CFLAGS_KASAN) $(call cc-disable-warning, vla) | |
| 39 | +ifndef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX | |
| 40 | +# If compiler instruments memintrinsics by prefixing them with __asan/__hwasan, | |
| 41 | +# we need to treat them normally (as builtins), otherwise the compiler won't | |
| 42 | +# recognize them as instrumentable. If it doesn't instrument them, we need to | |
| 43 | +# pass -fno-builtin, so the compiler doesn't inline them. | |
| 44 | +CFLAGS_KASAN_TEST += -fno-builtin | |
| 45 | +endif | |
| 39 | 46 | |
| 40 | 47 | CFLAGS_kasan_test.o := $(CFLAGS_KASAN_TEST) |
| 41 | 48 | CFLAGS_kasan_test_module.o := $(CFLAGS_KASAN_TEST) |
| @@ -666,4 +666,8 @@ void __hwasan_storeN_noabort(unsigned long addr, size_t size); · 665 unmodified lines | ||
| 666 | 666 | |
| 667 | 667 | void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size); |
| 668 | 668 | |
| 669 | +void *__hwasan_memset(void *addr, int c, size_t len); | |
| 670 | +void *__hwasan_memmove(void *dest, const void *src, size_t len); | |
| 671 | +void *__hwasan_memcpy(void *dest, const void *src, size_t len); | |
| 672 | + | |
| 669 | 673 | #endif /* __MM_KASAN_KASAN_H */ |
| @@ -165,6 +165,15 @@ static void kasan_test_exit(struct kunit *test) · 164 unmodified lines | ||
| 165 | 165 | kunit_skip((test), "Test requires " #config "=n"); \ |
| 166 | 166 | } while (0) |
| 167 | 167 | |
| 168 | +#define KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test) do { \ | |
| 169 | + if (IS_ENABLED(CONFIG_KASAN_HW_TAGS)) \ | |
| 170 | + break; /* No compiler instrumentation. */ \ | |
| 171 | + if (IS_ENABLED(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX)) \ | |
| 172 | + break; /* Should always be instrumented! */ \ | |
| 173 | + if (IS_ENABLED(CONFIG_GENERIC_ENTRY)) \ | |
| 174 | + kunit_skip((test), "Test requires checked mem*()"); \ | |
| 175 | +} while (0) | |
| 176 | + | |
| 168 | 177 | static void kmalloc_oob_right(struct kunit *test) |
| 169 | 178 | { |
| 170 | 179 | char *ptr; |
| @@ -454,6 +463,8 @@ static void kmalloc_oob_16(struct kunit *test) · 283 unmodified lines | ||
| 454 | 463 | u64 words[2]; |
| 455 | 464 | } *ptr1, *ptr2; |
| 456 | 465 | |
| 466 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 467 | + | |
| 457 | 468 | /* This test is specifically crafted for the generic mode. */ |
| 458 | 469 | KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC); |
| 459 | 470 | |
| @@ -476,6 +487,8 @@ static void kmalloc_uaf_16(struct kunit *test) · 16 unmodified lines | ||
| 476 | 487 | u64 words[2]; |
| 477 | 488 | } *ptr1, *ptr2; |
| 478 | 489 | |
| 490 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 491 | + | |
| 479 | 492 | ptr1 = kmalloc(sizeof(*ptr1), GFP_KERNEL); |
| 480 | 493 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); |
| 481 | 494 | |
| @@ -498,6 +511,8 @@ static void kmalloc_oob_memset_2(struct kunit *test) · 16 unmodified lines | ||
| 498 | 511 | char *ptr; |
| 499 | 512 | size_t size = 128 - KASAN_GRANULE_SIZE; |
| 500 | 513 | |
| 514 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 515 | + | |
| 501 | 516 | ptr = kmalloc(size, GFP_KERNEL); |
| 502 | 517 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 503 | 518 | |
| @@ -511,6 +526,8 @@ static void kmalloc_oob_memset_4(struct kunit *test) · 7 unmodified lines | ||
| 511 | 526 | char *ptr; |
| 512 | 527 | size_t size = 128 - KASAN_GRANULE_SIZE; |
| 513 | 528 | |
| 529 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 530 | + | |
| 514 | 531 | ptr = kmalloc(size, GFP_KERNEL); |
| 515 | 532 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 516 | 533 | |
| @@ -524,6 +541,8 @@ static void kmalloc_oob_memset_8(struct kunit *test) · 7 unmodified lines | ||
| 524 | 541 | char *ptr; |
| 525 | 542 | size_t size = 128 - KASAN_GRANULE_SIZE; |
| 526 | 543 | |
| 544 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 545 | + | |
| 527 | 546 | ptr = kmalloc(size, GFP_KERNEL); |
| 528 | 547 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 529 | 548 | |
| @@ -537,6 +556,8 @@ static void kmalloc_oob_memset_16(struct kunit *test) · 7 unmodified lines | ||
| 537 | 556 | char *ptr; |
| 538 | 557 | size_t size = 128 - KASAN_GRANULE_SIZE; |
| 539 | 558 | |
| 559 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 560 | + | |
| 540 | 561 | ptr = kmalloc(size, GFP_KERNEL); |
| 541 | 562 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 542 | 563 | |
| @@ -550,6 +571,8 @@ static void kmalloc_oob_in_memset(struct kunit *test) · 7 unmodified lines | ||
| 550 | 571 | char *ptr; |
| 551 | 572 | size_t size = 128 - KASAN_GRANULE_SIZE; |
| 552 | 573 | |
| 574 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 575 | + | |
| 553 | 576 | ptr = kmalloc(size, GFP_KERNEL); |
| 554 | 577 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 555 | 578 | |
| @@ -566,6 +589,8 @@ static void kmalloc_memmove_negative_size(struct kunit *test) · 10 unmodified lines | ||
| 566 | 589 | size_t size = 64; |
| 567 | 590 | size_t invalid_size = -2; |
| 568 | 591 | |
| 592 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 593 | + | |
| 569 | 594 | /* |
| 570 | 595 | * Hardware tag-based mode doesn't check memmove for negative size. |
| 571 | 596 | * As a result, this test introduces a side-effect memory corruption, |
| @@ -590,6 +615,8 @@ static void kmalloc_memmove_invalid_size(struct kunit *test) · 18 unmodified lines | ||
| 590 | 615 | size_t size = 64; |
| 591 | 616 | size_t invalid_size = size; |
| 592 | 617 | |
| 618 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 619 | + | |
| 593 | 620 | ptr = kmalloc(size, GFP_KERNEL); |
| 594 | 621 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); |
| 595 | 622 | |
| @@ -618,6 +645,8 @@ static void kmalloc_uaf_memset(struct kunit *test) · 22 unmodified lines | ||
| 618 | 645 | char *ptr; |
| 619 | 646 | size_t size = 33; |
| 620 | 647 | |
| 648 | + KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); | |
| 649 | + | |
| 621 | 650 | /* |
| 622 | 651 | * Only generic KASAN uses quarantine, which is required to avoid a |
| 623 | 652 | * kernel memory corruption this test causes. |
| @@ -38,11 +38,14 @@ bool __kasan_check_write(const volatile void *p, unsigned int size) · 37 unmodified lines | ||
| 38 | 38 | } |
| 39 | 39 | EXPORT_SYMBOL(__kasan_check_write); |
| 40 | 40 | |
| 41 | −#ifndef CONFIG_GENERIC_ENTRY | |
| 41 | +#if !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) && !defined(CONFIG_GENERIC_ENTRY) | |
| 42 | 42 | /* |
| 43 | 43 | * CONFIG_GENERIC_ENTRY relies on compiler emitted mem*() calls to not be |
| 44 | 44 | * instrumented. KASAN enabled toolchains should emit __asan_mem*() functions |
| 45 | 45 | * for the sites they want to instrument. |
| 46 | + * | |
| 47 | + * If we have a compiler that can instrument meminstrinsics, never override | |
| 48 | + * these, so that non-instrumented files can safely consider them as builtins. | |
| 46 | 49 | */ |
| 47 | 50 | #undef memset |
| 48 | 51 | void *memset(void *addr, int c, size_t len) |
| @@ -107,6 +110,17 @@ void *__asan_memcpy(void *dest, const void *src, size_t len) · 58 unmodified lines | ||
| 107 | 110 | } |
| 108 | 111 | EXPORT_SYMBOL(__asan_memcpy); |
| 109 | 112 | |
| 113 | +#ifdef CONFIG_KASAN_SW_TAGS | |
| 114 | +void *__hwasan_memset(void *addr, int c, size_t len) __alias(__asan_memset); | |
| 115 | +EXPORT_SYMBOL(__hwasan_memset); | |
| 116 | +#ifdef __HAVE_ARCH_MEMMOVE | |
| 117 | +void *__hwasan_memmove(void *dest, const void *src, size_t len) __alias(__asan_memmove); | |
| 118 | +EXPORT_SYMBOL(__hwasan_memmove); | |
| 119 | +#endif | |
| 120 | +void *__hwasan_memcpy(void *dest, const void *src, size_t len) __alias(__asan_memcpy); | |
| 121 | +EXPORT_SYMBOL(__hwasan_memcpy); | |
| 122 | +#endif | |
| 123 | + | |
| 110 | 124 | void kasan_poison(const void *addr, size_t size, u8 value, bool init) |
| 111 | 125 | { |
| 112 | 126 | void *shadow_start, *shadow_end; |
| @@ -1069,7 +1069,7 @@ static int me_pagecache_dirty(struct page_state *ps, struct page *p) · 1068 unmodified lines | ||
| 1069 | 1069 | * cache and swap cache(ie. page is freshly swapped in). So it could be |
| 1070 | 1070 | * referenced concurrently by 2 types of PTEs: |
| 1071 | 1071 | * normal PTEs and swap PTEs. We try to handle them consistently by calling |
| 1072 | − * try_to_unmap(TTU_IGNORE_HWPOISON) to convert the normal PTEs to swap PTEs, | |
| 1072 | + * try_to_unmap(!TTU_HWPOISON) to convert the normal PTEs to swap PTEs, | |
| 1073 | 1073 | * and then |
| 1074 | 1074 | * - clear dirty bit to prevent IO |
| 1075 | 1075 | * - remove from LRU |
| @@ -1486,7 +1486,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, · 410 unmodified lines | ||
| 1486 | 1486 | int flags, struct page *hpage) |
| 1487 | 1487 | { |
| 1488 | 1488 | struct folio *folio = page_folio(hpage); |
| 1489 | − enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC; | |
| 1489 | + enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; | |
| 1490 | 1490 | struct address_space *mapping; |
| 1491 | 1491 | LIST_HEAD(tokill); |
| 1492 | 1492 | bool unmap_success; |
| @@ -1516,7 +1516,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, · 23 unmodified lines | ||
| 1516 | 1516 | |
| 1517 | 1517 | if (PageSwapCache(p)) { |
| 1518 | 1518 | pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); |
| 1519 | − ttu |= TTU_IGNORE_HWPOISON; | |
| 1519 | + ttu &= ~TTU_HWPOISON; | |
| 1520 | 1520 | } |
| 1521 | 1521 | |
| 1522 | 1522 | /* |
| @@ -1531,7 +1531,7 @@ static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, · 8 unmodified lines | ||
| 1531 | 1531 | if (page_mkclean(hpage)) { |
| 1532 | 1532 | SetPageDirty(hpage); |
| 1533 | 1533 | } else { |
| 1534 | − ttu |= TTU_IGNORE_HWPOISON; | |
| 1534 | + ttu &= ~TTU_HWPOISON; | |
| 1535 | 1535 | pr_info("%#lx: corrupted page was clean: dropped without side effects\n", |
| 1536 | 1536 | pfn); |
| 1537 | 1537 | } |
| @@ -973,7 +973,7 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm, · 972 unmodified lines | ||
| 973 | 973 | vma_end = addr; |
| 974 | 974 | adjust = mid; |
| 975 | 975 | adj_next = -(vma->vm_end - addr); |
| 976 | − err = dup_anon_vma(res, adjust); | |
| 976 | + err = dup_anon_vma(adjust, prev); | |
| 977 | 977 | } else { |
| 978 | 978 | vma = next; /* case 3 */ |
| 979 | 979 | vma_start = addr; |
| @@ -1602,7 +1602,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, · 1601 unmodified lines | ||
| 1602 | 1602 | /* Update high watermark before we lower rss */ |
| 1603 | 1603 | update_hiwater_rss(mm); |
| 1604 | 1604 | |
| 1605 | − if (PageHWPoison(subpage) && !(flags & TTU_IGNORE_HWPOISON)) { | |
| 1605 | + if (PageHWPoison(subpage) && (flags & TTU_HWPOISON)) { | |
| 1606 | 1606 | pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); |
| 1607 | 1607 | if (folio_test_hugetlb(folio)) { |
| 1608 | 1608 | hugetlb_count_sub(folio_nr_pages(folio), mm); |
| @@ -1,5 +1,14 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | + | |
| 3 | +ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX | |
| 4 | +# Safe for compiler to generate meminstrinsic calls in uninstrumented files. | |
| 5 | +CFLAGS_KASAN_NOSANITIZE := | |
| 6 | +else | |
| 7 | +# Don't let compiler generate memintrinsic calls in uninstrumented files | |
| 8 | +# because they are instrumented. | |
| 2 | 9 | CFLAGS_KASAN_NOSANITIZE := -fno-builtin |
| 10 | +endif | |
| 11 | + | |
| 3 | 12 | KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) |
| 4 | 13 | |
| 5 | 14 | cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) |
| @@ -38,6 +47,11 @@ endif · 32 unmodified lines | ||
| 38 | 47 | |
| 39 | 48 | CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) |
| 40 | 49 | |
| 50 | +# Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*() | |
| 51 | +# instead. With compilers that don't support this option, compiler-inserted | |
| 52 | +# memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures. | |
| 53 | +CFLAGS_KASAN += $(call cc-param,asan-kernel-mem-intrinsic-prefix=1) | |
| 54 | + | |
| 41 | 55 | endif # CONFIG_KASAN_GENERIC |
| 42 | 56 | |
| 43 | 57 | ifdef CONFIG_KASAN_SW_TAGS |
| @@ -54,6 +68,9 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ · 10 unmodified lines | ||
| 54 | 68 | $(call cc-param,hwasan-inline-all-checks=0) \ |
| 55 | 69 | $(instrumentation_flags) |
| 56 | 70 | |
| 71 | +# Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). | |
| 72 | +CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) | |
| 73 | + | |
| 57 | 74 | endif # CONFIG_KASAN_SW_TAGS |
| 58 | 75 | |
| 59 | 76 | export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE |