13bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki/* 23b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 3772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * honggfuzz - architecture dependent code (LINUX/PTRACE) 4772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * ----------------------------------------- 53b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 6772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * Author: Robert Swiecki <swiecki@google.com> 73b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 8772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * Copyright 2010-2015 by Google Inc. All Rights Reserved. 93b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 103b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * Licensed under the Apache License, Version 2.0 (the "License"); you may 113b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * not use this file except in compliance with the License. You may obtain 12772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * a copy of the License at 133b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 14772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * http://www.apache.org/licenses/LICENSE-2.0 153b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 16772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * Unless required by applicable law or agreed to in writing, software 17772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * distributed under the License is distributed on an "AS IS" BASIS, 18772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 19772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * implied. See the License for the specific language governing 20772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com * permissions and limitations under the License. 213b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 22772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com */ 233bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 24019de49cb1a0901019839e0218174a0f7bf838e1Robert Swiecki#include "linux/trace.h" 25ba85c3e351a63c68108935d717c24ef20cc32018robert.swiecki@gmail.com 2612fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <ctype.h> 275f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com#include <dirent.h> 2812fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <elf.h> 294c1ad431dc7fbac0308d175e4f7a77ad6912880drobert.swiecki@gmail.com#include <endian.h> 303bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki#include <errno.h> 31ad6af2246b9d25e66266653ed292dc03928df7a5robert.swiecki@gmail.com#include <fcntl.h> 32d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#include <inttypes.h> 3312fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <signal.h> 343bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki#include <stdio.h> 3512fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <stdlib.h> 363bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki#include <string.h> 3712fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/cdefs.h> 3812fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/personality.h> 393bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki#include <sys/ptrace.h> 4012fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/resource.h> 41ad6af2246b9d25e66266653ed292dc03928df7a5robert.swiecki@gmail.com#include <sys/stat.h> 428b76934f112fdbca5cd6b902c1cc503a677bc47cRobert Swiecki#include <sys/syscall.h> 4312fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/time.h> 4412fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/types.h> 45ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com#include <sys/uio.h> 463bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki#include <sys/user.h> 4712fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <sys/wait.h> 4812fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <time.h> 4912fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com#include <unistd.h> 503bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 5110eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "libcommon/common.h" 5210eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "libcommon/files.h" 5310eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "libcommon/log.h" 5410eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "libcommon/util.h" 5510eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "linux/bfd.h" 5610eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "linux/unwind.h" 5710eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "sancov.h" 5810eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "sanitizers.h" 5910eeb0a296350f6e756a736692762a6ce3358d27Robert Swiecki#include "subproc.h" 603bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 61cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#if defined(__ANDROID__) 62cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#include "capstone.h" 63cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 64cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 65cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#if defined(__i386__) || defined(__arm__) || defined(__powerpc__) 66cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#define REG_TYPE uint32_t 67d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define REG_PM PRIx32 68d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define REG_PD "0x%08" 69d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki#elif defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) || \ 70d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki defined(__mips__) || defined(__mips64__) 71cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#define REG_TYPE uint64_t 72d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define REG_PM PRIx64 73d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define REG_PD "0x%016" 74cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 75cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 76d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis/* 77d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * Size in characters required to store a string representation of a 78d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * register value (0xdeadbeef style)) 79d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis */ 80d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define REGSIZEINCHAR (2 * sizeof(REG_TYPE) + 3) 81d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 82cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#if defined(__i386__) || defined(__x86_64__) 83cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#define MAX_INSTR_SZ 16 84cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#elif defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) 85cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#define MAX_INSTR_SZ 4 86cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#elif defined(__aarch64__) 87cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#define MAX_INSTR_SZ 8 881441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki#elif defined(__mips__) || defined(__mips64__) 891441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki#define MAX_INSTR_SZ 8 90cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 91cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 92cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis#if defined(__i386__) || defined(__x86_64__) 93cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_32 { 94cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t ebx; 95cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t ecx; 96cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t edx; 97cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t esi; 98cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t edi; 99cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t ebp; 100cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t eax; 101cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t ds, __ds; 102cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t es, __es; 103cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t fs, __fs; 104cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t gs, __gs; 105cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t orig_eax; 106cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t eip; 107cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t cs, __cs; 108cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t eflags; 109cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t esp; 110cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint16_t ss, __ss; 111cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 112cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 113cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_64 { 114cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r15; 115cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r14; 116cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r13; 117cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r12; 118cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t bp; 119cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t bx; 120cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r11; 121cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r10; 122cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r9; 123cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t r8; 124cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ax; 125cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t cx; 126cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t dx; 127cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t si; 128cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t di; 129cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t orig_ax; 130cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ip; 131cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t cs; 132cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t flags; 133cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t sp; 134cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ss; 135cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t fs_base; 136cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t gs_base; 137cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ds; 138cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t es; 139cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t fs; 140cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t gs; 141cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 142cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis#define HEADERS_STRUCT struct user_regs_struct_64 1434e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__i386__) || defined(__x86_64__) */ 144cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 14517887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#if defined(__arm__) || defined(__aarch64__) 146d628a709694488a860974063c8b44f33e82d7ec2Jagger#ifndef ARM_pc 1474e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#ifdef __ANDROID__ /* Building with NDK headers */ 148d628a709694488a860974063c8b44f33e82d7ec2Jagger#define ARM_pc uregs[15] 1494e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#else /* Building with glibc headers */ 150d628a709694488a860974063c8b44f33e82d7ec2Jagger#define ARM_pc 15 151d628a709694488a860974063c8b44f33e82d7ec2Jagger#endif 1524e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* ARM_pc */ 153d628a709694488a860974063c8b44f33e82d7ec2Jagger#ifndef ARM_cpsr 1544e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#ifdef __ANDROID__ /* Building with NDK headers */ 155d628a709694488a860974063c8b44f33e82d7ec2Jagger#define ARM_cpsr uregs[16] 1564e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#else /* Building with glibc headers */ 157d628a709694488a860974063c8b44f33e82d7ec2Jagger#define ARM_cpsr 16 158d628a709694488a860974063c8b44f33e82d7ec2Jagger#endif 1594e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* ARM_cpsr */ 160cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_32 { 161cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t uregs[18]; 162cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 163cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 164cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_64 { 165cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t regs[31]; 166cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t sp; 167cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t pc; 168cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t pstate; 169cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 17017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#define HEADERS_STRUCT struct user_regs_struct_64 1714e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__arm__) || defined(__aarch64__) */ 172cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 173cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis#if defined(__powerpc64__) || defined(__powerpc__) 174cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis#define HEADERS_STRUCT struct pt_regs 175cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_32 { 176cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t gpr[32]; 177cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t nip; 178cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t msr; 179cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t orig_gpr3; 180cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t ctr; 181cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t link; 182cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t xer; 183cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t ccr; 184cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t mq; 185cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t trap; 186cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t dar; 187cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t dsisr; 188cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t result; 189cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis /* 190cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * elf.h's ELF_NGREG says it's 48 registers, so kernel fills it in 191cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * with some zeros 192cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis */ 193cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t zero0; 194cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t zero1; 195cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t zero2; 196cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint32_t zero3; 197cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 198cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudisstruct user_regs_struct_64 { 199cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t gpr[32]; 200cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t nip; 201cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t msr; 202cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t orig_gpr3; 203cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ctr; 204cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t link; 205cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t xer; 206cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t ccr; 207cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t softe; 208cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t trap; 209cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t dar; 210cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t dsisr; 211cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t result; 212cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis /* 213cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * elf.h's ELF_NGREG says it's 48 registers, so kernel fills it in 214cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * with some zeros 215cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis */ 216cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t zero0; 217cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t zero1; 218cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t zero2; 219cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis uint64_t zero3; 220cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis}; 2214e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__powerpc64__) || defined(__powerpc__) */ 222cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 2231441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki#if defined(__mips__) || defined(__mips64__) 2241441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swieckistruct user_regs_struct { 2251441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t regs[32]; 2261441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki 2271441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t lo; 2281441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t hi; 2291441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t cp0_epc; 2301441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t cp0_badvaddr; 2311441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t cp0_status; 2321441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki uint64_t cp0_cause; 2331441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki}; 2341441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki#define HEADERS_STRUCT struct user_regs_struct 2354e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__mips__) || defined(__mips64__) */ 2361441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki 237cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#if defined(__ANDROID__) 23823ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki/* 2396d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis * Some Android ABIs don't implement PTRACE_GETREGS (e.g. aarch64) 240cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis */ 2416d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#if defined(PTRACE_GETREGS) 2426d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#define PTRACE_GETREGS_AVAILABLE 1 2436d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#else 2446d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#define PTRACE_GETREGS_AVAILABLE 0 2454e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(PTRACE_GETREGS) */ 2464e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__ANDROID__) */ 247cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 248e84b645dcff103f9bd80b2be15c784e8bf736d0eRobert Swieckistatic struct { 249d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki const char* descr; 2501f2d5b194a249716fbd6f094cc335c751767fb99Jagger bool important; 251e84b645dcff103f9bd80b2be15c784e8bf736d0eRobert Swiecki} arch_sigs[_NSIG + 1] = { 2524e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki [0 ...(_NSIG)].important = false, 253d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki [0 ...(_NSIG)].descr = "UNKNOWN", 254b16e1d9511616c7d91710cc35ca32ca33b653d38robert.swiecki@gmail.com 255dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger [SIGTRAP].important = false, 256dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger [SIGTRAP].descr = "SIGTRAP", 2571f2d5b194a249716fbd6f094cc335c751767fb99Jagger 25834a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGILL].important = true, 25934a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGILL].descr = "SIGILL", 2601f2d5b194a249716fbd6f094cc335c751767fb99Jagger 26134a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGFPE].important = true, 26234a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGFPE].descr = "SIGFPE", 2631f2d5b194a249716fbd6f094cc335c751767fb99Jagger 26434a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGSEGV].important = true, 26534a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGSEGV].descr = "SIGSEGV", 2661f2d5b194a249716fbd6f094cc335c751767fb99Jagger 26734a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGBUS].important = true, 26834a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com [SIGBUS].descr = "SIGBUS", 2691f2d5b194a249716fbd6f094cc335c751767fb99Jagger 270f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis /* Is affected from monitorSIGABRT flag */ 2718e634c3ef96143be77e8beaaa5620e3fdf41dcd5Anestis Bechtsoudis [SIGABRT].important = false, 272e84b645dcff103f9bd80b2be15c784e8bf736d0eRobert Swiecki [SIGABRT].descr = "SIGABRT", 273e84b645dcff103f9bd80b2be15c784e8bf736d0eRobert Swiecki 274eba27171213942cb463e68f04ad2f2b70012d106Robert Swiecki /* Is affected from tmoutVTALRM flag */ 275f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis [SIGVTALRM].important = false, 276e84b645dcff103f9bd80b2be15c784e8bf736d0eRobert Swiecki [SIGVTALRM].descr = "SIGVTALRM-TMOUT", 27749028c9d1a4397b2e02415b164e4d8fd07571016Robert Swiecki 27849028c9d1a4397b2e02415b164e4d8fd07571016Robert Swiecki /* seccomp-bpf kill */ 27949028c9d1a4397b2e02415b164e4d8fd07571016Robert Swiecki [SIGSYS].important = true, 28049028c9d1a4397b2e02415b164e4d8fd07571016Robert Swiecki [SIGSYS].descr = "SIGSYS", 28134a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com}; 2823bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 2838d95df7617521689db58fb6f6e4373549a54cb75Anestis Bechtsoudis#ifndef SI_FROMUSER 284d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0) 2854e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* SI_FROMUSER */ 2868d95df7617521689db58fb6f6e4373549a54cb75Anestis Bechtsoudis 2874e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swieckiextern const char* sys_sigabbrev[]; 288bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki 289bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swieckistatic __thread char arch_signame[32]; 290d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic const char* arch_sigName(int signo) { 291bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki if (signo < 0 || signo > _NSIG) { 292bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki snprintf(arch_signame, sizeof(arch_signame), "UNKNOWN-%d", signo); 293bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki return arch_signame; 294bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki } 295bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki if (signo > __SIGRTMIN) { 296bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki snprintf(arch_signame, sizeof(arch_signame), "SIG%d-RTMIN+%d", signo, signo - __SIGRTMIN); 297bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki return arch_signame; 298bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki } 299bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki#ifdef __ANDROID__ 300bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki return arch_sigs[signo].descr; 301bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki#else 302cd3d0c5ff7a32aa6d080555a1b6a43f73d502391Robert Swiecki if (sys_sigabbrev[signo] == NULL) { 303cd3d0c5ff7a32aa6d080555a1b6a43f73d502391Robert Swiecki snprintf(arch_signame, sizeof(arch_signame), "SIG%d", signo); 304cd3d0c5ff7a32aa6d080555a1b6a43f73d502391Robert Swiecki } else { 305cd3d0c5ff7a32aa6d080555a1b6a43f73d502391Robert Swiecki snprintf(arch_signame, sizeof(arch_signame), "SIG%s", sys_sigabbrev[signo]); 306cd3d0c5ff7a32aa6d080555a1b6a43f73d502391Robert Swiecki } 307bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki return arch_signame; 3084e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* __ANDROID__ */ 309bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki} 310bfbc78b1d1c64a6da925f665b8891a0fee1080cdRobert Swiecki 311d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic size_t arch_getProcMem(pid_t pid, uint8_t* buf, size_t len, REG_TYPE pc) { 312772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com /* 3133b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * Let's try process_vm_readv first 314772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com */ 315ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com const struct iovec local_iov = { 316ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com .iov_base = buf, 317ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com .iov_len = len, 318ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com }; 319ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com const struct iovec remote_iov = { 3204e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki .iov_base = (void*)(uintptr_t)pc, 321ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com .iov_len = len, 322ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com }; 3234e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki if (process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0) == (ssize_t)len) { 324ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com return len; 325ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com } 326cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis // Debug if failed since it shouldn't happen very often 327c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_D("process_vm_readv() failed"); 328cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 3293bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki /* 330ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com * Ok, let's do it via ptrace() then. 3313bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki * len must be aligned to the sizeof(long) 3323bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki */ 3333bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki int cnt = len / sizeof(long); 3343bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki size_t memsz = 0; 3353bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 3363bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki for (int x = 0; x < cnt; x++) { 3374e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki uint8_t* addr = (uint8_t*)(uintptr_t)pc + (int)(x * sizeof(long)); 338a0df592ba4f3ed3c1c04efbe422caa9c380c7053Jagger long ret = ptrace(PTRACE_PEEKDATA, pid, addr, NULL); 3393bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 3403bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki if (errno != 0) { 341c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_W("Couldn't PT_READ_D on pid %d, addr: %p", pid, addr); 3423bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki break; 3433bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 3443bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 3453bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki memsz += sizeof(long); 3463bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki memcpy(&buf[x * sizeof(long)], &ret, sizeof(long)); 3473bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 3483bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki return memsz; 3493bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki} 3503bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 351d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic size_t arch_getPC(pid_t pid, REG_TYPE* pc, REG_TYPE* status_reg UNUSED) { 3524021d12859c2517ffd379fafe00617b22b84d6c1Robert Swiecki/* 3530b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki * Some old ARM android kernels are failing with PTRACE_GETREGS to extract 3540b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki * the correct register values if struct size is bigger than expected. As such the 3550b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki * 32/64-bit multiplexing trick is not working for them in case PTRACE_GETREGSET 3560b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki * fails or is not implemented. To cover such cases we explicitly define 3570b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki * the struct size to 32bit version for arm CPU. 3580b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki */ 359672a9180036242d16d83bc77347834228a7bbe29Anestis Bechtsoudis#if defined(__arm__) 360672a9180036242d16d83bc77347834228a7bbe29Anestis Bechtsoudis struct user_regs_struct_32 regs; 361672a9180036242d16d83bc77347834228a7bbe29Anestis Bechtsoudis#else 362cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis HEADERS_STRUCT regs; 363672a9180036242d16d83bc77347834228a7bbe29Anestis Bechtsoudis#endif 364ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com struct iovec pt_iov = { 365cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis .iov_base = ®s, 366cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis .iov_len = sizeof(regs), 367ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com }; 368cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 3698a7d698c26084d21ade1cb044da721540bfc1706robert.swiecki@gmail.com if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &pt_iov) == -1L) { 370c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_D("ptrace(PTRACE_GETREGSET) failed"); 37117887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis 3724021d12859c2517ffd379fafe00617b22b84d6c1Robert Swiecki// If PTRACE_GETREGSET fails, try PTRACE_GETREGS if available 3736d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#if PTRACE_GETREGS_AVAILABLE 374cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis if (ptrace(PTRACE_GETREGS, pid, 0, ®s)) { 375c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_D("ptrace(PTRACE_GETREGS) failed"); 376d81f09724246b794d5acccde2e008c9d12d9c4edAnestis Bechtsoudis LOG_W("ptrace PTRACE_GETREGSET & PTRACE_GETREGS failed to extract target registers"); 37717887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return 0; 378cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis } 3796d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#else 3806d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis return 0; 3816d8d612b6ea0d3cec3502de8976d7c481672eca0Anestis Bechtsoudis#endif 382ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com } 383cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis#if defined(__i386__) || defined(__x86_64__) 384772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com /* 3853b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 32-bit 386772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com */ 387ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_32)) { 3884e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_32* r32 = (struct user_regs_struct_32*)®s; 389730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r32->eip; 390cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *status_reg = r32->eflags; 39117887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 392ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com } 393cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 394772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com /* 3953b630b47e7d39e7b36c749290385e284bc5eb950robert.swiecki@gmail.com * 64-bit 396772b33d10d4225a4befcb557ffbea889ad891958robert.swiecki@gmail.com */ 397ae20f60e3af7cb3bea4943b53a1f3e35d9fe1eb0robert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_64)) { 3984e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_64* r64 = (struct user_regs_struct_64*)®s; 399730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r64->ip; 400cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *status_reg = r64->flags; 40117887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 402ec3acc56bdc6ad3a682f24d09bcca65bdc8f5e8erobert.swiecki@gmail.com } 403c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_W("Unknown registers structure size: '%zd'", pt_iov.iov_len); 40417887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return 0; 4054e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__i386__) || defined(__x86_64__) */ 406cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 40717887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#if defined(__arm__) || defined(__aarch64__) 40817887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis /* 40917887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis * 32-bit 41017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis */ 411730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_32)) { 4124e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_32* r32 = (struct user_regs_struct_32*)®s; 413cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#ifdef __ANDROID__ 414cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *pc = r32->ARM_pc; 415cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *status_reg = r32->ARM_cpsr; 416cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#else 417730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r32->uregs[ARM_pc]; 418cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *status_reg = r32->uregs[ARM_cpsr]; 419cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 42017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 421730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com } 422cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 42317887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis /* 42417887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis * 64-bit 42517887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis */ 426730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_64)) { 4274e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_64* r64 = (struct user_regs_struct_64*)®s; 428730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r64->pc; 429cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis *status_reg = r64->pstate; 43017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 431730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com } 432b48b4744ce83120f3ef979f58ccab70a15f06762Anestis Bechtsoudis LOG_W("Unknown registers structure size: '%zd'", pt_iov.iov_len); 43317887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return 0; 4344e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__arm__) || defined(__aarch64__) */ 435cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 436730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com#if defined(__powerpc64__) || defined(__powerpc__) 437cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis /* 438cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * 32-bit 439cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis */ 440730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_32)) { 4414e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_32* r32 = (struct user_regs_struct_32*)®s; 442730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r32->nip; 44317887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 444730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com } 445cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 446cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis /* 447cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis * 64-bit 448cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis */ 449730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com if (pt_iov.iov_len == sizeof(struct user_regs_struct_64)) { 4504e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct user_regs_struct_64* r64 = (struct user_regs_struct_64*)®s; 451730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com *pc = r64->nip; 45217887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return pt_iov.iov_len; 453730f9486a4292fc6c94c29b3730cb87edc8cdb4brobert.swiecki@gmail.com } 454cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 455b48b4744ce83120f3ef979f58ccab70a15f06762Anestis Bechtsoudis LOG_W("Unknown registers structure size: '%zd'", pt_iov.iov_len); 45617887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return 0; 4574e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__powerpc64__) || defined(__powerpc__) */ 458cab40dea61c8bbe0d3a291fed4ef33a95135a33eAnestis Bechtsoudis 4591441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki#if defined(__mips__) || defined(__mips64__) 4601441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki *pc = regs.cp0_epc; 4611441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki return pt_iov.iov_len; 4624e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__mips__) || defined(__mips64__) */ 4631441b6bb52013236da04b61b6b06c48e4b6f36f5Robert Swiecki 464c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_D("Unknown/unsupported CPU architecture"); 46517887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis return 0; 46612fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com} 46712fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com 468d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_getInstrStr(pid_t pid, REG_TYPE* pc, char* instr) { 4693bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki /* 47034a4070a273f9f64ee42053677d0632576ddfbd0robert.swiecki@gmail.com * We need a value aligned to 8 4713bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki * which is sizeof(long) on 64bit CPU archs (on most of them, I hope;) 4723bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki */ 473cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis uint8_t buf[MAX_INSTR_SZ]; 4743bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki size_t memsz; 475cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis REG_TYPE status_reg = 0; 476cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 4779e2d43de38ba979258bedf81b7a65f98bd0af929robert.swiecki@gmail.com snprintf(instr, _HF_INSTR_SZ, "%s", "[UNKNOWN]"); 47812fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com 47917887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis size_t pcRegSz = arch_getPC(pid, pc, &status_reg); 48017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis if (!pcRegSz) { 481c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_W("Current architecture not supported for disassembly"); 48212fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com return; 48312fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com } 48412fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com 48512fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com if ((memsz = arch_getProcMem(pid, buf, sizeof(buf), *pc)) == 0) { 4869e2d43de38ba979258bedf81b7a65f98bd0af929robert.swiecki@gmail.com snprintf(instr, _HF_INSTR_SZ, "%s", "[NOT_MMAPED]"); 4873bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki return; 4883bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 489cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#if !defined(__ANDROID__) 49026eee243813ffb12957e386d9475d7d4a9d9b245robert.swiecki@gmail.com arch_bfdDisasm(pid, buf, memsz, instr); 491cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#else 49217887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis cs_arch arch; 49317887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis cs_mode mode; 49417887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#if defined(__arm__) || defined(__aarch64__) 49517887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis arch = (pcRegSz == sizeof(struct user_regs_struct_64)) ? CS_ARCH_ARM64 : CS_ARCH_ARM; 49617887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis if (arch == CS_ARCH_ARM) { 49717887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis mode = (status_reg & 0x20) ? CS_MODE_THUMB : CS_MODE_ARM; 498d628a709694488a860974063c8b44f33e82d7ec2Jagger } else { 49917887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis mode = CS_MODE_ARM; 500d628a709694488a860974063c8b44f33e82d7ec2Jagger } 50117887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#elif defined(__i386__) || defined(__x86_64__) 50217887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis arch = CS_ARCH_X86; 50317887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis mode = (pcRegSz == sizeof(struct user_regs_struct_64)) ? CS_MODE_64 : CS_MODE_32; 504cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#else 505e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis LOG_E("Unknown/Unsupported Android CPU architecture"); 506cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 507cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 508cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis csh handle; 509cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis cs_err err = cs_open(arch, mode, &handle); 510cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis if (err != CS_ERR_OK) { 511c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_W("Capstone initialization failed: '%s'", cs_strerror(err)); 512cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis return; 513cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis } 514cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 5154e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki cs_insn* insn; 516cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis size_t count = cs_disasm(handle, buf, sizeof(buf), *pc, 0, &insn); 517cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 518cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis if (count < 1) { 519c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_W("Couldn't disassemble the assembler instructions' stream: '%s'", 5204e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki cs_strerror(cs_errno(handle))); 521cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis cs_close(&handle); 522cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis return; 523cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis } 524cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 525cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis snprintf(instr, _HF_INSTR_SZ, "%s %s", insn[0].mnemonic, insn[0].op_str); 526cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis cs_free(insn, count); 527cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis cs_close(&handle); 5284e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* defined(__ANDROID__) */ 529cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis 5309e2d43de38ba979258bedf81b7a65f98bd0af929robert.swiecki@gmail.com for (int x = 0; instr[x] && x < _HF_INSTR_SZ; x++) { 5310b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki if (instr[x] == '/' || instr[x] == '\\' || isspace(instr[x]) || !isprint(instr[x])) { 5323bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki instr[x] = '_'; 5333bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 5343bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 53526eee243813ffb12957e386d9475d7d4a9d9b245robert.swiecki@gmail.com 53626eee243813ffb12957e386d9475d7d4a9d9b245robert.swiecki@gmail.com return; 5373bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki} 5383bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 539d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_hashCallstack(run_t* run, funcs_t* funcs, size_t funcCnt, bool enableMasking) { 540d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis uint64_t hash = 0; 54178633d1b907775e7067fb04332859703de72ac3fRobert Swiecki for (size_t i = 0; i < funcCnt && i < run->global->linux.numMajorFrames; i++) { 542d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis /* 543d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * Convert PC to char array to be compatible with hash function 544d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis */ 545d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki char pcStr[REGSIZEINCHAR] = {0}; 5464e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki snprintf(pcStr, REGSIZEINCHAR, REG_PD REG_PM, (REG_TYPE)(long)funcs[i].pc); 547d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 548d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis /* 549d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * Hash the last three nibbles 550d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis */ 551d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis hash ^= util_hash(&pcStr[strlen(pcStr) - 3], 3); 552d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis } 553d3ffe9eeebf753e451c63febb7590d383e395e02Anestis Bechtsoudis 554d3ffe9eeebf753e451c63febb7590d383e395e02Anestis Bechtsoudis /* 55560ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis * If only one frame, hash is not safe to be used for uniqueness. We mask it 55660ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis * here with a constant prefix, so analyzers can pick it up and create filenames 55760ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis * accordingly. 'enableMasking' is controlling masking for cases where it should 55860ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis * not be enabled (e.g. fuzzer worker is from verifier). 559d3ffe9eeebf753e451c63febb7590d383e395e02Anestis Bechtsoudis */ 560d3ffe9eeebf753e451c63febb7590d383e395e02Anestis Bechtsoudis if (enableMasking && funcCnt == 1) { 561c06f8b33adf90032a34508c190923d82fa99f398Anestis Bechtsoudis hash |= _HF_SINGLE_FRAME_MASK; 562d3ffe9eeebf753e451c63febb7590d383e395e02Anestis Bechtsoudis } 563e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->backtrace = hash; 564d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis} 565d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 5660b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swieckistatic void arch_traceGenerateReport( 567d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki pid_t pid, run_t* run, funcs_t* funcs, size_t funcCnt, siginfo_t* si, const char* instr) { 568e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->report[0] = '\0'; 569e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "ORIG_FNAME: %s\n", run->origFileName); 570e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "FUZZ_FNAME: %s\n", run->crashFileName); 571e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "PID: %d\n", pid); 572e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "SIGNAL: %s (%d)\n", 5734e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki arch_sigName(si->si_signo), si->si_signo); 574e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "FAULT ADDRESS: %p\n", 5754e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki SI_FROMUSER(si) ? NULL : si->si_addr); 576e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "INSTRUCTION: %s\n", instr); 577e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "STACK HASH: %016llx\n", run->backtrace); 578e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "STACK:\n"); 579576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com for (size_t i = 0; i < funcCnt; i++) { 580cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#ifdef __HF_USE_CAPSTONE__ 581e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf( 582e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->report, sizeof(run->report), " <" REG_PD REG_PM "> ", (REG_TYPE)(long)funcs[i].pc); 583cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis if (funcs[i].func[0] != '\0') 584e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "[%s() + 0x%x at %s]\n", funcs[i].func, 585e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki funcs[i].line, funcs[i].mapName); 586cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis else 587e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "[]\n"); 588cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#else 589e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), " <" REG_PD REG_PM "> [%s():%u at %s]\n", 590e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki (REG_TYPE)(long)funcs[i].pc, funcs[i].func, funcs[i].line, funcs[i].mapName); 591cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis#endif 592576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com } 593576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com 5944021d12859c2517ffd379fafe00617b22b84d6c1Robert Swiecki// libunwind is not working for 32bit targets in 64bit systems 59517887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#if defined(__aarch64__) 59617887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis if (funcCnt == 0) { 597e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), 5980b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki " !ERROR: If 32bit fuzz target" 5990b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki " in aarch64 system, try ARM 32bit build\n"); 60017887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis } 60117887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis#endif 60217887e2503e8e99d1ee151bfa468d47f426866abAnestis Bechtsoudis 603576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com return; 604576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com} 605576232be18a657a5e08da39d52beffaacafe46b1robert.swiecki@gmail.com 606d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_traceAnalyzeData(run_t* run, pid_t pid) { 607c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis REG_TYPE pc = 0, status_reg = 0; 608c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis size_t pcRegSz = arch_getPC(pid, &pc, &status_reg); 609c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis if (!pcRegSz) { 610c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis LOG_W("ptrace arch_getPC failed"); 611c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis return; 612c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } 613c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis 6145c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis /* 6155c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis * Unwind and resolve symbols 6165c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis */ 6174e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t)); 6180b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { free(funcs); }; 6196fb025e8c04bfec166ade14046458f124f3e344cAnestis Bechtsoudis memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t)); 6205c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis 6215c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis#if !defined(__ANDROID__) 6225c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis size_t funcCnt = arch_unwindStack(pid, funcs); 6235c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis arch_bfdResolveSyms(pid, funcs, funcCnt); 6245c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis#else 6255c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis size_t funcCnt = arch_unwindStack(pid, funcs); 6265c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis#endif 6275c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis 62823ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 62923ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki * If unwinder failed (zero frames), use PC from ptrace GETREGS if not zero. 630c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis * If PC reg zero return and callers should handle zero hash case. 631c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis */ 632c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis if (funcCnt == 0) { 633c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis if (pc) { 634c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis /* Manually update major frame PC & frames counter */ 6354e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs[0].pc = (void*)(uintptr_t)pc; 636c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis funcCnt = 1; 637c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } else { 638c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis return; 639c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } 640c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } 641c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis 6425c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis /* 6435c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis * Calculate backtrace callstack hash signature 6445c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis */ 64578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_hashCallstack(run, funcs, funcCnt, false); 6465c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis} 6475c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis 648d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_traceSaveData(run_t* run, pid_t pid) { 649cfc39fb203a5e14915dee874957487935554d23bAnestis Bechtsoudis REG_TYPE pc = 0; 65036068adbbe41bc8b9f2a7ca2052e8cb2c3542f4fAnestis Bechtsoudis 65136068adbbe41bc8b9f2a7ca2052e8cb2c3542f4fAnestis Bechtsoudis /* Local copy since flag is overridden for some crashes */ 65226fd6d58dfabe2d047d422c1098794980d59dad2Robert Swiecki bool saveUnique = run->global->io.saveUnique; 6533bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 6549e2d43de38ba979258bedf81b7a65f98bd0af929robert.swiecki@gmail.com char instr[_HF_INSTR_SZ] = "\x00"; 6553bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki siginfo_t si; 656dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger bzero(&si, sizeof(si)); 6573bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 658a0df592ba4f3ed3c1c04efbe422caa9c380c7053Jagger if (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) == -1) { 659c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_W("Couldn't get siginfo for pid %d", pid); 6603bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 6613bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 66212fbf549cb142fa18650f8a6a780c1a69dabf6f0robert.swiecki@gmail.com arch_getInstrStr(pid, &pc, instr); 6633bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 664d0fa62c5606ba9caf914b4db031d22d9551d16baRobert Swiecki LOG_D("Pid: %d, signo: %d, errno: %d, code: %d, addr: %p, pc: %" REG_PM ", instr: '%s'", pid, 6654e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki si.si_signo, si.si_errno, si.si_code, si.si_addr, pc, instr); 6663bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 66778633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (!SI_FROMUSER(&si) && pc && si.si_addr < run->global->linux.ignoreAddr) { 668c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_I("'%s' is interesting (%s), but the si.si_addr is %p (below %p), skipping", 66978633d1b907775e7067fb04332859703de72ac3fRobert Swiecki run->fileName, arch_sigName(si.si_signo), si.si_addr, run->global->linux.ignoreAddr); 6703bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki return; 6713bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 6723bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 673d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis /* 674d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * Unwind and resolve symbols 675d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis */ 6764e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t)); 6770b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { free(funcs); }; 6786fb025e8c04bfec166ade14046458f124f3e344cAnestis Bechtsoudis memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t)); 679d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 680d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis#if !defined(__ANDROID__) 681d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis size_t funcCnt = arch_unwindStack(pid, funcs); 682d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis arch_bfdResolveSyms(pid, funcs, funcCnt); 683d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis#else 684d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis size_t funcCnt = arch_unwindStack(pid, funcs); 685d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis#endif 686d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 68723ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 68823ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki * If unwinder failed (zero frames), use PC from ptrace GETREGS if not zero. 689c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis * If PC reg zero, temporarily disable uniqueness flag since callstack 690c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis * hash will be also zero, thus not safe for unique decisions. 691c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis */ 692c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis if (funcCnt == 0) { 693c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis if (pc) { 694c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis /* Manually update major frame PC & frames counter */ 6954e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs[0].pc = (void*)(uintptr_t)pc; 696c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis funcCnt = 1; 697c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } else { 698c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis saveUnique = false; 699c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } 700c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis } 701c45db7fc0013ac67e4ac98add8f4278e1aa2f93cAnestis Bechtsoudis 70223ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 7032013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * Temp local copy of previous backtrace value in case worker hit crashes into multiple 7042013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * tids for same target master thread. Will be 0 for first crash against target. 7052013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis */ 706e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki uint64_t oldBacktrace = run->backtrace; 7072013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis 708d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis /* 709d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis * Calculate backtrace callstack hash signature 710d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis */ 71178633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_hashCallstack(run, funcs, funcCnt, saveUnique); 712d4b8fe91d8f0cc84e2b499fa4057c420b2b74f59Anestis Bechtsoudis 713a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis /* 714a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis * If fuzzing with sanitizer coverage feedback increase crashes counter used 715a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis * as metric for dynFile evolution 716a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis */ 71778633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->useSanCov) { 718e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->sanCovCnts.crashesCnt++; 719a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis } 720a16f70fd00bbfe175cff200fb3b95a28e741760aAnestis Bechtsoudis 72123ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 72223ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki * If unique flag is set and single frame crash, disable uniqueness for this crash 72360ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis * to always save (timestamp will be added to the filename) 72460ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis */ 72536068adbbe41bc8b9f2a7ca2052e8cb2c3542f4fAnestis Bechtsoudis if (saveUnique && (funcCnt == 1)) { 72660ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis saveUnique = false; 7270ef9000a3c6de8154989e7777c332d48bb2b9c38Anestis Bechtsoudis } 7280ef9000a3c6de8154989e7777c332d48bb2b9c38Anestis Bechtsoudis 72923ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 7302013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * If worker crashFileName member is set, it means that a tid has already crashed 7312013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * from target master thread. 7322013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis */ 733e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (run->crashFileName[0] != '\0') { 7342013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis LOG_D("Multiple crashes detected from worker against attached tids group"); 73525262b3dbda4ddc7182ccdb2cf8965ed69ca8ea6Anestis Bechtsoudis 7362013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis /* 7372013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * If stackhashes match, don't re-analyze. This will avoid duplicates 7382013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * and prevent verifier from running multiple passes. Depth of check is 7392013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis * always 1 (last backtrace saved only per target iteration). 7402013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis */ 741e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (oldBacktrace == run->backtrace) { 7422013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis return; 7432013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis } 7442013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis } 7452013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis 7462013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis /* Increase global crashes counter */ 7472542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.crashesCnt); 7482013f25a0d1c7e8355a696cd2c396e2e32c86adfAnestis Bechtsoudis 74923ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 750ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis * Check if backtrace contains whitelisted symbol. Whitelist overrides 751ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis * both stackhash and symbol blacklist. Crash is always kept regardless 752ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis * of the status of uniqueness flag. 753d59af69918025f45fd346abed60370cf69c30eebAnestis Bechtsoudis */ 75478633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->linux.symsWl) { 75578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki char* wlSymbol = arch_btContainsSymbol( 75678633d1b907775e7067fb04332859703de72ac3fRobert Swiecki run->global->linux.symsWlCnt, run->global->linux.symsWl, funcCnt, funcs); 757ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis if (wlSymbol != NULL) { 758ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis saveUnique = false; 759ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis LOG_D("Whitelisted symbol '%s' found, skipping blacklist checks", wlSymbol); 760ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis } 761ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis } else { 762ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis /* 763ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis * Check if stackhash is blacklisted 764ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis */ 765d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki if (run->global->blacklist && (fastArray64Search(run->global->blacklist, 766d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki run->global->blacklistCnt, run->backtrace) != -1)) { 767e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("Blacklisted stack hash '%" PRIx64 "', skipping", run->backtrace); 7682542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.blCrashesCnt); 769ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis return; 770ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis } 771ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis 772ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis /* 773ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis * Check if backtrace contains blacklisted symbol 774ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis */ 77578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki char* blSymbol = arch_btContainsSymbol( 77678633d1b907775e7067fb04332859703de72ac3fRobert Swiecki run->global->linux.symsBlCnt, run->global->linux.symsBl, funcCnt, funcs); 777ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis if (blSymbol != NULL) { 778ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis LOG_I("Blacklisted symbol '%s' found, skipping", blSymbol); 7792542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.blCrashesCnt); 780ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis return; 781ba68b38c475614a7f7193533e03adfd464cfd450Anestis Bechtsoudis } 782d59af69918025f45fd346abed60370cf69c30eebAnestis Bechtsoudis } 783d59af69918025f45fd346abed60370cf69c30eebAnestis Bechtsoudis 7845a311410960d771264787b9118ee30ca7affb172Anestis Bechtsoudis /* If non-blacklisted crash detected, zero set two MSB */ 78578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki ATOMIC_POST_ADD(run->global->dynFileIterExpire, _HF_DYNFILE_SUB_MASK); 7865a311410960d771264787b9118ee30ca7affb172Anestis Bechtsoudis 7874e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki void* sig_addr = si.si_addr; 78878633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->linux.disableRandomization == false) { 7891f2d5b194a249716fbd6f094cc335c751767fb99Jagger pc = 0UL; 7901f2d5b194a249716fbd6f094cc335c751767fb99Jagger sig_addr = NULL; 7911f2d5b194a249716fbd6f094cc335c751767fb99Jagger } 7921f2d5b194a249716fbd6f094cc335c751767fb99Jagger 793d08c85024fa513431fdf16770067420834b76814Jagger /* User-induced signals don't set si.si_addr */ 794d08c85024fa513431fdf16770067420834b76814Jagger if (SI_FROMUSER(&si)) { 7951011c9e23075da1e3246eaeb7a245144dbc1957cJagger sig_addr = NULL; 7961011c9e23075da1e3246eaeb7a245144dbc1957cJagger } 7971f2d5b194a249716fbd6f094cc335c751767fb99Jagger 79846ea10e4663744661c4a772e95110745dafec5e3Anestis Bechtsoudis /* If dry run mode, copy file with same name into workspace */ 79978633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->mutationsPerRun == 0U && run->global->useVerifier) { 800ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), "%s/%s", run->global->io.crashDir, 801e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->origFileName); 80260ea5e7dd1d45013f7ce63afd6faa9333ea7bc3aAnestis Bechtsoudis } else if (saveUnique) { 803e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), 80478633d1b907775e7067fb04332859703de72ac3fRobert Swiecki "%s/%s.PC.%" REG_PM ".STACK.%" PRIx64 ".CODE.%d.ADDR.%p.INSTR.%s.%s", 805ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki run->global->io.crashDir, arch_sigName(si.si_signo), pc, run->backtrace, si.si_code, 80682c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki sig_addr, instr, run->global->io.fileExtn); 8073bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } else { 8083bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki char localtmstr[PATH_MAX]; 80981c6a0d2338d140606491be7ec82434b8a3eb316Robert Swiecki util_getLocalTime("%F.%H:%M:%S", localtmstr, sizeof(localtmstr), time(NULL)); 810e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), 8114e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki "%s/%s.PC.%" REG_PM ".STACK.%" PRIx64 ".CODE.%d.ADDR.%p.INSTR.%s.%s.%d.%s", 812ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki run->global->io.crashDir, arch_sigName(si.si_signo), pc, run->backtrace, si.si_code, 81382c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki sig_addr, instr, localtmstr, pid, run->global->io.fileExtn); 8143bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 8153bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 816e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (files_exists(run->crashFileName)) { 817e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("It seems that '%s' already exists, skipping", run->crashFileName); 8181d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger // Clear filename so that verifier can understand we hit a duplicate 819e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki memset(run->crashFileName, 0, sizeof(run->crashFileName)); 8201d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger return; 8211d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger } 822e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 823e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (files_writeBufToFile(run->crashFileName, run->dynamicFile, run->dynamicFileSz, 824d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC) == false) { 825e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_E("Couldn't copy '%s' to '%s'", run->fileName, run->crashFileName); 826e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis return; 8273bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 828ad6af2246b9d25e66266653ed292dc03928df7a5robert.swiecki@gmail.com 829e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("Ok, that's interesting, saved '%s' as '%s'", run->fileName, run->crashFileName); 8301d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger 8312542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.uniqueCrashesCnt); 8321d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger /* If unique crash found, reset dynFile counter */ 83378633d1b907775e7067fb04332859703de72ac3fRobert Swiecki ATOMIC_CLEAR(run->global->dynFileIterExpire); 8341d74338219eefd3ff6dea33f488d1d0ddb360e04Jagger 835e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki arch_traceGenerateReport(pid, run, funcs, funcCnt, &si, instr); 8363bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki} 8373bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 8389ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis/* TODO: Add report parsing support for other sanitizers too */ 8390b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swieckistatic int arch_parseAsanReport( 840d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki run_t* run, pid_t pid, funcs_t* funcs, void** crashAddr, char** op) { 841d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki char crashReport[PATH_MAX] = {0}; 8424e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki const char* const crashReportCpy = crashReport; 84382c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki snprintf( 84482c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki crashReport, sizeof(crashReport), "%s/%s.%d", run->global->io.workDir, kLOGPREFIX, pid); 845e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 8464e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki FILE* fReport = fopen(crashReport, "rb"); 847e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (fReport == NULL) { 848c28e5ed675d22e7a209f96b4723b2d6571799f50Anestis Bechtsoudis PLOG_D("Couldn't open '%s' - R/O mode", crashReport); 849e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis return -1; 850e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 8510b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { fclose(fReport); }; 8520b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { unlink(crashReportCpy); }; 853e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 854d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki char header[35] = {0}; 855e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis snprintf(header, sizeof(header), "==%d==ERROR: AddressSanitizer:", pid); 856e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis size_t headerSz = strlen(header); 857e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis bool headerFound = false; 858e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 859e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis uint8_t frameIdx = 0; 860d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki char framePrefix[5] = {0}; 861e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis snprintf(framePrefix, sizeof(framePrefix), "#%" PRIu8, frameIdx); 862e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 863e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis char *lineptr = NULL, *cAddr = NULL; 864e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis size_t n = 0; 8650b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { free(lineptr); }; 866e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis for (;;) { 867e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (getline(&lineptr, &n, fReport) == -1) { 868e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis break; 869e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 870e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 871e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* First step is to identify header */ 872e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (headerFound == false) { 873e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if ((strlen(lineptr) > headerSz) && (strncmp(header, lineptr, headerSz) == 0)) { 874e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis headerFound = true; 875e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 876e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Parse crash address */ 877e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis cAddr = strstr(lineptr, "address 0x"); 878e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (cAddr) { 879e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis cAddr = cAddr + strlen("address "); 8804e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* endOff = strchr(cAddr, ' '); 881e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis cAddr[endOff - cAddr] = '\0'; 8824e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki *crashAddr = (void*)((size_t)strtoull(cAddr, NULL, 16)); 883e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 884e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis *crashAddr = 0x0; 885e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 886e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 887e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis continue; 888e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 8894e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* pLineLC = lineptr; 890e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Trim leading spaces */ 891ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis while (*pLineLC != '\0' && isspace(*pLineLC)) { 892ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis ++pLineLC; 893e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 894e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 8950ddd0787fa7ccc8af74fc5e2872a60b31557f862Anestis Bechtsoudis /* End separator for crash thread stack trace is an empty line */ 896ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis if ((*pLineLC == '\0') && (frameIdx != 0)) { 897e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis break; 898e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 899e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 900e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Basic length checks */ 901ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis if (strlen(pLineLC) < 10) { 902e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis continue; 903e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 904e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 905e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* If available parse the type of error (READ/WRITE) */ 906ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis if (cAddr && strstr(pLineLC, cAddr)) { 907ca556e6076f3688d7a9730320230cabc4c714f9dAnestis Bechtsoudis if (strncmp(pLineLC, "READ", 4) == 0) { 908e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis *op = "READ"; 909ca556e6076f3688d7a9730320230cabc4c714f9dAnestis Bechtsoudis } else if (strncmp(pLineLC, "WRITE", 5) == 0) { 910e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis *op = "WRITE"; 911e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 912ca556e6076f3688d7a9730320230cabc4c714f9dAnestis Bechtsoudis cAddr = NULL; 913e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 914e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 915e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Check for crash thread frames */ 916ea0bcb6620729fdad8153681bc4e694b65c93b40Anestis Bechtsoudis if (strncmp(pLineLC, framePrefix, strlen(framePrefix)) == 0) { 917e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Abort if max depth */ 918e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (frameIdx >= _HF_MAX_FUNCS) { 919e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis break; 920e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 921e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 92223ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 923e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis * Frames have following format: 924e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis #0 0xaa860177 (/system/lib/libc.so+0x196177) 925e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis */ 9264e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* savePtr = NULL; 9276b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis strtok_r(pLineLC, " ", &savePtr); 928d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki funcs[frameIdx].pc = 929d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki (void*)((size_t)strtoull(strtok_r(NULL, " ", &savePtr), NULL, 16)); 930e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 931e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* DSO & code offset parsing */ 9324e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* targetStr = strtok_r(NULL, " ", &savePtr); 9334e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* startOff = strchr(targetStr, '(') + 1; 9344e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* plusOff = strchr(targetStr, '+'); 9354e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* endOff = strrchr(targetStr, ')'); 936e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis targetStr[endOff - startOff] = '\0'; 937e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if ((startOff == NULL) || (endOff == NULL) || (plusOff == NULL)) { 9386b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis LOG_D("Invalid ASan report entry (%s)", lineptr); 939e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 940d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki size_t dsoSz = 941d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki MIN(sizeof(funcs[frameIdx].mapName), (size_t)(plusOff - startOff)); 942217836576aa0747bd53d2e4c1a59771135fb3903Anestis Bechtsoudis memcpy(funcs[frameIdx].mapName, startOff, dsoSz); 9434e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* codeOff = targetStr + (plusOff - startOff) + 1; 944e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis funcs[frameIdx].line = strtoull(codeOff, NULL, 16); 945e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 946e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 947e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis frameIdx++; 948e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis snprintf(framePrefix, sizeof(framePrefix), "#%" PRIu8, frameIdx); 949e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 950e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 951e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 952e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 953e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis return frameIdx; 954e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis} 955e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 95639bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis/* 95739bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis * Special book keeping for cases where crashes are detected based on exitcode and not 958e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis * a raised signal. Such case is the ASan fuzzing for Android. Crash file name maintains 959e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis * the same format for compatibility with post campaign tools. 96039bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis */ 961d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_traceExitSaveData(run_t* run, pid_t pid) { 962e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis REG_TYPE pc = 0; 9634e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki void* crashAddr = 0; 9644e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* op = "UNKNOWN"; 96578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki pid_t targetPid = (run->global->linux.pid > 0) ? run->global->linux.pid : run->pid; 966e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 96739bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis /* Save only the first hit for each worker */ 968e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (run->crashFileName[0] != '\0') { 96939bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis return; 97039bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis } 971ac05480ed98bd630294ce1a43325eb12eb2354a5Anestis Bechtsoudis 97239bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis /* Increase global crashes counter */ 9732542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.crashesCnt); 97478633d1b907775e7067fb04332859703de72ac3fRobert Swiecki ATOMIC_POST_AND(run->global->dynFileIterExpire, _HF_DYNFILE_SUB_MASK); 97577392728d91a8848fa9896dd7eea3d9690422417Anestis Bechtsoudis 9766b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis /* 9776b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis * If fuzzing with sanitizer coverage feedback increase crashes counter used 9786b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis * as metric for dynFile evolution 9796b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis */ 98078633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->useSanCov) { 981e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->sanCovCnts.crashesCnt++; 9826b43204f9d4f96ac4e43cb323f8b1e4bb130d065Anestis Bechtsoudis } 98339bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis 984e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* If sanitizer produces reports with stack traces (e.g. ASan), they're parsed manually */ 985e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis int funcCnt = 0; 9864e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t)); 9870b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { free(funcs); }; 9886fb025e8c04bfec166ade14046458f124f3e344cAnestis Bechtsoudis memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t)); 989e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 9909ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis /* Sanitizers save reports against parent PID */ 9919ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis if (targetPid != pid) { 9929ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis return; 9939ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis } 99478633d1b907775e7067fb04332859703de72ac3fRobert Swiecki funcCnt = arch_parseAsanReport(run, pid, funcs, &crashAddr, &op); 995c209aa5de036693718d1ed0d9e775c3c92e5d424Anestis Bechtsoudis 9969ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis /* 9979ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis * -1 error indicates a file not found for report. This is expected to happen often since 9989ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis * ASan report is generated once for crashing TID. Ptrace arch is not guaranteed to parse 9999ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis * that TID first. Not setting the 'crashFileName' variable will ensure that this branch 10009ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis * is executed again for all TIDs until the matching report is found 10019ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis */ 10029ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis if (funcCnt == -1) { 10039ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis return; 10049ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis } 10059ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis 10069ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis /* Since crash address is available, apply ignoreAddr filters */ 100778633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (crashAddr < run->global->linux.ignoreAddr) { 1008e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("'%s' is interesting, but the crash addr is %p (below %p), skipping", run->fileName, 100978633d1b907775e7067fb04332859703de72ac3fRobert Swiecki crashAddr, run->global->linux.ignoreAddr); 10109ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis return; 10119ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis } 1012e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 10139ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis /* If frames successfully recovered, calculate stack hash & populate crash PC */ 101478633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_hashCallstack(run, funcs, funcCnt, false); 10154e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki pc = (uintptr_t)funcs[0].pc; 10169ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis 10179ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis /* 101894afac6adfc35ef96bbede9fd8bcf0f2334a3dafAnestis Bechtsoudis * Check if stackhash is blacklisted 10199ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis */ 1020d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki if (run->global->blacklist && (fastArray64Search(run->global->blacklist, 1021d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki run->global->blacklistCnt, run->backtrace) != -1)) { 1022e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("Blacklisted stack hash '%" PRIx64 "', skipping", run->backtrace); 10232542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.blCrashesCnt); 102494afac6adfc35ef96bbede9fd8bcf0f2334a3dafAnestis Bechtsoudis return; 1025e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 1026e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 102739bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis /* If dry run mode, copy file with same name into workspace */ 102878633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->mutationsPerRun == 0U && run->global->useVerifier) { 1029ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), "%s/%s", run->global->io.crashDir, 1030e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->origFileName); 103139bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis } else { 1032e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Keep the crashes file name format identical */ 103326fd6d58dfabe2d047d422c1098794980d59dad2Robert Swiecki if (run->backtrace != 0ULL && run->global->io.saveUnique) { 1034e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), 10354e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki "%s/%s.PC.%" REG_PM ".STACK.%" PRIx64 ".CODE.%s.ADDR.%p.INSTR.%s.%s", 1036ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki run->global->io.crashDir, "SAN", pc, run->backtrace, op, crashAddr, "[UNKNOWN]", 103782c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki run->global->io.fileExtn); 1038e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 1039e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* If no stack hash available, all crashes treated as unique */ 1040e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis char localtmstr[PATH_MAX]; 1041e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis util_getLocalTime("%F.%H:%M:%S", localtmstr, sizeof(localtmstr), time(NULL)); 1042e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki snprintf(run->crashFileName, sizeof(run->crashFileName), 10434e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki "%s/%s.PC.%" REG_PM ".STACK.%" PRIx64 ".CODE.%s.ADDR.%p.INSTR.%s.%s.%s", 1044ced3ebaa5a4a96185dc92a40c98f6dbb8728743bRobert Swiecki run->global->io.crashDir, "SAN", pc, run->backtrace, op, crashAddr, "[UNKNOWN]", 104582c707ccd07e9b6bb8eea2cea6d031a968fd33eaRobert Swiecki localtmstr, run->global->io.fileExtn); 1046e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 104739bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis } 104839bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis 104939bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis bool dstFileExists = false; 1050e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (files_copyFile(run->fileName, run->crashFileName, &dstFileExists, true /* try_link */)) { 1051e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("Ok, that's interesting, saved '%s' as '%s'", run->fileName, run->crashFileName); 105239bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis 105339bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis /* Increase unique crashes counters */ 10542542dc097ea7f48c3bd3e250071687f29ee34e9fRobert Swiecki ATOMIC_POST_INC(run->global->cnts.uniqueCrashesCnt); 105578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki ATOMIC_CLEAR(run->global->dynFileIterExpire); 105639bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis } else { 1057e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (dstFileExists) { 1058e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_I("It seems that '%s' already exists, skipping", run->crashFileName); 1059e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 1060e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Clear stack hash so that verifier can understand we hit a duplicate */ 1061e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->backtrace = 0ULL; 1062e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 1063e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki LOG_E("Couldn't copy '%s' to '%s'", run->fileName, run->crashFileName); 1064e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 10650b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki /* In case of write error, clear crashFileName to so that other monitored TIDs can retry 10660b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki */ 1067e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki memset(run->crashFileName, 0, sizeof(run->crashFileName)); 1068e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 1069e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis 1070e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Don't bother generating reports for duplicate or non-saved crashes */ 107139bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis return; 107239bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis } 107339bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis 1074e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis /* Generate report */ 1075e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki run->report[0] = '\0'; 1076e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "EXIT_CODE: %s\n", HF_SAN_EXIT_CODE); 1077e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "ORIG_FNAME: %s\n", run->origFileName); 1078e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "FUZZ_FNAME: %s\n", run->crashFileName); 1079e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "PID: %d\n", pid); 1080e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "OPERATION: %s\n", op); 1081e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "FAULT ADDRESS: %p\n", crashAddr); 1082e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis if (funcCnt > 0) { 1083e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "STACK HASH: %016llx\n", run->backtrace); 1084e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "STACK:\n"); 1085e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis for (int i = 0; i < funcCnt; i++) { 1086e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), " <" REG_PD REG_PM "> ", 10874e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki (REG_TYPE)(long)funcs[i].pc); 1088217836576aa0747bd53d2e4c1a59771135fb3903Anestis Bechtsoudis if (funcs[i].mapName[0] != '\0') { 1089e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "[%s + 0x%x]\n", funcs[i].mapName, 1090e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki funcs[i].line); 1091e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } else { 1092e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki util_ssnprintf(run->report, sizeof(run->report), "[]\n"); 1093e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 1094e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 1095e5208106fe75cc37bc8655e67511d44731765051Anestis Bechtsoudis } 109639bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis} 109739bf6cf7b6dea9ecaf0a2dbb126760582f4ba31fAnestis Bechtsoudis 1098d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_traceExitAnalyzeData(run_t* run, pid_t pid) { 10994e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki void* crashAddr = 0; 11004e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki char* op = "UNKNOWN"; 110197633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis int funcCnt = 0; 11024e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki funcs_t* funcs = util_Malloc(_HF_MAX_FUNCS * sizeof(funcs_t)); 11030b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { free(funcs); }; 11046fb025e8c04bfec166ade14046458f124f3e344cAnestis Bechtsoudis memset(funcs, 0, _HF_MAX_FUNCS * sizeof(funcs_t)); 110597633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis 110678633d1b907775e7067fb04332859703de72ac3fRobert Swiecki funcCnt = arch_parseAsanReport(run, pid, funcs, &crashAddr, &op); 110797633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis 110823ec02a25410945a30a76b7b6f53c6302de96e75Robert Swiecki /* 110997633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis * -1 error indicates a file not found for report. This is expected to happen often since 111097633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis * ASan report is generated once for crashing TID. Ptrace arch is not guaranteed to parse 111197633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis * that TID first. Not setting the 'crashFileName' variable will ensure that this branch 111297633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis * is executed again for all TIDs until the matching report is found 111397633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis */ 111497633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis if (funcCnt == -1) { 111597633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis return; 111697633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis } 111797633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis 111897633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis /* If frames successfully recovered, calculate stack hash & populate crash PC */ 111978633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_hashCallstack(run, funcs, funcCnt, false); 112097633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis} 112197633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis 1122d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckivoid arch_traceExitAnalyze(run_t* run, pid_t pid) { 1123e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (run->mainWorker) { 112497633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis /* Main fuzzing threads */ 112578633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_traceExitSaveData(run, pid); 112697633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis } else { 112797633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis /* Post crash analysis (e.g. crashes verifier) */ 112878633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_traceExitAnalyzeData(run, pid); 112997633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis } 113097633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis} 113197633ccbc54c47858efcedda15a038af0864bd16Anestis Bechtsoudis 1132a5a5c7b33295450a96682d71d4690d4c4343a006Jagger#define __WEVENT(status) ((status & 0xFF0000) >> 16) 1133d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic void arch_traceEvent(run_t* run, int status, pid_t pid) { 1134c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_D("PID: %d, Ptrace event: %d", pid, __WEVENT(status)); 1135dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger switch (__WEVENT(status)) { 1136d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki case PTRACE_EVENT_EXIT: { 1137d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki unsigned long event_msg; 1138d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &event_msg) == -1) { 1139d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki PLOG_E("ptrace(PTRACE_GETEVENTMSG,%d) failed", pid); 1140d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki return; 1141d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki } 11425de55a2b8ecf248ad78f829008ac5c30519cbee2Jagger 1143d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki if (WIFEXITED(event_msg)) { 1144d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki LOG_D("PID: %d exited with exit_code: %lu", pid, 1145d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki (unsigned long)WEXITSTATUS(event_msg)); 1146d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki if (WEXITSTATUS(event_msg) == (unsigned long)HF_SAN_EXIT_CODE) { 1147d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki arch_traceExitAnalyze(run, pid); 1148d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki } 1149d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki } else if (WIFSIGNALED(event_msg)) { 1150d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki LOG_D( 1151d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki "PID: %d terminated with signal: %lu", pid, (unsigned long)WTERMSIG(event_msg)); 1152d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki } else { 1153d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki LOG_D("PID: %d exited with unknown status: %lu", pid, event_msg); 1154dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger } 1155d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki } break; 1156d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki default: 1157d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki break; 1158dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger } 1159dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger 1160a0df592ba4f3ed3c1c04efbe422caa9c380c7053Jagger ptrace(PTRACE_CONT, pid, 0, 0); 1161a5a5c7b33295450a96682d71d4690d4c4343a006Jagger} 1162a5a5c7b33295450a96682d71d4690d4c4343a006Jagger 1163d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckivoid arch_traceAnalyze(run_t* run, int status, pid_t pid) { 11643bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki /* 1165a5a5c7b33295450a96682d71d4690d4c4343a006Jagger * It's a ptrace event, deal with it elsewhere 11663bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki */ 1167a5a5c7b33295450a96682d71d4690d4c4343a006Jagger if (WIFSTOPPED(status) && __WEVENT(status)) { 116878633d1b907775e7067fb04332859703de72ac3fRobert Swiecki return arch_traceEvent(run, status, pid); 11693bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 11703bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 1171a5a5c7b33295450a96682d71d4690d4c4343a006Jagger if (WIFSTOPPED(status)) { 1172a5a5c7b33295450a96682d71d4690d4c4343a006Jagger /* 1173a5a5c7b33295450a96682d71d4690d4c4343a006Jagger * If it's an interesting signal, save the testcase 1174a5a5c7b33295450a96682d71d4690d4c4343a006Jagger */ 1175f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis if (arch_sigs[WSTOPSIG(status)].important) { 11766b9e83de10dd9812eccfffb48ee1f56efcbd9c4aAnestis Bechtsoudis /* 11776b9e83de10dd9812eccfffb48ee1f56efcbd9c4aAnestis Bechtsoudis * If fuzzer worker is from core fuzzing process run full 11786b9e83de10dd9812eccfffb48ee1f56efcbd9c4aAnestis Bechtsoudis * analysis. Otherwise just unwind and get stack hash signature. 11796b9e83de10dd9812eccfffb48ee1f56efcbd9c4aAnestis Bechtsoudis */ 1180e7294caf2461dcc9a7b666e8a62d516b8663206cRobert Swiecki if (run->mainWorker) { 118178633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_traceSaveData(run, pid); 11826b9e83de10dd9812eccfffb48ee1f56efcbd9c4aAnestis Bechtsoudis } else { 118378633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_traceAnalyzeData(run, pid); 11845c86ebc569dff1d715fc114de8ab308e9f4b89f3Anestis Bechtsoudis } 1185a5a5c7b33295450a96682d71d4690d4c4343a006Jagger } 1186cf03fc10df32d99d33266488bbcc6284b4d82652Robert Swiecki /* Do not deliver SIGSTOP, as we don't support PTRACE_LISTEN anyway */ 1187cf03fc10df32d99d33266488bbcc6284b4d82652Robert Swiecki int sig = (WSTOPSIG(status) != SIGSTOP) ? WSTOPSIG(status) : 0; 1188cf03fc10df32d99d33266488bbcc6284b4d82652Robert Swiecki ptrace(PTRACE_CONT, pid, 0, sig); 118922e66a9fc45532d2b663764a2d24abcec0561af7robert.swiecki@gmail.com return; 11903bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 11913bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 11923bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki /* 11933bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki * Resumed by delivery of SIGCONT 11943bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki */ 11953bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki if (WIFCONTINUED(status)) { 119622e66a9fc45532d2b663764a2d24abcec0561af7robert.swiecki@gmail.com return; 11973bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 11983bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 11993bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki /* 1200124ba814038bb69717dff75455772fa301ee9e22robert.swiecki@gmail.com * Process exited 12013bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki */ 1202dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger if (WIFEXITED(status)) { 12033e0ea96d416c371212f36237e183ddab874b0390Anestis Bechtsoudis /* 12043e0ea96d416c371212f36237e183ddab874b0390Anestis Bechtsoudis * Target exited with sanitizer defined exitcode (used when SIGABRT is not monitored) 12053e0ea96d416c371212f36237e183ddab874b0390Anestis Bechtsoudis */ 12069ea67cbd04e874ba33573f1dc01818cce8e887e8Anestis Bechtsoudis if (WEXITSTATUS(status) == (unsigned long)HF_SAN_EXIT_CODE) { 120778633d1b907775e7067fb04332859703de72ac3fRobert Swiecki arch_traceExitAnalyze(run, pid); 12083e0ea96d416c371212f36237e183ddab874b0390Anestis Bechtsoudis } 1209dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger return; 1210dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger } 1211dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger 1212dbc4a15c0efdad486d4cf928d6362307f7ca81b2Jagger if (WIFSIGNALED(status)) { 121322e66a9fc45532d2b663764a2d24abcec0561af7robert.swiecki@gmail.com return; 12143bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki } 12153bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 12164e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki abort(); /* NOTREACHED */ 12173bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki} 12183bb518cae7801e061cacd770b15d6d8982d94bcrobert.swiecki 1219d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckistatic bool arch_listThreads(int tasks[], size_t thrSz, int pid) { 12205f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com char path[512]; 12215f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com snprintf(path, sizeof(path), "/proc/%d/task", pid); 12221bbe840db82a66ac115c2f5951e705a9549369d7Jagger 12231bbe840db82a66ac115c2f5951e705a9549369d7Jagger /* An optimization, the number of threads is st.st_nlink - 2 (. and ..) */ 12241bbe840db82a66ac115c2f5951e705a9549369d7Jagger struct stat st; 12251bbe840db82a66ac115c2f5951e705a9549369d7Jagger if (stat(path, &st) != -1) { 12261bbe840db82a66ac115c2f5951e705a9549369d7Jagger if (st.st_nlink == 3) { 12271bbe840db82a66ac115c2f5951e705a9549369d7Jagger tasks[0] = pid; 12281bbe840db82a66ac115c2f5951e705a9549369d7Jagger tasks[1] = 0; 12291bbe840db82a66ac115c2f5951e705a9549369d7Jagger return true; 12301bbe840db82a66ac115c2f5951e705a9549369d7Jagger } 12311bbe840db82a66ac115c2f5951e705a9549369d7Jagger } 12321bbe840db82a66ac115c2f5951e705a9549369d7Jagger 12331bbe840db82a66ac115c2f5951e705a9549369d7Jagger size_t count = 0; 12344e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki DIR* dir = opendir(path); 12355f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com if (!dir) { 1236c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_E("Couldn't open dir '%s'", path); 12375f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com return false; 12385f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12390b5661142ce282754e8c22e02ea8e9d66036ae58Robert Swiecki defer { closedir(dir); }; 12405f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 12415f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com for (;;) { 1242acd1cdbed3f16f2186d00b799402c7fc9736bac6Robert Swiecki errno = 0; 12434e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki struct dirent* res = readdir(dir); 1244acd1cdbed3f16f2186d00b799402c7fc9736bac6Robert Swiecki if (res == NULL && errno != 0) { 1245c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_E("Couldn't read contents of '%s'", path); 12465f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com return false; 12475f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12485f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 12495f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com if (res == NULL) { 12505f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com break; 12515f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12525f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 12534e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki pid_t pid = (pid_t)strtol(res->d_name, (char**)NULL, 10); 12545f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com if (pid == 0) { 1255c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_D("The following dir entry couldn't be converted to pid_t '%s'", res->d_name); 12565f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com continue; 12575f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12585f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 12595f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com tasks[count++] = pid; 1260c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_D("Added pid '%d' from '%s/%s'", pid, path, res->d_name); 12615f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 12625f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com if (count >= thrSz) { 12635f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com break; 12645f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12655f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 1266c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki PLOG_D("Total number of threads in pid '%d': '%zd'", pid, count); 12675f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com tasks[count + 1] = 0; 12685f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com if (count < 1) { 12695f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com return false; 12705f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com } 12715f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com return true; 12725f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com} 12735f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com 1274d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckibool arch_traceWaitForPidStop(pid_t pid) { 12753aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger for (;;) { 12763aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger int status; 1277e79c47525e9b581c673a89913e330b409298bad2Jagger pid_t ret = wait4(pid, &status, __WALL | WUNTRACED, NULL); 12783aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger if (ret == -1 && errno == EINTR) { 12793aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger continue; 12803aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger } 12813aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger if (ret == -1) { 128239cb9a724de1112cc3dea10ab9404808197c458cJagger PLOG_W("wait4(pid=%d) failed", pid); 128339cb9a724de1112cc3dea10ab9404808197c458cJagger return false; 12843aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger } 128539cb9a724de1112cc3dea10ab9404808197c458cJagger if (!WIFSTOPPED(status)) { 128639cb9a724de1112cc3dea10ab9404808197c458cJagger LOG_W("PID %d not in a stopped state - status:%d", pid, status); 128739cb9a724de1112cc3dea10ab9404808197c458cJagger return false; 1288d695262cfc0db52dbc79aa7f469cb3593784274bJagger } 128939cb9a724de1112cc3dea10ab9404808197c458cJagger return true; 12903aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger } 12913aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger} 12923aacd58aca8931e6b54e4d2b684b3c283593afb8Jagger 12934f9d479548dad8529ac19d601e5df89efc17641bJagger#define MAX_THREAD_IN_TASK 4096 1294d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckibool arch_traceAttach(run_t* run, pid_t pid) { 129554adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki/* 129654adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki * It should be present since, at least, Linux kernel 3.8, but 129754adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki * not always defined in kernel-headers 129854adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki */ 129954adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki#if !defined(PTRACE_O_EXITKILL) 130054adb764906a304c9a3a2e3f435fb54f754a3a7dRobert Swiecki#define PTRACE_O_EXITKILL (1 << 20) 13014e595fb320d85cc29abe1cf38bea8eb04bfd301dRobert Swiecki#endif /* !defined(PTRACE_O_EXITKILL) */ 1302746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki long seize_options = PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK; 130378633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->linux.pid == 0) { 130420b0d0bb9627b335a88a74078efd389ace87f7c0Robert Swiecki seize_options |= PTRACE_O_EXITKILL; 130520b0d0bb9627b335a88a74078efd389ace87f7c0Robert Swiecki } 1306746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki /* The event is only used with sanitizers */ 130778633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->enableSanitizers) { 1308746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki seize_options |= PTRACE_O_TRACEEXIT; 1309746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki } 1310ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger 131178633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->linux.pid == 0 && arch_traceWaitForPidStop(pid) == false) { 13121c9d809c9dc2ed9d0983c5d87776fc250102675dRobert Swiecki return false; 13131c9d809c9dc2ed9d0983c5d87776fc250102675dRobert Swiecki } 13141c9d809c9dc2ed9d0983c5d87776fc250102675dRobert Swiecki 1315ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger if (ptrace(PTRACE_SEIZE, pid, NULL, seize_options) == -1) { 131603a507ebde56b6a7a91fbbf24c7b4c936a833e4bJagger PLOG_W("Couldn't ptrace(PTRACE_SEIZE) to pid: %d", pid); 1317ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger return false; 1318ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger } 131903a507ebde56b6a7a91fbbf24c7b4c936a833e4bJagger 13209402137bb77538503e6f0dc09f299103907dae2aJagger LOG_D("Attached to PID: %d", pid); 1321ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger 1322746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki /* It only makes sense to attach to threads with -p */ 132378633d1b907775e7067fb04332859703de72ac3fRobert Swiecki if (run->global->linux.pid == 0) { 1324746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki return true; 1325746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki } 1326746eaf040947790147b7ad5fc2875b33efe3b718Robert Swiecki 1327d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki int tasks[MAX_THREAD_IN_TASK + 1] = {0}; 1328d526d31c9c86779f0d245cb950726a2142bcce8erobert.swiecki@gmail.com if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) { 1329c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_E("Couldn't read thread list for pid '%d'", pid); 133028cba5cf23eb6edc5515bf320b10bb1286bb3df1robert.swiecki return false; 133128cba5cf23eb6edc5515bf320b10bb1286bb3df1robert.swiecki } 133228cba5cf23eb6edc5515bf320b10bb1286bb3df1robert.swiecki 13335f667521866d77bb5a0a76527b95046fdc98cbb7robert.swiecki@gmail.com for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { 1334ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger if (tasks[i] == pid) { 1335ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger continue; 1336ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger } 1337ea9595d37bfa5823532f275857a23cd9a814a6d7Jagger if (ptrace(PTRACE_SEIZE, tasks[i], NULL, seize_options) == -1) { 133803a507ebde56b6a7a91fbbf24c7b4c936a833e4bJagger PLOG_W("Couldn't ptrace(PTRACE_SEIZE) to pid: %d", tasks[i]); 1339c2bde39714e16e86d9a1259dab08f73cda269964Jagger continue; 1340c2bde39714e16e86d9a1259dab08f73cda269964Jagger } 13419402137bb77538503e6f0dc09f299103907dae2aJagger LOG_D("Attached to PID: %d (thread_group:%d)", tasks[i], pid); 13427faf6f49114cdfb23d2e696961fa3ada807da78bJagger } 134328cba5cf23eb6edc5515bf320b10bb1286bb3df1robert.swiecki return true; 134428cba5cf23eb6edc5515bf320b10bb1286bb3df1robert.swiecki} 13454f9d479548dad8529ac19d601e5df89efc17641bJagger 1346d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckivoid arch_traceDetach(pid_t pid) { 13478b76934f112fdbca5cd6b902c1cc503a677bc47cRobert Swiecki if (syscall(__NR_kill, pid, 0) == -1 && errno == ESRCH) { 1348c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_D("PID: %d no longer exists", pid); 1349ebc7479588bc8ae3f67a762ff0be1c7d01729e38Jagger return; 1350ebc7479588bc8ae3f67a762ff0be1c7d01729e38Jagger } 1351ebc7479588bc8ae3f67a762ff0be1c7d01729e38Jagger 1352d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swiecki int tasks[MAX_THREAD_IN_TASK + 1] = {0}; 13534f9d479548dad8529ac19d601e5df89efc17641bJagger if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) { 1354c8c32dbf6444e4b7d27db38f40beb1bf904830b2Robert Swiecki LOG_E("Couldn't read thread list for pid '%d'", pid); 13554f9d479548dad8529ac19d601e5df89efc17641bJagger return; 13564f9d479548dad8529ac19d601e5df89efc17641bJagger } 13574f9d479548dad8529ac19d601e5df89efc17641bJagger 13584f9d479548dad8529ac19d601e5df89efc17641bJagger for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) { 13594f9d479548dad8529ac19d601e5df89efc17641bJagger ptrace(PTRACE_INTERRUPT, tasks[i], NULL, NULL); 1360019de49cb1a0901019839e0218174a0f7bf838e1Robert Swiecki arch_traceWaitForPidStop(tasks[i]); 13614f9d479548dad8529ac19d601e5df89efc17641bJagger ptrace(PTRACE_DETACH, tasks[i], NULL, NULL); 13624f9d479548dad8529ac19d601e5df89efc17641bJagger } 13634f9d479548dad8529ac19d601e5df89efc17641bJagger} 1364f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis 1365d50ed4254e9260cd0b4ddb5f6608ec54447ec08dRobert Swieckivoid arch_traceSignalsInit(honggfuzz_t* hfuzz) { 1366f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis /* Default is true for all platforms except Android */ 1367f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis arch_sigs[SIGABRT].important = hfuzz->monitorSIGABRT; 1368f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis 1369f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis /* Default is false */ 1370eba27171213942cb463e68f04ad2f2b70012d106Robert Swiecki arch_sigs[SIGVTALRM].important = hfuzz->timing.tmoutVTALRM; 1371f1b6e89a45eb74ec2de816f82b682093421aa1e1Anestis Bechtsoudis} 1372