Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * This is for all the tests relating directly to heap memory, including
0004  * page allocation and slab allocations.
0005  */
0006 #include "lkdtm.h"
0007 #include <linux/slab.h>
0008 #include <linux/vmalloc.h>
0009 #include <linux/sched.h>
0010 
0011 static struct kmem_cache *double_free_cache;
0012 static struct kmem_cache *a_cache;
0013 static struct kmem_cache *b_cache;
0014 
0015 /*
0016  * Using volatile here means the compiler cannot ever make assumptions
0017  * about this value. This means compile-time length checks involving
0018  * this variable cannot be performed; only run-time checks.
0019  */
0020 static volatile int __offset = 1;
0021 
0022 /*
0023  * If there aren't guard pages, it's likely that a consecutive allocation will
0024  * let us overflow into the second allocation without overwriting something real.
0025  *
0026  * This should always be caught because there is an unconditional unmapped
0027  * page after vmap allocations.
0028  */
0029 static void lkdtm_VMALLOC_LINEAR_OVERFLOW(void)
0030 {
0031     char *one, *two;
0032 
0033     one = vzalloc(PAGE_SIZE);
0034     two = vzalloc(PAGE_SIZE);
0035 
0036     pr_info("Attempting vmalloc linear overflow ...\n");
0037     memset(one, 0xAA, PAGE_SIZE + __offset);
0038 
0039     vfree(two);
0040     vfree(one);
0041 }
0042 
0043 /*
0044  * This tries to stay within the next largest power-of-2 kmalloc cache
0045  * to avoid actually overwriting anything important if it's not detected
0046  * correctly.
0047  *
0048  * This should get caught by either memory tagging, KASan, or by using
0049  * CONFIG_SLUB_DEBUG=y and slub_debug=ZF (or CONFIG_SLUB_DEBUG_ON=y).
0050  */
0051 static void lkdtm_SLAB_LINEAR_OVERFLOW(void)
0052 {
0053     size_t len = 1020;
0054     u32 *data = kmalloc(len, GFP_KERNEL);
0055     if (!data)
0056         return;
0057 
0058     pr_info("Attempting slab linear overflow ...\n");
0059     OPTIMIZER_HIDE_VAR(data);
0060     data[1024 / sizeof(u32)] = 0x12345678;
0061     kfree(data);
0062 }
0063 
0064 static void lkdtm_WRITE_AFTER_FREE(void)
0065 {
0066     int *base, *again;
0067     size_t len = 1024;
0068     /*
0069      * The slub allocator uses the first word to store the free
0070      * pointer in some configurations. Use the middle of the
0071      * allocation to avoid running into the freelist
0072      */
0073     size_t offset = (len / sizeof(*base)) / 2;
0074 
0075     base = kmalloc(len, GFP_KERNEL);
0076     if (!base)
0077         return;
0078     pr_info("Allocated memory %p-%p\n", base, &base[offset * 2]);
0079     pr_info("Attempting bad write to freed memory at %p\n",
0080         &base[offset]);
0081     kfree(base);
0082     base[offset] = 0x0abcdef0;
0083     /* Attempt to notice the overwrite. */
0084     again = kmalloc(len, GFP_KERNEL);
0085     kfree(again);
0086     if (again != base)
0087         pr_info("Hmm, didn't get the same memory range.\n");
0088 }
0089 
0090 static void lkdtm_READ_AFTER_FREE(void)
0091 {
0092     int *base, *val, saw;
0093     size_t len = 1024;
0094     /*
0095      * The slub allocator will use the either the first word or
0096      * the middle of the allocation to store the free pointer,
0097      * depending on configurations. Store in the second word to
0098      * avoid running into the freelist.
0099      */
0100     size_t offset = sizeof(*base);
0101 
0102     base = kmalloc(len, GFP_KERNEL);
0103     if (!base) {
0104         pr_info("Unable to allocate base memory.\n");
0105         return;
0106     }
0107 
0108     val = kmalloc(len, GFP_KERNEL);
0109     if (!val) {
0110         pr_info("Unable to allocate val memory.\n");
0111         kfree(base);
0112         return;
0113     }
0114 
0115     *val = 0x12345678;
0116     base[offset] = *val;
0117     pr_info("Value in memory before free: %x\n", base[offset]);
0118 
0119     kfree(base);
0120 
0121     pr_info("Attempting bad read from freed memory\n");
0122     saw = base[offset];
0123     if (saw != *val) {
0124         /* Good! Poisoning happened, so declare a win. */
0125         pr_info("Memory correctly poisoned (%x)\n", saw);
0126     } else {
0127         pr_err("FAIL: Memory was not poisoned!\n");
0128         pr_expected_config_param(CONFIG_INIT_ON_FREE_DEFAULT_ON, "init_on_free");
0129     }
0130 
0131     kfree(val);
0132 }
0133 
0134 static void lkdtm_WRITE_BUDDY_AFTER_FREE(void)
0135 {
0136     unsigned long p = __get_free_page(GFP_KERNEL);
0137     if (!p) {
0138         pr_info("Unable to allocate free page\n");
0139         return;
0140     }
0141 
0142     pr_info("Writing to the buddy page before free\n");
0143     memset((void *)p, 0x3, PAGE_SIZE);
0144     free_page(p);
0145     schedule();
0146     pr_info("Attempting bad write to the buddy page after free\n");
0147     memset((void *)p, 0x78, PAGE_SIZE);
0148     /* Attempt to notice the overwrite. */
0149     p = __get_free_page(GFP_KERNEL);
0150     free_page(p);
0151     schedule();
0152 }
0153 
0154 static void lkdtm_READ_BUDDY_AFTER_FREE(void)
0155 {
0156     unsigned long p = __get_free_page(GFP_KERNEL);
0157     int saw, *val;
0158     int *base;
0159 
0160     if (!p) {
0161         pr_info("Unable to allocate free page\n");
0162         return;
0163     }
0164 
0165     val = kmalloc(1024, GFP_KERNEL);
0166     if (!val) {
0167         pr_info("Unable to allocate val memory.\n");
0168         free_page(p);
0169         return;
0170     }
0171 
0172     base = (int *)p;
0173 
0174     *val = 0x12345678;
0175     base[0] = *val;
0176     pr_info("Value in memory before free: %x\n", base[0]);
0177     free_page(p);
0178     pr_info("Attempting to read from freed memory\n");
0179     saw = base[0];
0180     if (saw != *val) {
0181         /* Good! Poisoning happened, so declare a win. */
0182         pr_info("Memory correctly poisoned (%x)\n", saw);
0183     } else {
0184         pr_err("FAIL: Buddy page was not poisoned!\n");
0185         pr_expected_config_param(CONFIG_INIT_ON_FREE_DEFAULT_ON, "init_on_free");
0186     }
0187 
0188     kfree(val);
0189 }
0190 
0191 static void lkdtm_SLAB_INIT_ON_ALLOC(void)
0192 {
0193     u8 *first;
0194     u8 *val;
0195 
0196     first = kmalloc(512, GFP_KERNEL);
0197     if (!first) {
0198         pr_info("Unable to allocate 512 bytes the first time.\n");
0199         return;
0200     }
0201 
0202     memset(first, 0xAB, 512);
0203     kfree(first);
0204 
0205     val = kmalloc(512, GFP_KERNEL);
0206     if (!val) {
0207         pr_info("Unable to allocate 512 bytes the second time.\n");
0208         return;
0209     }
0210     if (val != first) {
0211         pr_warn("Reallocation missed clobbered memory.\n");
0212     }
0213 
0214     if (memchr(val, 0xAB, 512) == NULL) {
0215         pr_info("Memory appears initialized (%x, no earlier values)\n", *val);
0216     } else {
0217         pr_err("FAIL: Slab was not initialized\n");
0218         pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc");
0219     }
0220     kfree(val);
0221 }
0222 
0223 static void lkdtm_BUDDY_INIT_ON_ALLOC(void)
0224 {
0225     u8 *first;
0226     u8 *val;
0227 
0228     first = (u8 *)__get_free_page(GFP_KERNEL);
0229     if (!first) {
0230         pr_info("Unable to allocate first free page\n");
0231         return;
0232     }
0233 
0234     memset(first, 0xAB, PAGE_SIZE);
0235     free_page((unsigned long)first);
0236 
0237     val = (u8 *)__get_free_page(GFP_KERNEL);
0238     if (!val) {
0239         pr_info("Unable to allocate second free page\n");
0240         return;
0241     }
0242 
0243     if (val != first) {
0244         pr_warn("Reallocation missed clobbered memory.\n");
0245     }
0246 
0247     if (memchr(val, 0xAB, PAGE_SIZE) == NULL) {
0248         pr_info("Memory appears initialized (%x, no earlier values)\n", *val);
0249     } else {
0250         pr_err("FAIL: Slab was not initialized\n");
0251         pr_expected_config_param(CONFIG_INIT_ON_ALLOC_DEFAULT_ON, "init_on_alloc");
0252     }
0253     free_page((unsigned long)val);
0254 }
0255 
0256 static void lkdtm_SLAB_FREE_DOUBLE(void)
0257 {
0258     int *val;
0259 
0260     val = kmem_cache_alloc(double_free_cache, GFP_KERNEL);
0261     if (!val) {
0262         pr_info("Unable to allocate double_free_cache memory.\n");
0263         return;
0264     }
0265 
0266     /* Just make sure we got real memory. */
0267     *val = 0x12345678;
0268     pr_info("Attempting double slab free ...\n");
0269     kmem_cache_free(double_free_cache, val);
0270     kmem_cache_free(double_free_cache, val);
0271 }
0272 
0273 static void lkdtm_SLAB_FREE_CROSS(void)
0274 {
0275     int *val;
0276 
0277     val = kmem_cache_alloc(a_cache, GFP_KERNEL);
0278     if (!val) {
0279         pr_info("Unable to allocate a_cache memory.\n");
0280         return;
0281     }
0282 
0283     /* Just make sure we got real memory. */
0284     *val = 0x12345679;
0285     pr_info("Attempting cross-cache slab free ...\n");
0286     kmem_cache_free(b_cache, val);
0287 }
0288 
0289 static void lkdtm_SLAB_FREE_PAGE(void)
0290 {
0291     unsigned long p = __get_free_page(GFP_KERNEL);
0292 
0293     pr_info("Attempting non-Slab slab free ...\n");
0294     kmem_cache_free(NULL, (void *)p);
0295     free_page(p);
0296 }
0297 
0298 /*
0299  * We have constructors to keep the caches distinctly separated without
0300  * needing to boot with "slab_nomerge".
0301  */
0302 static void ctor_double_free(void *region)
0303 { }
0304 static void ctor_a(void *region)
0305 { }
0306 static void ctor_b(void *region)
0307 { }
0308 
0309 void __init lkdtm_heap_init(void)
0310 {
0311     double_free_cache = kmem_cache_create("lkdtm-heap-double_free",
0312                           64, 0, 0, ctor_double_free);
0313     a_cache = kmem_cache_create("lkdtm-heap-a", 64, 0, 0, ctor_a);
0314     b_cache = kmem_cache_create("lkdtm-heap-b", 64, 0, 0, ctor_b);
0315 }
0316 
0317 void __exit lkdtm_heap_exit(void)
0318 {
0319     kmem_cache_destroy(double_free_cache);
0320     kmem_cache_destroy(a_cache);
0321     kmem_cache_destroy(b_cache);
0322 }
0323 
0324 static struct crashtype crashtypes[] = {
0325     CRASHTYPE(SLAB_LINEAR_OVERFLOW),
0326     CRASHTYPE(VMALLOC_LINEAR_OVERFLOW),
0327     CRASHTYPE(WRITE_AFTER_FREE),
0328     CRASHTYPE(READ_AFTER_FREE),
0329     CRASHTYPE(WRITE_BUDDY_AFTER_FREE),
0330     CRASHTYPE(READ_BUDDY_AFTER_FREE),
0331     CRASHTYPE(SLAB_INIT_ON_ALLOC),
0332     CRASHTYPE(BUDDY_INIT_ON_ALLOC),
0333     CRASHTYPE(SLAB_FREE_DOUBLE),
0334     CRASHTYPE(SLAB_FREE_CROSS),
0335     CRASHTYPE(SLAB_FREE_PAGE),
0336 };
0337 
0338 struct crashtype_category heap_crashtypes = {
0339     .crashtypes = crashtypes,
0340     .len        = ARRAY_SIZE(crashtypes),
0341 };