|
@@ -172,19 +172,27 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|
|
case R_X86_64_NONE:
|
|
|
break;
|
|
|
case R_X86_64_64:
|
|
|
+ if (*(u64 *)loc != 0)
|
|
|
+ goto invalid_relocation;
|
|
|
*(u64 *)loc = val;
|
|
|
break;
|
|
|
case R_X86_64_32:
|
|
|
+ if (*(u32 *)loc != 0)
|
|
|
+ goto invalid_relocation;
|
|
|
*(u32 *)loc = val;
|
|
|
if (val != *(u32 *)loc)
|
|
|
goto overflow;
|
|
|
break;
|
|
|
case R_X86_64_32S:
|
|
|
+ if (*(s32 *)loc != 0)
|
|
|
+ goto invalid_relocation;
|
|
|
*(s32 *)loc = val;
|
|
|
if ((s64)val != *(s32 *)loc)
|
|
|
goto overflow;
|
|
|
break;
|
|
|
case R_X86_64_PC32:
|
|
|
+ if (*(u32 *)loc != 0)
|
|
|
+ goto invalid_relocation;
|
|
|
val -= (u64)loc;
|
|
|
*(u32 *)loc = val;
|
|
|
#if 0
|
|
@@ -200,6 +208,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|
|
}
|
|
|
return 0;
|
|
|
|
|
|
+invalid_relocation:
|
|
|
+ pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n",
|
|
|
+ (int)ELF64_R_TYPE(rel[i].r_info), loc, val);
|
|
|
+ return -ENOEXEC;
|
|
|
+
|
|
|
overflow:
|
|
|
pr_err("overflow in relocation type %d val %Lx\n",
|
|
|
(int)ELF64_R_TYPE(rel[i].r_info), val);
|