Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so/arch/sparc64 Fix a few bounds and instruct...



details:   https://anonhg.NetBSD.org/src/rev/05f07c67cc65
branches:  trunk
changeset: 346039:05f07c67cc65
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Jun 20 08:12:25 2016 +0000

description:
Fix a few bounds and instruction sequences generated in the PLT; exercised
by ASLR and verified to work with the aslr fixed random debug sysctls.

diffstat:

 libexec/ld.elf_so/arch/sparc64/mdreloc.c |  48 ++++++++++++++++++--------------
 1 files changed, 27 insertions(+), 21 deletions(-)

diffs (117 lines):

diff -r fc5d4b90da87 -r 05f07c67cc65 libexec/ld.elf_so/arch/sparc64/mdreloc.c
--- a/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Mon Jun 20 08:08:13 2016 +0000
+++ b/libexec/ld.elf_so/arch/sparc64/mdreloc.c  Mon Jun 20 08:12:25 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mdreloc.c,v 1.57 2014/08/25 20:40:53 joerg Exp $       */
+/*     $NetBSD: mdreloc.c,v 1.58 2016/06/20 08:12:25 martin Exp $      */
 
 /*-
  * Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: mdreloc.c,v 1.57 2014/08/25 20:40:53 joerg Exp $");
+__RCSID("$NetBSD: mdreloc.c,v 1.58 2016/06/20 08:12:25 martin Exp $");
 #endif /* not lint */
 
 #include <errno.h>
@@ -202,6 +202,7 @@
 #define        MOV17   0x9e106000      /*      or      %g1, 0, %o7 */
 #define        CALL    0x40000000      /*      call    0 */
 #define        SLLX    0x83287000      /*      sllx    %g1, 0, %g1 */
+#define        NEG     0x82200001      /*      neg     %g1 */
 #define        SETHIG5 0x0b000000      /*      sethi   %hi(0), %g5 */
 #define        ORG5    0x82104005      /*      or      %g1, %g5, %g1 */
 
@@ -662,7 +663,7 @@
                 *      nop
                 *
                 */
-               where[1] = BAA | ((offset >> 2) & 0x3fffff);
+               where[1] = BAA | ((offset >> 2) & 0x7ffff);
                __asm volatile("iflush %0+4" : : "r" (where));
        } else if (value < (1L<<32)) {
                /* 
@@ -708,7 +709,8 @@
                __asm volatile("iflush %0+8" : : "r" (where));
                __asm volatile("iflush %0+4" : : "r" (where));
 
-       } else if (offset <= (1L<<32) && (Elf_SOff)offset >= -((1L<<32) - 4)) {
+       } else if ((offset+8) <= (1L<<31) &&
+           (Elf_SOff)(offset+8) >= -((1L<<31) - 4)) {
                /* 
                 * We're within 32-bits -- we can use a direct call insn 
                 *
@@ -724,14 +726,15 @@
                 *      nop
                 *
                 */
+               offset += 8;    /* call is at where[2], 8 byte further */
                where[3] = MOV17;
-               where[2] = CALL   | ((offset >> 4) & 0x3fffffff);
+               where[2] = CALL   | ((-offset >> 2) & 0x3fffffff);
                where[1] = MOV71;
                __asm volatile("iflush %0+12" : : "r" (where));
                __asm volatile("iflush %0+8" : : "r" (where));
                __asm volatile("iflush %0+4" : : "r" (where));
 
-       } else if (offset < (1L<<44)) {
+       } else if ((Elf_SOff)value > 0 && value < (1L<<44)) {
                /* 
                 * We're within 44 bits.  We can generate this pattern:
                 *
@@ -747,35 +750,38 @@
                 *      nop
                 *
                 */
-               where[4] = JMP   | LOVAL(offset, 0);
+               where[4] = JMP   | LOVAL(value, 0);
                where[3] = SLLX  | 12;
-               where[2] = OR    | (((offset) >> 12) & 0x00001fff);
-               where[1] = SETHI | HIVAL(offset, 22);
+               where[2] = OR    | (((value) >> 12) & 0x00001fff);
+               where[1] = SETHI | HIVAL(value, 22);
                __asm volatile("iflush %0+16" : : "r" (where));
                __asm volatile("iflush %0+12" : : "r" (where));
                __asm volatile("iflush %0+8" : : "r" (where));
                __asm volatile("iflush %0+4" : : "r" (where));
 
-       } else if ((Elf_SOff)offset < 0 && (Elf_SOff)offset > -(1L<<44)) {
-               /* 
-                * We're within 44 bits.  We can generate this pattern:
+       } else if ((Elf_SOff)value < 0 && (Elf_SOff)value > -(1L<<44)) {
+               /*
+                *  We're within 44 bits.  We can generate this pattern:
                 *
                 * The resulting code in the jump slot is:
                 *
                 *      sethi   %hi(. - .PLT0), %g1
-                *      sethi   %h44(-addr), %g1
-                *      xor     %g1, %m44(-addr), %g1
-                *      sllx    %g1, 12, %g1    
-                *      jmp     %g1+%l44(addr)  
-                *      nop
+                *      sethi   %hi((-addr)>>12), %g1
+                *      or      %g1, %lo((-addr)>>12), %g1
+                *      neg     %g1
+                *      sllx    %g1, 12, %g1
+                *      jmp     %g1+(addr&0x0fff)
                 *      nop
                 *      nop
                 *
                 */
-               where[4] = JMP   | LOVAL(offset, 0);
-               where[3] = SLLX  | 12;
-               where[2] = XOR   | (((~offset) >> 12) & 0x00001fff);
-               where[1] = SETHI | HIVAL(~offset, 22);
+               Elf_Addr neg = (~value+1)>>12;
+               where[5] = JMP   | (value & 0x0fff);
+               where[4] = SLLX  | 12;
+               where[3] = NEG;
+               where[2] = OR    | (LOVAL(neg, 0)+1);
+               where[1] = SETHI | HIVAL(neg, 10);
+               __asm volatile("iflush %0+20" : : "r" (where));
                __asm volatile("iflush %0+16" : : "r" (where));
                __asm volatile("iflush %0+12" : : "r" (where));
                __asm volatile("iflush %0+8" : : "r" (where));



Home | Main Index | Thread Index | Old Index