crashpad/client/crashpad_info_note.S

56 lines
2.1 KiB
ArmAsm
Raw Normal View History

// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This note section is used on ELF platforms to give ElfImageReader a method
// of finding the instance of CrashpadInfo g_crashpad_info without requiring
// that symbol to be in the dynamic symbol table.
#include "util/misc/elf_note_types.h"
// namespace crashpad {
// CrashpadInfo g_crashpad_info;
// } // namespace crashpad
#define CRASHPAD_INFO_SYMBOL _ZN8crashpad15g_crashpad_infoE
#define NOTE_ALIGN 4
// This section must be "a"llocated so that it appears in the final binary at
Use a relative address in .note.crashpad.info The desc value in the note is now the offset of CRASHPAD_INFO_SYMBOL from desc. Making this note writable can trigger a linker error resulting in the binary embedding .note.crashpad.info to be rejected by the kernel during program loading. The error was observed with: GNU ld (GNU Binutils for Debian) 2.30 clang version 4.0.1-10 (tags/RELEASE_401/final) Debian 4.17.17-1rodete2 When the note is made writable, crashpad_snapshot_test contains two PT_LOAD segments which map to the same page. LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000258 0x0000000000000258 R 0x200000 LOAD 0x0000000000000258 0x0000000000000258 0x0000000000000258 0x00000000002b84d8 0x00000000002b8950 RWE 0x200000 Executing this binary with the execv system call triggers a segfault during program loading (an error can't be returned because the original process vm has already been discarded). I suspect (I haven't set up a debuggable kernel) the failure occurs while attempting to map the second load segment because its virtual address, 0x258, is in the same page as the first load segment. https://elixir.bootlin.com/linux/v4.17.17/source/fs/binfmt_elf.c#L380 The linker normally produces consecutive load segments where the second segment is loaded 0x200000 bytes after the first, which I think is the maximum expected page size. Modifying the test executable to load the second segment at 0x1258 (4096 byte page size) allows program loading to succeed (but of course crashes after control is given to it). Bug: crashpad:260 Change-Id: I2b9f1e66e98919138baef3da991a9710bd970dc4 Reviewed-on: https://chromium-review.googlesource.com/c/1292232 Reviewed-by: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
2018-10-30 18:11:33 -07:00
// runtime. The reference to CRASHPAD_INFO_SYMBOL uses an offset relative to
// this note to avoid making this note writable, which triggers a bug in GNU
// ld, or adding text relocations which require the target system to allow
// making text segments writable. https://crbug.com/crashpad/260.
.section .note.crashpad.info,"a",%note
.balign NOTE_ALIGN
# .globl indicates that it's available to link against other .o files. .hidden
# indicates that it will not appear in the executable's symbol table.
.globl CRASHPAD_NOTE_REFERENCE
.hidden CRASHPAD_NOTE_REFERENCE
.type CRASHPAD_NOTE_REFERENCE, %object
CRASHPAD_NOTE_REFERENCE:
.long name_end - name // namesz
.long desc_end - desc // descsz
.long CRASHPAD_ELF_NOTE_TYPE_CRASHPAD_INFO // type
name:
.asciz CRASHPAD_ELF_NOTE_NAME
name_end:
.balign NOTE_ALIGN
desc:
#if defined(__LP64__)
Use a relative address in .note.crashpad.info The desc value in the note is now the offset of CRASHPAD_INFO_SYMBOL from desc. Making this note writable can trigger a linker error resulting in the binary embedding .note.crashpad.info to be rejected by the kernel during program loading. The error was observed with: GNU ld (GNU Binutils for Debian) 2.30 clang version 4.0.1-10 (tags/RELEASE_401/final) Debian 4.17.17-1rodete2 When the note is made writable, crashpad_snapshot_test contains two PT_LOAD segments which map to the same page. LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000258 0x0000000000000258 R 0x200000 LOAD 0x0000000000000258 0x0000000000000258 0x0000000000000258 0x00000000002b84d8 0x00000000002b8950 RWE 0x200000 Executing this binary with the execv system call triggers a segfault during program loading (an error can't be returned because the original process vm has already been discarded). I suspect (I haven't set up a debuggable kernel) the failure occurs while attempting to map the second load segment because its virtual address, 0x258, is in the same page as the first load segment. https://elixir.bootlin.com/linux/v4.17.17/source/fs/binfmt_elf.c#L380 The linker normally produces consecutive load segments where the second segment is loaded 0x200000 bytes after the first, which I think is the maximum expected page size. Modifying the test executable to load the second segment at 0x1258 (4096 byte page size) allows program loading to succeed (but of course crashes after control is given to it). Bug: crashpad:260 Change-Id: I2b9f1e66e98919138baef3da991a9710bd970dc4 Reviewed-on: https://chromium-review.googlesource.com/c/1292232 Reviewed-by: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
2018-10-30 18:11:33 -07:00
.quad CRASHPAD_INFO_SYMBOL - desc
#else
Use a relative address in .note.crashpad.info The desc value in the note is now the offset of CRASHPAD_INFO_SYMBOL from desc. Making this note writable can trigger a linker error resulting in the binary embedding .note.crashpad.info to be rejected by the kernel during program loading. The error was observed with: GNU ld (GNU Binutils for Debian) 2.30 clang version 4.0.1-10 (tags/RELEASE_401/final) Debian 4.17.17-1rodete2 When the note is made writable, crashpad_snapshot_test contains two PT_LOAD segments which map to the same page. LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000258 0x0000000000000258 R 0x200000 LOAD 0x0000000000000258 0x0000000000000258 0x0000000000000258 0x00000000002b84d8 0x00000000002b8950 RWE 0x200000 Executing this binary with the execv system call triggers a segfault during program loading (an error can't be returned because the original process vm has already been discarded). I suspect (I haven't set up a debuggable kernel) the failure occurs while attempting to map the second load segment because its virtual address, 0x258, is in the same page as the first load segment. https://elixir.bootlin.com/linux/v4.17.17/source/fs/binfmt_elf.c#L380 The linker normally produces consecutive load segments where the second segment is loaded 0x200000 bytes after the first, which I think is the maximum expected page size. Modifying the test executable to load the second segment at 0x1258 (4096 byte page size) allows program loading to succeed (but of course crashes after control is given to it). Bug: crashpad:260 Change-Id: I2b9f1e66e98919138baef3da991a9710bd970dc4 Reviewed-on: https://chromium-review.googlesource.com/c/1292232 Reviewed-by: Scott Graham <scottmg@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
2018-10-30 18:11:33 -07:00
.long CRASHPAD_INFO_SYMBOL - desc
#endif // __LP64__
desc_end:
.size CRASHPAD_NOTE_REFERENCE, .-CRASHPAD_NOTE_REFERENCE