On 10/14/24 09:52, Feng Tang wrote: > On Fri, Oct 04, 2024 at 05:52:10PM +0800, Vlastimil Babka wrote: > Thanks for the suggestion! > > As there were error report about the NULL slab for big kmalloc object, how > about the following code for > > __do_krealloc(const void *p, size_t new_size, gfp_t flags) > { > void *ret; > size_t ks = 0; > int orig_size = 0; > struct kmem_cache *s = NULL; > > /* Check for double-free. */ > if (likely(!ZERO_OR_NULL_PTR(p))) { > if (!kasan_check_byte(p)) > return NULL; > > ks = ksize(p); I think this will result in __ksize() doing skip_orig_size_check(folio_slab(folio)->slab_cache, object); and we don't want that? Also the checks below repeat some of the checks of ksize(). So I think in __do_krealloc() we should do things manually to determine ks and not call ksize(). Just not break any of the cases ksize() handles (kfence, large kmalloc). > > /* Some objects have no orig_size, like big kmalloc case */ > if (is_kfence_address(p)) { > orig_size = kfence_ksize(p); > } else if (virt_to_slab(p)) { > s = virt_to_cache(p); > orig_size = get_orig_size(s, (void *)p); > } > } else { > goto alloc_new; > } > > /* If the object doesn't fit, allocate a bigger one */ > if (new_size > ks) > goto alloc_new; > > /* Zero out spare memory. */ > if (want_init_on_alloc(flags)) { > kasan_disable_current(); > if (orig_size && orig_size < new_size) > memset((void *)p + orig_size, 0, new_size - orig_size); > else > memset((void *)p + new_size, 0, ks - new_size); > kasan_enable_current(); > } > > /* Setup kmalloc redzone when needed */ > if (s && slub_debug_orig_size(s) && !is_kfence_address(p)) { > set_orig_size(s, (void *)p, new_size); > if (s->flags & SLAB_RED_ZONE && new_size < ks) > memset_no_sanitize_memory((void *)p + new_size, > SLUB_RED_ACTIVE, ks - new_size); > } > > p = kasan_krealloc((void *)p, new_size, flags); > return (void *)p; > > alloc_new: > ret = kmalloc_node_track_caller_noprof(new_size, flags, NUMA_NO_NODE, _RET_IP_); > if (ret && p) { > /* Disable KASAN checks as the object's redzone is accessed. */ > kasan_disable_current(); > memcpy(ret, kasan_reset_tag(p), orig_size ?: ks); > kasan_enable_current(); > } > > return ret; > } > > I've run it with the reproducer of syzbot, so far the issue hasn't been > reproduced on my local machine. > > Thanks, > Feng > >> >> But either way means rewriting 2 commits. I think it's indeed better to drop >> the series now from -next and submit a v3. >> >> Vlastimil >> >> >> Thanks, >> >> -- Marco >> > >>