···144144smaller than page size.145145146146The address of a chunk allocated with `kmalloc` is aligned to at least147147-ARCH_KMALLOC_MINALIGN bytes. For sizes which are a power of two, the148148-alignment is also guaranteed to be at least the respective size.147147+ARCH_KMALLOC_MINALIGN bytes. For sizes which are a power of two, the148148+alignment is also guaranteed to be at least the respective size. For other149149+sizes, the alignment is guaranteed to be at least the largest power-of-two150150+divisor of the size.149151150152Chunks allocated with kmalloc() can be resized with krealloc(). Similarly151153to kmalloc_array(): a helper for resizing arrays is provided in the form of
+3-3
include/linux/mm.h
···11101110 *11111111 * Return: The order of the folio.11121112 */11131113-static inline unsigned int folio_order(struct folio *folio)11131113+static inline unsigned int folio_order(const struct folio *folio)11141114{11151115 if (!folio_test_large(folio))11161116 return 0;···21502150 * it from being split. It is not necessary for the folio to be locked.21512151 * Return: The base-2 logarithm of the size of this folio.21522152 */21532153-static inline unsigned int folio_shift(struct folio *folio)21532153+static inline unsigned int folio_shift(const struct folio *folio)21542154{21552155 return PAGE_SHIFT + folio_order(folio);21562156}···21632163 * it from being split. It is not necessary for the folio to be locked.21642164 * Return: The number of bytes in this folio.21652165 */21662166-static inline size_t folio_size(struct folio *folio)21662166+static inline size_t folio_size(const struct folio *folio)21672167{21682168 return PAGE_SIZE << folio_order(folio);21692169}
+2-5
include/linux/poison.h
···3838 * Magic nums for obj red zoning.3939 * Placed in the first word before and the first word after an obj.4040 */4141-#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */4242-#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */4343-4444-#define SLUB_RED_INACTIVE 0xbb4545-#define SLUB_RED_ACTIVE 0xcc4141+#define SLUB_RED_INACTIVE 0xbb /* when obj is inactive */4242+#define SLUB_RED_ACTIVE 0xcc /* when obj is active */46434744/* ...and for poisoning */4845#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */
+65-32
include/linux/slab.h
···426426 NR_KMALLOC_TYPES427427};428428429429-extern struct kmem_cache *430430-kmalloc_caches[NR_KMALLOC_TYPES][KMALLOC_SHIFT_HIGH + 1];429429+typedef struct kmem_cache * kmem_buckets[KMALLOC_SHIFT_HIGH + 1];430430+431431+extern kmem_buckets kmalloc_caches[NR_KMALLOC_TYPES];431432432433/*433434 * Define gfp bits that should not be set for KMALLOC_NORMAL.···529528530529#include <linux/alloc_tag.h>531530532532-void *__kmalloc_noprof(size_t size, gfp_t flags) __assume_kmalloc_alignment __alloc_size(1);533533-#define __kmalloc(...) alloc_hooks(__kmalloc_noprof(__VA_ARGS__))534534-535531/**536532 * kmem_cache_alloc - Allocate an object537533 * @cachep: The cache to allocate from.···549551550552void kmem_cache_free(struct kmem_cache *s, void *objp);551553554554+kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,555555+ unsigned int useroffset, unsigned int usersize,556556+ void (*ctor)(void *));557557+552558/*553559 * Bulk allocation and freeing operations. These are accelerated in an554560 * allocator specific way to avoid taking locks repeatedly or building···570568 kmem_cache_free_bulk(NULL, size, p);571569}572570573573-void *__kmalloc_node_noprof(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment574574- __alloc_size(1);575575-#define __kmalloc_node(...) alloc_hooks(__kmalloc_node_noprof(__VA_ARGS__))576576-577571void *kmem_cache_alloc_node_noprof(struct kmem_cache *s, gfp_t flags,578572 int node) __assume_slab_alignment __malloc;579573#define kmem_cache_alloc_node(...) alloc_hooks(kmem_cache_alloc_node_noprof(__VA_ARGS__))580574581581-void *kmalloc_trace_noprof(struct kmem_cache *s, gfp_t flags, size_t size)582582- __assume_kmalloc_alignment __alloc_size(3);575575+/*576576+ * These macros allow declaring a kmem_buckets * parameter alongside size, which577577+ * can be compiled out with CONFIG_SLAB_BUCKETS=n so that a large number of call578578+ * sites don't have to pass NULL.579579+ */580580+#ifdef CONFIG_SLAB_BUCKETS581581+#define DECL_BUCKET_PARAMS(_size, _b) size_t (_size), kmem_buckets *(_b)582582+#define PASS_BUCKET_PARAMS(_size, _b) (_size), (_b)583583+#define PASS_BUCKET_PARAM(_b) (_b)584584+#else585585+#define DECL_BUCKET_PARAMS(_size, _b) size_t (_size)586586+#define PASS_BUCKET_PARAMS(_size, _b) (_size)587587+#define PASS_BUCKET_PARAM(_b) NULL588588+#endif583589584584-void *kmalloc_node_trace_noprof(struct kmem_cache *s, gfp_t gfpflags,585585- int node, size_t size) __assume_kmalloc_alignment586586- __alloc_size(4);587587-#define kmalloc_trace(...) alloc_hooks(kmalloc_trace_noprof(__VA_ARGS__))590590+/*591591+ * The following functions are not to be used directly and are intended only592592+ * for internal use from kmalloc() and kmalloc_node()593593+ * with the exception of kunit tests594594+ */588595589589-#define kmalloc_node_trace(...) alloc_hooks(kmalloc_node_trace_noprof(__VA_ARGS__))596596+void *__kmalloc_noprof(size_t size, gfp_t flags)597597+ __assume_kmalloc_alignment __alloc_size(1);590598591591-void *kmalloc_large_noprof(size_t size, gfp_t flags) __assume_page_alignment592592- __alloc_size(1);593593-#define kmalloc_large(...) alloc_hooks(kmalloc_large_noprof(__VA_ARGS__))599599+void *__kmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node)600600+ __assume_kmalloc_alignment __alloc_size(1);594601595595-void *kmalloc_large_node_noprof(size_t size, gfp_t flags, int node) __assume_page_alignment596596- __alloc_size(1);597597-#define kmalloc_large_node(...) alloc_hooks(kmalloc_large_node_noprof(__VA_ARGS__))602602+void *__kmalloc_cache_noprof(struct kmem_cache *s, gfp_t flags, size_t size)603603+ __assume_kmalloc_alignment __alloc_size(3);604604+605605+void *__kmalloc_cache_node_noprof(struct kmem_cache *s, gfp_t gfpflags,606606+ int node, size_t size)607607+ __assume_kmalloc_alignment __alloc_size(4);608608+609609+void *__kmalloc_large_noprof(size_t size, gfp_t flags)610610+ __assume_page_alignment __alloc_size(1);611611+612612+void *__kmalloc_large_node_noprof(size_t size, gfp_t flags, int node)613613+ __assume_page_alignment __alloc_size(1);598614599615/**600616 * kmalloc - allocate kernel memory···624604 *625605 * The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN626606 * bytes. For @size of power of two bytes, the alignment is also guaranteed627627- * to be at least to the size.607607+ * to be at least to the size. For other sizes, the alignment is guaranteed to608608+ * be at least the largest power-of-two divisor of @size.628609 *629610 * The @flags argument may be one of the GFP flags defined at630611 * include/linux/gfp_types.h and described at···675654 unsigned int index;676655677656 if (size > KMALLOC_MAX_CACHE_SIZE)678678- return kmalloc_large_noprof(size, flags);657657+ return __kmalloc_large_noprof(size, flags);679658680659 index = kmalloc_index(size);681681- return kmalloc_trace_noprof(660660+ return __kmalloc_cache_noprof(682661 kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],683662 flags, size);684663 }···686665}687666#define kmalloc(...) alloc_hooks(kmalloc_noprof(__VA_ARGS__))688667668668+#define kmem_buckets_alloc(_b, _size, _flags) \669669+ alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE))670670+671671+#define kmem_buckets_alloc_track_caller(_b, _size, _flags) \672672+ alloc_hooks(__kmalloc_node_track_caller_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE, _RET_IP_))673673+689674static __always_inline __alloc_size(1) void *kmalloc_node_noprof(size_t size, gfp_t flags, int node)690675{691676 if (__builtin_constant_p(size) && size) {692677 unsigned int index;693678694679 if (size > KMALLOC_MAX_CACHE_SIZE)695695- return kmalloc_large_node_noprof(size, flags, node);680680+ return __kmalloc_large_node_noprof(size, flags, node);696681697682 index = kmalloc_index(size);698698- return kmalloc_node_trace_noprof(683683+ return __kmalloc_cache_node_noprof(699684 kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],700685 flags, node, size);701686 }702702- return __kmalloc_node_noprof(size, flags, node);687687+ return __kmalloc_node_noprof(PASS_BUCKET_PARAMS(size, NULL), flags, node);703688}704689#define kmalloc_node(...) alloc_hooks(kmalloc_node_noprof(__VA_ARGS__))705690···756729 */757730#define kcalloc(n, size, flags) kmalloc_array(n, size, (flags) | __GFP_ZERO)758731759759-void *kmalloc_node_track_caller_noprof(size_t size, gfp_t flags, int node,760760- unsigned long caller) __alloc_size(1);732732+void *__kmalloc_node_track_caller_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node,733733+ unsigned long caller) __alloc_size(1);734734+#define kmalloc_node_track_caller_noprof(size, flags, node, caller) \735735+ __kmalloc_node_track_caller_noprof(PASS_BUCKET_PARAMS(size, NULL), flags, node, caller)761736#define kmalloc_node_track_caller(...) \762737 alloc_hooks(kmalloc_node_track_caller_noprof(__VA_ARGS__, _RET_IP_))763738···785756 return NULL;786757 if (__builtin_constant_p(n) && __builtin_constant_p(size))787758 return kmalloc_node_noprof(bytes, flags, node);788788- return __kmalloc_node_noprof(bytes, flags, node);759759+ return __kmalloc_node_noprof(PASS_BUCKET_PARAMS(bytes, NULL), flags, node);789760}790761#define kmalloc_array_node(...) alloc_hooks(kmalloc_array_node_noprof(__VA_ARGS__))791762···809780#define kzalloc(...) alloc_hooks(kzalloc_noprof(__VA_ARGS__))810781#define kzalloc_node(_size, _flags, _node) kmalloc_node(_size, (_flags)|__GFP_ZERO, _node)811782812812-extern void *kvmalloc_node_noprof(size_t size, gfp_t flags, int node) __alloc_size(1);783783+void *__kvmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node) __alloc_size(1);784784+#define kvmalloc_node_noprof(size, flags, node) \785785+ __kvmalloc_node_noprof(PASS_BUCKET_PARAMS(size, NULL), flags, node)813786#define kvmalloc_node(...) alloc_hooks(kvmalloc_node_noprof(__VA_ARGS__))814787815788#define kvmalloc(_size, _flags) kvmalloc_node(_size, _flags, NUMA_NO_NODE)···819788#define kvzalloc(_size, _flags) kvmalloc(_size, (_flags)|__GFP_ZERO)820789821790#define kvzalloc_node(_size, _flags, _node) kvmalloc_node(_size, (_flags)|__GFP_ZERO, _node)791791+#define kmem_buckets_valloc(_b, _size, _flags) \792792+ alloc_hooks(__kvmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE))822793823794static inline __alloc_size(1, 2) void *824795kvmalloc_array_node_noprof(size_t n, size_t size, gfp_t flags, int node)
···273273 sacrifices to harden the kernel slab allocator against common274274 freelist exploit methods.275275276276+config SLAB_BUCKETS277277+ bool "Support allocation from separate kmalloc buckets"278278+ depends on !SLUB_TINY279279+ default SLAB_FREELIST_HARDENED280280+ help281281+ Kernel heap attacks frequently depend on being able to create282282+ specifically-sized allocations with user-controlled contents283283+ that will be allocated into the same kmalloc bucket as a284284+ target object. To avoid sharing these allocation buckets,285285+ provide an explicitly separated set of buckets to be used for286286+ user-controlled allocations. This may very slightly increase287287+ memory fragmentation, though in practice it's only a handful288288+ of extra pages since the bulk of user-controlled allocations289289+ are relatively long-lived.290290+291291+ If unsure, say Y.292292+276293config SLUB_STATS277294 default n278295 bool "Enable performance statistics"
+6-4
mm/slab.h
···168168 */169169static inline bool slab_test_pfmemalloc(const struct slab *slab)170170{171171- return folio_test_active((struct folio *)slab_folio(slab));171171+ return folio_test_active(slab_folio(slab));172172}173173174174static inline void slab_set_pfmemalloc(struct slab *slab)···213213214214static inline int slab_order(const struct slab *slab)215215{216216- return folio_order((struct folio *)slab_folio(slab));216216+ return folio_order(slab_folio(slab));217217}218218219219static inline size_t slab_size(const struct slab *slab)···405405 * KMALLOC_MAX_CACHE_SIZE and the caller must check that.406406 */407407static inline struct kmem_cache *408408-kmalloc_slab(size_t size, gfp_t flags, unsigned long caller)408408+kmalloc_slab(size_t size, kmem_buckets *b, gfp_t flags, unsigned long caller)409409{410410 unsigned int index;411411412412+ if (!b)413413+ b = &kmalloc_caches[kmalloc_type(flags, caller)];412414 if (size <= 192)413415 index = kmalloc_size_index[size_index_elem(size)];414416 else415417 index = fls(size - 1);416418417417- return kmalloc_caches[kmalloc_type(flags, caller)][index];419419+ return (*b)[index];418420}419421420422gfp_t kmalloc_fix_flags(gfp_t flags);
+104-7
mm/slab_common.c
···392392}393393EXPORT_SYMBOL(kmem_cache_create);394394395395+static struct kmem_cache *kmem_buckets_cache __ro_after_init;396396+397397+/**398398+ * kmem_buckets_create - Create a set of caches that handle dynamic sized399399+ * allocations via kmem_buckets_alloc()400400+ * @name: A prefix string which is used in /proc/slabinfo to identify this401401+ * cache. The individual caches with have their sizes as the suffix.402402+ * @flags: SLAB flags (see kmem_cache_create() for details).403403+ * @useroffset: Starting offset within an allocation that may be copied404404+ * to/from userspace.405405+ * @usersize: How many bytes, starting at @useroffset, may be copied406406+ * to/from userspace.407407+ * @ctor: A constructor for the objects, run when new allocations are made.408408+ *409409+ * Cannot be called within an interrupt, but can be interrupted.410410+ *411411+ * Return: a pointer to the cache on success, NULL on failure. When412412+ * CONFIG_SLAB_BUCKETS is not enabled, ZERO_SIZE_PTR is returned, and413413+ * subsequent calls to kmem_buckets_alloc() will fall back to kmalloc().414414+ * (i.e. callers only need to check for NULL on failure.)415415+ */416416+kmem_buckets *kmem_buckets_create(const char *name, slab_flags_t flags,417417+ unsigned int useroffset,418418+ unsigned int usersize,419419+ void (*ctor)(void *))420420+{421421+ kmem_buckets *b;422422+ int idx;423423+424424+ /*425425+ * When the separate buckets API is not built in, just return426426+ * a non-NULL value for the kmem_buckets pointer, which will be427427+ * unused when performing allocations.428428+ */429429+ if (!IS_ENABLED(CONFIG_SLAB_BUCKETS))430430+ return ZERO_SIZE_PTR;431431+432432+ if (WARN_ON(!kmem_buckets_cache))433433+ return NULL;434434+435435+ b = kmem_cache_alloc(kmem_buckets_cache, GFP_KERNEL|__GFP_ZERO);436436+ if (WARN_ON(!b))437437+ return NULL;438438+439439+ flags |= SLAB_NO_MERGE;440440+441441+ for (idx = 0; idx < ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]); idx++) {442442+ char *short_size, *cache_name;443443+ unsigned int cache_useroffset, cache_usersize;444444+ unsigned int size;445445+446446+ if (!kmalloc_caches[KMALLOC_NORMAL][idx])447447+ continue;448448+449449+ size = kmalloc_caches[KMALLOC_NORMAL][idx]->object_size;450450+ if (!size)451451+ continue;452452+453453+ short_size = strchr(kmalloc_caches[KMALLOC_NORMAL][idx]->name, '-');454454+ if (WARN_ON(!short_size))455455+ goto fail;456456+457457+ cache_name = kasprintf(GFP_KERNEL, "%s-%s", name, short_size + 1);458458+ if (WARN_ON(!cache_name))459459+ goto fail;460460+461461+ if (useroffset >= size) {462462+ cache_useroffset = 0;463463+ cache_usersize = 0;464464+ } else {465465+ cache_useroffset = useroffset;466466+ cache_usersize = min(size - cache_useroffset, usersize);467467+ }468468+ (*b)[idx] = kmem_cache_create_usercopy(cache_name, size,469469+ 0, flags, cache_useroffset,470470+ cache_usersize, ctor);471471+ kfree(cache_name);472472+ if (WARN_ON(!(*b)[idx]))473473+ goto fail;474474+ }475475+476476+ return b;477477+478478+fail:479479+ for (idx = 0; idx < ARRAY_SIZE(kmalloc_caches[KMALLOC_NORMAL]); idx++)480480+ kmem_cache_destroy((*b)[idx]);481481+ kfree(b);482482+483483+ return NULL;484484+}485485+EXPORT_SYMBOL(kmem_buckets_create);486486+395487#ifdef SLAB_SUPPORTS_SYSFS396488/*397489 * For a given kmem_cache, kmem_cache_destroy() should only be called···709617 s->size = s->object_size = size;710618711619 /*712712- * For power of two sizes, guarantee natural alignment for kmalloc713713- * caches, regardless of SL*B debugging options.620620+ * kmalloc caches guarantee alignment of at least the largest621621+ * power-of-two divisor of the size. For power-of-two sizes,622622+ * it is the size itself.714623 */715715- if (is_power_of_2(size))716716- align = max(align, size);624624+ if (flags & SLAB_KMALLOC)625625+ align = max(align, 1U << (ffs(size) - 1));717626 s->align = calculate_alignment(flags, align, size);718627719628#ifdef CONFIG_HARDENED_USERCOPY···746653 return s;747654}748655749749-struct kmem_cache *750750-kmalloc_caches[NR_KMALLOC_TYPES][KMALLOC_SHIFT_HIGH + 1] __ro_after_init =656656+kmem_buckets kmalloc_caches[NR_KMALLOC_TYPES] __ro_after_init =751657{ /* initialization for https://llvm.org/pr42570 */ };752658EXPORT_SYMBOL(kmalloc_caches);753659···795703 * The flags don't matter since size_index is common to all.796704 * Neither does the caller for just getting ->object_size.797705 */798798- return kmalloc_slab(size, GFP_KERNEL, 0)->object_size;706706+ return kmalloc_slab(size, NULL, GFP_KERNEL, 0)->object_size;799707 }800708801709 /* Above the smaller buckets, size is a multiple of page size. */···10249321025933 /* Kmalloc array is now usable */1026934 slab_state = UP;935935+936936+ if (IS_ENABLED(CONFIG_SLAB_BUCKETS))937937+ kmem_buckets_cache = kmem_cache_create("kmalloc_buckets",938938+ sizeof(kmem_buckets),939939+ 0, SLAB_NO_MERGE, NULL);1027940}10289411029942/**
+75-56
mm/slub.c
···788788 kunit_put_resource(resource);789789 return true;790790}791791+792792+static bool slab_in_kunit_test(void)793793+{794794+ struct kunit_resource *resource;795795+796796+ if (!kunit_get_current_test())797797+ return false;798798+799799+ resource = kunit_find_named_resource(current->kunit_test, "slab_errors");800800+ if (!resource)801801+ return false;802802+803803+ kunit_put_resource(resource);804804+ return true;805805+}791806#else792807static inline bool slab_add_kunit_errors(void) { return false; }808808+static inline bool slab_in_kunit_test(void) { return false; }793809#endif794810795811static inline unsigned int size_from_object(struct kmem_cache *s)···978962979963static void print_slab_info(const struct slab *slab)980964{981981- struct folio *folio = (struct folio *)slab_folio(slab);982982-983965 pr_err("Slab 0x%p objects=%u used=%u fp=0x%p flags=%pGp\n",984966 slab, slab->objects, slab->inuse, slab->freelist,985985- folio_flags(folio, 0));967967+ &slab->__page_flags);986968}987969988970/*···12061192 pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",12071193 fault, end - 1, fault - addr,12081194 fault[0], value);12091209- print_trailer(s, slab, object);12101210- add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);1211119512121196skip_bug_print:12131197 restore_bytes(s, what, value, fault, end);···12281216 * Padding is extended by another word if Redzoning is enabled and12291217 * object_size == inuse.12301218 *12311231- * We fill with 0xbb (RED_INACTIVE) for inactive objects and with12321232- * 0xcc (RED_ACTIVE) for objects in use.12191219+ * We fill with 0xbb (SLUB_RED_INACTIVE) for inactive objects and with12201220+ * 0xcc (SLUB_RED_ACTIVE) for objects in use.12331221 *12341222 * object + s->inuse12351223 * Meta data starts here.···13141302 u8 *p = object;13151303 u8 *endobject = object + s->object_size;13161304 unsigned int orig_size, kasan_meta_size;13051305+ int ret = 1;1317130613181307 if (s->flags & SLAB_RED_ZONE) {13191308 if (!check_bytes_and_report(s, slab, object, "Left Redzone",13201309 object - s->red_left_pad, val, s->red_left_pad))13211321- return 0;13101310+ ret = 0;1322131113231312 if (!check_bytes_and_report(s, slab, object, "Right Redzone",13241313 endobject, val, s->inuse - s->object_size))13251325- return 0;13141314+ ret = 0;1326131513271316 if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {13281317 orig_size = get_orig_size(s, object);···13321319 !check_bytes_and_report(s, slab, object,13331320 "kmalloc Redzone", p + orig_size,13341321 val, s->object_size - orig_size)) {13351335- return 0;13221322+ ret = 0;13361323 }13371324 }13381325 } else {13391326 if ((s->flags & SLAB_POISON) && s->object_size < s->inuse) {13401340- check_bytes_and_report(s, slab, p, "Alignment padding",13271327+ if (!check_bytes_and_report(s, slab, p, "Alignment padding",13411328 endobject, POISON_INUSE,13421342- s->inuse - s->object_size);13291329+ s->inuse - s->object_size))13301330+ ret = 0;13431331 }13441332 }13451333···13561342 !check_bytes_and_report(s, slab, p, "Poison",13571343 p + kasan_meta_size, POISON_FREE,13581344 s->object_size - kasan_meta_size - 1))13591359- return 0;13451345+ ret = 0;13601346 if (kasan_meta_size < s->object_size &&13611347 !check_bytes_and_report(s, slab, p, "End Poison",13621348 p + s->object_size - 1, POISON_END, 1))13631363- return 0;13491349+ ret = 0;13641350 }13651351 /*13661352 * check_pad_bytes cleans up on its own.13671353 */13681368- check_pad_bytes(s, slab, p);13541354+ if (!check_pad_bytes(s, slab, p))13551355+ ret = 0;13691356 }1370135713711371- if (!freeptr_outside_object(s) && val == SLUB_RED_ACTIVE)13721372- /*13731373- * Object and freepointer overlap. Cannot check13741374- * freepointer while object is allocated.13751375- */13761376- return 1;13771377-13781378- /* Check free pointer validity */13791379- if (!check_valid_pointer(s, slab, get_freepointer(s, p))) {13581358+ /*13591359+ * Cannot check freepointer while object is allocated if13601360+ * object and freepointer overlap.13611361+ */13621362+ if ((freeptr_outside_object(s) || val != SLUB_RED_ACTIVE) &&13631363+ !check_valid_pointer(s, slab, get_freepointer(s, p))) {13801364 object_err(s, slab, p, "Freepointer corrupt");13811365 /*13821366 * No choice but to zap it and thus lose the remainder···13821370 * another error because the object count is now wrong.13831371 */13841372 set_freepointer(s, p, NULL);13851385- return 0;13731373+ ret = 0;13861374 }13871387- return 1;13751375+13761376+ if (!ret && !slab_in_kunit_test()) {13771377+ print_trailer(s, slab, object);13781378+ add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);13791379+ }13801380+13811381+ return ret;13881382}1389138313901384static int check_slab(struct kmem_cache *s, struct slab *slab)···25722554 */25732555static inline bool slab_test_node_partial(const struct slab *slab)25742556{25752575- return folio_test_workingset((struct folio *)slab_folio(slab));25572557+ return folio_test_workingset(slab_folio(slab));25762558}2577255925782560static inline void slab_set_node_partial(struct slab *slab)···40814063 * directly to the page allocator. We use __GFP_COMP, because we will need to40824064 * know the allocation order to free the pages properly in kfree.40834065 */40844084-static void *__kmalloc_large_node(size_t size, gfp_t flags, int node)40664066+static void *___kmalloc_large_node(size_t size, gfp_t flags, int node)40854067{40864068 struct folio *folio;40874069 void *ptr = NULL;···41064088 return ptr;41074089}4108409041094109-void *kmalloc_large_noprof(size_t size, gfp_t flags)40914091+void *__kmalloc_large_noprof(size_t size, gfp_t flags)41104092{41114111- void *ret = __kmalloc_large_node(size, flags, NUMA_NO_NODE);40934093+ void *ret = ___kmalloc_large_node(size, flags, NUMA_NO_NODE);4112409441134095 trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << get_order(size),41144096 flags, NUMA_NO_NODE);41154097 return ret;41164098}41174117-EXPORT_SYMBOL(kmalloc_large_noprof);40994099+EXPORT_SYMBOL(__kmalloc_large_noprof);4118410041194119-void *kmalloc_large_node_noprof(size_t size, gfp_t flags, int node)41014101+void *__kmalloc_large_node_noprof(size_t size, gfp_t flags, int node)41204102{41214121- void *ret = __kmalloc_large_node(size, flags, node);41034103+ void *ret = ___kmalloc_large_node(size, flags, node);4122410441234105 trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << get_order(size),41244106 flags, node);41254107 return ret;41264108}41274127-EXPORT_SYMBOL(kmalloc_large_node_noprof);41094109+EXPORT_SYMBOL(__kmalloc_large_node_noprof);4128411041294111static __always_inline41304130-void *__do_kmalloc_node(size_t size, gfp_t flags, int node,41124112+void *__do_kmalloc_node(size_t size, kmem_buckets *b, gfp_t flags, int node,41314113 unsigned long caller)41324114{41334115 struct kmem_cache *s;41344116 void *ret;4135411741364118 if (unlikely(size > KMALLOC_MAX_CACHE_SIZE)) {41374137- ret = __kmalloc_large_node(size, flags, node);41194119+ ret = __kmalloc_large_node_noprof(size, flags, node);41384120 trace_kmalloc(caller, ret, size,41394121 PAGE_SIZE << get_order(size), flags, node);41404122 return ret;···41434125 if (unlikely(!size))41444126 return ZERO_SIZE_PTR;4145412741464146- s = kmalloc_slab(size, flags, caller);41284128+ s = kmalloc_slab(size, b, flags, caller);4147412941484130 ret = slab_alloc_node(s, NULL, flags, node, caller, size);41494131 ret = kasan_kmalloc(s, ret, size, flags);41504132 trace_kmalloc(caller, ret, size, s->size, flags, node);41514133 return ret;41524134}41534153-41544154-void *__kmalloc_node_noprof(size_t size, gfp_t flags, int node)41354135+void *__kmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node)41554136{41564156- return __do_kmalloc_node(size, flags, node, _RET_IP_);41374137+ return __do_kmalloc_node(size, PASS_BUCKET_PARAM(b), flags, node, _RET_IP_);41574138}41584139EXPORT_SYMBOL(__kmalloc_node_noprof);4159414041604141void *__kmalloc_noprof(size_t size, gfp_t flags)41614142{41624162- return __do_kmalloc_node(size, flags, NUMA_NO_NODE, _RET_IP_);41434143+ return __do_kmalloc_node(size, NULL, flags, NUMA_NO_NODE, _RET_IP_);41634144}41644145EXPORT_SYMBOL(__kmalloc_noprof);4165414641664166-void *kmalloc_node_track_caller_noprof(size_t size, gfp_t flags,41674167- int node, unsigned long caller)41474147+void *__kmalloc_node_track_caller_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags,41484148+ int node, unsigned long caller)41684149{41694169- return __do_kmalloc_node(size, flags, node, caller);41704170-}41714171-EXPORT_SYMBOL(kmalloc_node_track_caller_noprof);41504150+ return __do_kmalloc_node(size, PASS_BUCKET_PARAM(b), flags, node, caller);4172415141734173-void *kmalloc_trace_noprof(struct kmem_cache *s, gfp_t gfpflags, size_t size)41524152+}41534153+EXPORT_SYMBOL(__kmalloc_node_track_caller_noprof);41544154+41554155+void *__kmalloc_cache_noprof(struct kmem_cache *s, gfp_t gfpflags, size_t size)41744156{41754157 void *ret = slab_alloc_node(s, NULL, gfpflags, NUMA_NO_NODE,41764158 _RET_IP_, size);···41804162 ret = kasan_kmalloc(s, ret, size, gfpflags);41814163 return ret;41824164}41834183-EXPORT_SYMBOL(kmalloc_trace_noprof);41654165+EXPORT_SYMBOL(__kmalloc_cache_noprof);4184416641854185-void *kmalloc_node_trace_noprof(struct kmem_cache *s, gfp_t gfpflags,41864186- int node, size_t size)41674167+void *__kmalloc_cache_node_noprof(struct kmem_cache *s, gfp_t gfpflags,41684168+ int node, size_t size)41874169{41884170 void *ret = slab_alloc_node(s, NULL, gfpflags, node, _RET_IP_, size);41894171···41924174 ret = kasan_kmalloc(s, ret, size, gfpflags);41934175 return ret;41944176}41954195-EXPORT_SYMBOL(kmalloc_node_trace_noprof);41774177+EXPORT_SYMBOL(__kmalloc_cache_node_noprof);4196417841974179static noinline void free_to_partial_list(41984180 struct kmem_cache *s, struct slab *slab,···51775159 */51785160 s->inuse = size;5179516151805180- if (slub_debug_orig_size(s) ||51815181- (flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)) ||51825182- ((flags & SLAB_RED_ZONE) && s->object_size < sizeof(void *)) ||51835183- s->ctor) {51625162+ if ((flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)) || s->ctor ||51635163+ ((flags & SLAB_RED_ZONE) &&51645164+ (s->object_size < sizeof(void *) || slub_debug_orig_size(s)))) {51845165 /*51855166 * Relocate free pointer after the object if it is not51865167 * permitted to overwrite the first word of the object on···51875170 *51885171 * This is the case if we do RCU, have a constructor or51895172 * destructor, are poisoning the objects, or are51905190- * redzoning an object smaller than sizeof(void *).51735173+ * redzoning an object smaller than sizeof(void *) or are51745174+ * redzoning an object with slub_debug_orig_size() enabled,51755175+ * in which case the right redzone may be extended.51915176 *51925177 * The assumption that s->offset >= s->inuse means free51935178 * pointer is outside of the object is used in the
+17-6
mm/util.c
···198198}199199EXPORT_SYMBOL(kmemdup_nul);200200201201+static kmem_buckets *user_buckets __ro_after_init;202202+203203+static int __init init_user_buckets(void)204204+{205205+ user_buckets = kmem_buckets_create("memdup_user", 0, 0, INT_MAX, NULL);206206+207207+ return 0;208208+}209209+subsys_initcall(init_user_buckets);210210+201211/**202212 * memdup_user - duplicate memory region from user space203213 *···221211{222212 void *p;223213224224- p = kmalloc_track_caller(len, GFP_USER | __GFP_NOWARN);214214+ p = kmem_buckets_alloc_track_caller(user_buckets, len, GFP_USER | __GFP_NOWARN);225215 if (!p)226216 return ERR_PTR(-ENOMEM);227217···247237{248238 void *p;249239250250- p = kvmalloc(len, GFP_USER);240240+ p = kmem_buckets_valloc(user_buckets, len, GFP_USER);251241 if (!p)252242 return ERR_PTR(-ENOMEM);253243···604594EXPORT_SYMBOL(vm_mmap);605595606596/**607607- * kvmalloc_node - attempt to allocate physically contiguous memory, but upon597597+ * __kvmalloc_node - attempt to allocate physically contiguous memory, but upon608598 * failure, fall back to non-contiguous (vmalloc) allocation.609599 * @size: size of the request.600600+ * @b: which set of kmalloc buckets to allocate from.610601 * @flags: gfp mask for the allocation - must be compatible (superset) with GFP_KERNEL.611602 * @node: numa node to allocate from612603 *···620609 *621610 * Return: pointer to the allocated memory of %NULL in case of failure622611 */623623-void *kvmalloc_node_noprof(size_t size, gfp_t flags, int node)612612+void *__kvmalloc_node_noprof(DECL_BUCKET_PARAMS(size, b), gfp_t flags, int node)624613{625614 gfp_t kmalloc_flags = flags;626615 void *ret;···642631 kmalloc_flags &= ~__GFP_NOFAIL;643632 }644633645645- ret = kmalloc_node_noprof(size, kmalloc_flags, node);634634+ ret = __kmalloc_node_noprof(PASS_BUCKET_PARAMS(size, b), kmalloc_flags, node);646635647636 /*648637 * It doesn't really make sense to fallback to vmalloc for sub page···671660 flags, PAGE_KERNEL, VM_ALLOW_HUGE_VMAP,672661 node, __builtin_return_address(0));673662}674674-EXPORT_SYMBOL(kvmalloc_node_noprof);663663+EXPORT_SYMBOL(__kvmalloc_node_noprof);675664676665/**677666 * kvfree() - Free memory.
+6-13
rust/kernel/alloc/allocator.rs
···1818 // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first.1919 let layout = new_layout.pad_to_align();20202121- let mut size = layout.size();2222-2323- if layout.align() > bindings::ARCH_SLAB_MINALIGN {2424- // The alignment requirement exceeds the slab guarantee, thus try to enlarge the size2525- // to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for2626- // more information).2727- //2828- // Note that `layout.size()` (after padding) is guaranteed to be a multiple of2929- // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee.3030- size = size.next_power_of_two();3131- }2121+ // Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()`2222+ // which together with the slab guarantees means the `krealloc` will return a properly aligned2323+ // object (see comments in `kmalloc()` for more information).2424+ let size = layout.size();32253326 // SAFETY:3427 // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the3528 // function safety requirement.3636- // - `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero3737- // according to the function safety requirement) or a result from `next_power_of_two()`.2929+ // - `size` is greater than 0 since it's from `layout.size()` (which cannot be zero according3030+ // to the function safety requirement)3831 unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags.0) as *mut u8 }3932}4033
···4747 * Magic nums for obj red zoning.4848 * Placed in the first word before and the first word after an obj.4949 */5050-#define RED_INACTIVE 0x09F911029D74E35BULL /* when obj is inactive */5151-#define RED_ACTIVE 0xD84156C5635688C0ULL /* when obj is active */5252-5353-#define SLUB_RED_INACTIVE 0xbb5454-#define SLUB_RED_ACTIVE 0xcc5050+#define SLUB_RED_INACTIVE 0xbb /* when obj is inactive */5151+#define SLUB_RED_ACTIVE 0xcc /* when obj is active */55525653/* ...and for poisoning */5754#define POISON_INUSE 0x5a /* for use-uninitialised poisoning */