From d62f9b681902bc65224bdc89162bd819609782e3 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Fri, 8 May 2020 00:59:19 +0200 Subject: [PATCH 1/5] Fix regression in ld.so elf size calculation In patch 1182d1200603c9f33ec9968a1a00df5ebd3aa7d8, I mistakingly added the size of the gap to the total size of the binary, which was not accurate. As the size of the binary was calculate by subtracting the upperbound from the lower bound, thus all gaps in the middle are taking into account. --- src/ld_so/linker.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 1b47d5c38e..47331f5af6 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -394,7 +394,7 @@ impl Linker { }; if same_elf { let addr = dso.as_ref().unwrap().base_addr; - let mut size = bounds.1; + let size = bounds.1; // Fill the gaps i the binary let mut ranges = Vec::new(); for ph in elf.program_headers.iter() { @@ -410,8 +410,6 @@ impl Linker { let mut start = addr; for (vaddr, vsize) in ranges.iter() { if start < addr + vaddr { - let gap_size = addr + vaddr - start; - size += gap_size; sys_mman::mmap( start as *mut c_void, addr + vaddr - start, From 4a47bc4a6f4421c374dd2f10fbd5b40787aee98a Mon Sep 17 00:00:00 2001 From: oddcoder Date: Fri, 8 May 2020 01:04:21 +0200 Subject: [PATCH 2/5] Fix regressing in printf padding with space There was bug in printf where space paddings cause segfault, the problem was that it was pulled from the stack twice while it should be only done once. --- src/header/stdio/printf.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/header/stdio/printf.rs b/src/header/stdio/printf.rs index d8b06bc70f..727de95264 100644 --- a/src/header/stdio/printf.rs +++ b/src/header/stdio/printf.rs @@ -472,7 +472,6 @@ struct PrintfArg { sign_always: bool, min_width: Number, precision: Option, - pad_space: Number, pad_zero: Number, intkind: IntKind, fmt: u8, @@ -596,7 +595,6 @@ impl Iterator for PrintfIter { sign_always, min_width, precision, - pad_space, pad_zero, intkind, fmt, @@ -667,8 +665,11 @@ unsafe fn inner_printf(w: W, format: *const c_char, mut ap: VaList) -> let sign_always = arg.sign_always; let min_width = arg.min_width.resolve(&mut varargs, &mut ap); let precision = arg.precision.map(|n| n.resolve(&mut varargs, &mut ap)); - let pad_space = arg.pad_space.resolve(&mut varargs, &mut ap); let pad_zero = arg.pad_zero.resolve(&mut varargs, &mut ap); + let pad_space = match pad_zero { + 0 => min_width, + _ => 0, + }; let intkind = arg.intkind; let fmt = arg.fmt; let fmtkind = arg.fmtkind; From d373bcb032952aebb8f17d55bc80c4925b3518a8 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Fri, 8 May 2020 22:36:59 +0200 Subject: [PATCH 3/5] Avoid accessing memory without initialization --- tests/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/error.c b/tests/error.c index 5cbe10385d..4170e1f4be 100644 --- a/tests/error.c +++ b/tests/error.c @@ -20,7 +20,7 @@ int main(void) { int ret2 = strerror_r(err, buf2, 3); printf("errno: %d = %s, return: %d\n", err, buf2, ret2); - char buf3[256]; + char buf3[256] = {0}; int ret3 = strerror_r(err, buf3, 0); printf("errno: %d = %s, return: %d\n", err, buf3, ret3); } From a39447e6a479af7770aaf0d6cad51285868214b2 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Fri, 8 May 2020 22:37:39 +0200 Subject: [PATCH 4/5] Test printf space padding regression --- tests/Makefile | 1 + tests/expected/stdio/printf_space_pad.stderr | 0 tests/expected/stdio/printf_space_pad.stdout | 1 + tests/stdio/printf_space_pad.c | 4 ++++ 4 files changed, 6 insertions(+) create mode 100644 tests/expected/stdio/printf_space_pad.stderr create mode 100644 tests/expected/stdio/printf_space_pad.stdout create mode 100644 tests/stdio/printf_space_pad.c diff --git a/tests/Makefile b/tests/Makefile index eec484b078..a6f967a872 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -41,6 +41,7 @@ EXPECT_NAMES=\ stdio/scanf \ stdio/setvbuf \ stdio/sprintf \ + stdio/printf_space_pad \ stdlib/a64l \ stdlib/alloc \ stdlib/atof \ diff --git a/tests/expected/stdio/printf_space_pad.stderr b/tests/expected/stdio/printf_space_pad.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/stdio/printf_space_pad.stdout b/tests/expected/stdio/printf_space_pad.stdout new file mode 100644 index 0000000000..8e9107f351 --- /dev/null +++ b/tests/expected/stdio/printf_space_pad.stdout @@ -0,0 +1 @@ +A B diff --git a/tests/stdio/printf_space_pad.c b/tests/stdio/printf_space_pad.c new file mode 100644 index 0000000000..9e9172826d --- /dev/null +++ b/tests/stdio/printf_space_pad.c @@ -0,0 +1,4 @@ +#include +int main() { + printf ("%s%*s\n","A", 3, "B"); +} From 43fbaf9970ebe04c81c5544133480e74fd745a69 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Wed, 13 May 2020 23:27:16 +0200 Subject: [PATCH 5/5] Fix a bug in thread local reloations There was a bug (also uncovered via binutils) where R_X86_64_DTPOFF64 is set uncorrectly. This program is the minimal reproducer of the seg fault #include int main() { int oerrno = errno; } But it works after the bug fix. --- src/ld_so/linker.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 47331f5af6..4aea9b4100 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -666,7 +666,7 @@ impl Linker { set_u64(tm as u64); } reloc::R_X86_64_DTPOFF64 => { - set_u64((s + a) as u64); + set_u64(rel.r_offset as u64); } reloc::R_X86_64_GLOB_DAT | reloc::R_X86_64_JUMP_SLOT => { set_u64(s as u64);