Merge tag 'for-linus-20190524' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / arch / arm64 / kernel / module.c
index f713e2f..f32359c 100644 (file)
@@ -56,7 +56,7 @@ void *module_alloc(unsigned long size)
                 * can simply omit this fallback in that case.
                 */
                p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
-                               module_alloc_base + SZ_4G, GFP_KERNEL,
+                               module_alloc_base + SZ_2G, GFP_KERNEL,
                                PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
                                __builtin_return_address(0));
 
@@ -96,15 +96,27 @@ static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
 {
        s64 sval = do_reloc(op, place, val);
 
+       /*
+        * The ELF psABI for AArch64 documents the 16-bit and 32-bit place
+        * relative relocations as having a range of [-2^15, 2^16) or
+        * [-2^31, 2^32), respectively. However, in order to be able to detect
+        * overflows reliably, we have to choose whether we interpret such
+        * quantities as signed or as unsigned, and stick with it.
+        * The way we organize our address space requires a signed
+        * interpretation of 32-bit relative references, so let's use that
+        * for all R_AARCH64_PRELxx relocations. This means our upper
+        * bound for overflow detection should be Sxx_MAX rather than Uxx_MAX.
+        */
+
        switch (len) {
        case 16:
                *(s16 *)place = sval;
-               if (sval < S16_MIN || sval > U16_MAX)
+               if (sval < S16_MIN || sval > S16_MAX)
                        return -ERANGE;
                break;
        case 32:
                *(s32 *)place = sval;
-               if (sval < S32_MIN || sval > U32_MAX)
+               if (sval < S32_MIN || sval > S32_MAX)
                        return -ERANGE;
                break;
        case 64: