Added Paul Gilliam's secure PLT patch
diff --git a/sysdeps/linux-gnu/alpha/plt.c b/sysdeps/linux-gnu/alpha/plt.c
index 30f2093..86511a9 100644
--- a/sysdeps/linux-gnu/alpha/plt.c
+++ b/sysdeps/linux-gnu/alpha/plt.c
@@ -7,7 +7,7 @@
return lte->plt_addr + ndx * 12 + 32;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/arm/plt.c b/sysdeps/linux-gnu/arm/plt.c
index 69e0077..cc6005e 100644
--- a/sysdeps/linux-gnu/arm/plt.c
+++ b/sysdeps/linux-gnu/arm/plt.c
@@ -7,7 +7,7 @@
return lte->plt_addr + 20 + ndx * 12;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/breakpoint.c b/sysdeps/linux-gnu/breakpoint.c
index 051ac00..3e11b24 100644
--- a/sysdeps/linux-gnu/breakpoint.c
+++ b/sysdeps/linux-gnu/breakpoint.c
@@ -33,7 +33,7 @@
&& i * sizeof(long) + j < BREAKPOINT_LENGTH; j++) {
unsigned char *bytes = (unsigned char *)&a;
- sbp->orig_value[i * sizeof(long) + j] = bytes[+j];
+ sbp->orig_value[i * sizeof(long) + j] = bytes[j];
bytes[j] = break_insn[i * sizeof(long) + j];
}
ptrace(PTRACE_POKETEXT, pid, sbp->addr + i * sizeof(long), a);
@@ -52,9 +52,7 @@
{
unsigned int i, j;
- if (opt_d > 1) {
- output_line(0, "disable_breakpoint(%d,%p)", pid, sbp->addr);
- }
+ debug(2, "disable_breakpoint(%d,%p)", pid, sbp->addr);
for (i = 0; i < 1 + ((BREAKPOINT_LENGTH - 1) / sizeof(long)); i++) {
long a =
diff --git a/sysdeps/linux-gnu/i386/plt.c b/sysdeps/linux-gnu/i386/plt.c
index 3eab56c..e8a2349 100644
--- a/sysdeps/linux-gnu/i386/plt.c
+++ b/sysdeps/linux-gnu/i386/plt.c
@@ -7,7 +7,7 @@
return lte->plt_addr + (ndx + 1) * 16;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/ia64/plt.c b/sysdeps/linux-gnu/ia64/plt.c
index faa3c0e..b1d1af4 100644
--- a/sysdeps/linux-gnu/ia64/plt.c
+++ b/sysdeps/linux-gnu/ia64/plt.c
@@ -42,7 +42,7 @@
return addr;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/m68k/plt.c b/sysdeps/linux-gnu/m68k/plt.c
index f1af366..8ee29e0 100644
--- a/sysdeps/linux-gnu/m68k/plt.c
+++ b/sysdeps/linux-gnu/m68k/plt.c
@@ -8,7 +8,7 @@
* ((lte->ehdr.e_flags & EF_CPU32) ? 24 : 12);
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index 7147b97..04692c4 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -4,10 +4,18 @@
#define LT_ELFCLASS ELFCLASS32
#define LT_ELF_MACHINE EM_PPC
-#ifdef __powerpc64__
+#ifdef __powerpc64__ // Says 'ltrace' is 64 bits, says nothing about target.
#define LT_ELFCLASS2 ELFCLASS64
#define LT_ELF_MACHINE2 EM_PPC64
#define PLT_REINITALISATION_BP "_start"
+#define PPC_NOP { 0x60, 0x00, 0x00, 0x00 }
+#define PPC_NOP_LENGTH 4
+
+#if (PPC_NOP_LENGTH != BREAKPOINT_LENGTH)
+#error "Length of the breakpoint value not equal to the length of a nop instruction"
+#endif
+
+
#endif
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 36c713b..e14e4c3 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -10,31 +10,49 @@
return rela->r_offset;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- long addr;
+ long addr = sym->enter_addr;
+ long pt_ret;
debug(3, 0);
- if (proc->e_machine == EM_PPC || plt == 0)
- return (void *)plt;
-
- if (proc->pid == 0)
- return (void *)0;
-
- // On a PowerPC-64 system, a plt is three 64-bit words: the first is the
- // 64-bit address of the routine. Before the PLT has been initialized, this
- // will be 0x0. In fact, the symbol table won't have the plt's address even.
- // Ater the PLT has been initialized, but before it has been resolved, the
- // first word will be the address of the function in the dynamic linker that
- // will reslove the PLT. After the PLT is resolved, this will will be the
- // address of the routine whose symbol is in the symbol table.
-
- addr = ptrace(PTRACE_PEEKTEXT, proc->pid, plt);
-
- if (opt_d >= 3) {
- xinfdump(proc->pid, plt, sizeof(void *) * 3);
+ if (sym->plt_type != LS_TOPLT_POINT) {
+ return addr;
}
- return (void *)addr;
+ if (proc->pid == 0) {
+ return 0;
+ }
+
+ if (opt_d >= 3) {
+ xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0),
+ sizeof(void*)*8);
+ }
+
+ // On a PowerPC-64 system, a plt is three 64-bit words: the first is the
+ // 64-bit address of the routine. Before the PLT has been initialized,
+ // this will be 0x0. In fact, the symbol table won't have the plt's
+ // address even. Ater the PLT has been initialized, but before it has
+ // been resolved, the first word will be the address of the function in
+ // the dynamic linker that will reslove the PLT. After the PLT is
+ // resolved, this will will be the address of the routine whose symbol
+ // is in the symbol table.
+
+ // On a PowerPC-32 system, there are two types of PLTs: secure (new) and
+ // non-secure (old). For the secure case, the PLT is simply a pointer
+ // and we can treat it much as we do for the PowerPC-64 case. For the
+ // non-secure case, the PLT is executable code and we can put the
+ // break-point right in the PLT.
+
+ pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
+
+ if (proc->mask_32bit) {
+ // Assume big-endian.
+ addr = (void *)((pt_ret >> 32) & 0xffffffff);
+ } else {
+ addr = (void *)pt_ret;
+ }
+
+ return addr;
}
diff --git a/sysdeps/linux-gnu/s390/plt.c b/sysdeps/linux-gnu/s390/plt.c
index 888c285..ffe7f11 100644
--- a/sysdeps/linux-gnu/s390/plt.c
+++ b/sysdeps/linux-gnu/s390/plt.c
@@ -7,7 +7,7 @@
return lte->plt_addr + (ndx + 1) * 32;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/sparc/plt.c b/sysdeps/linux-gnu/sparc/plt.c
index 68343b9..87dad8c 100644
--- a/sysdeps/linux-gnu/sparc/plt.c
+++ b/sysdeps/linux-gnu/sparc/plt.c
@@ -7,7 +7,7 @@
return rela->r_offset + 4;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}
diff --git a/sysdeps/linux-gnu/x86_64/plt.c b/sysdeps/linux-gnu/x86_64/plt.c
index 3eab56c..e8a2349 100644
--- a/sysdeps/linux-gnu/x86_64/plt.c
+++ b/sysdeps/linux-gnu/x86_64/plt.c
@@ -7,7 +7,7 @@
return lte->plt_addr + (ndx + 1) * 16;
}
-void *plt2addr(struct process *proc, void **plt)
+void *sym2addr(struct process *proc, struct library_symbol *sym)
{
- return (void *)plt;
+ return sym->enter_addr;
}