toolkit/crashreporter/google-breakpad/src/common/mac/macho_walker.cc

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 // Copyright (c) 2006, Google Inc.
     2 // All rights reserved.
     3 //
     4 // Redistribution and use in source and binary forms, with or without
     5 // modification, are permitted provided that the following conditions are
     6 // met:
     7 //
     8 //     * Redistributions of source code must retain the above copyright
     9 // notice, this list of conditions and the following disclaimer.
    10 //     * Redistributions in binary form must reproduce the above
    11 // copyright notice, this list of conditions and the following disclaimer
    12 // in the documentation and/or other materials provided with the
    13 // distribution.
    14 //     * Neither the name of Google Inc. nor the names of its
    15 // contributors may be used to endorse or promote products derived from
    16 // this software without specific prior written permission.
    17 //
    18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    30 // macho_walker.cc: Iterate over the load commands in a mach-o file
    31 //
    32 // See macho_walker.h for documentation
    33 //
    34 // Author: Dan Waylonis
    36 extern "C" {  // necessary for Leopard
    37   #include <assert.h>
    38   #include <fcntl.h>
    39   #include <mach-o/arch.h>
    40   #include <mach-o/loader.h>
    41   #include <mach-o/swap.h>
    42   #include <string.h>
    43   #include <unistd.h>
    44 }
    46 #include "common/mac/byteswap.h"
    47 #include "common/mac/macho_walker.h"
    48 #include "common/mac/macho_utilities.h"
    50 namespace MacFileUtilities {
    52 MachoWalker::MachoWalker(const char *path, LoadCommandCallback callback,
    53                          void *context)
    54     : file_(0),
    55       memory_(NULL),
    56       memory_size_(0),
    57       callback_(callback),
    58       callback_context_(context),
    59       current_header_(NULL),
    60       current_header_size_(0),
    61       current_header_offset_(0) {
    62   file_ = open(path, O_RDONLY);
    63 }
    65 MachoWalker::MachoWalker(void *memory, size_t size,
    66                          LoadCommandCallback callback, void *context)
    67     : file_(0),
    68       memory_(memory),
    69       memory_size_(size),
    70       callback_(callback),
    71       callback_context_(context),
    72       current_header_(NULL),
    73       current_header_size_(0),
    74       current_header_offset_(0) {
    75 }
    77 MachoWalker::~MachoWalker() {
    78   if (file_ != -1)
    79     close(file_);
    80 }
    82 bool MachoWalker::WalkHeader(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) {
    83   cpu_type_t valid_cpu_type = cpu_type;
    84   cpu_subtype_t valid_cpu_subtype = cpu_subtype;
    85   // if |cpu_type| is 0, use the native cpu type.
    86   if (cpu_type == 0) {
    87     const NXArchInfo *arch = NXGetLocalArchInfo();
    88     assert(arch);
    89     valid_cpu_type = arch->cputype;
    90     valid_cpu_subtype = CPU_SUBTYPE_MULTIPLE;
    91   }
    92   off_t offset;
    93   if (FindHeader(valid_cpu_type, valid_cpu_subtype, offset)) {
    94     if (cpu_type & CPU_ARCH_ABI64)
    95       return WalkHeader64AtOffset(offset);
    97     return WalkHeaderAtOffset(offset);
    98   }
   100   return false;
   101 }
   103 bool MachoWalker::ReadBytes(void *buffer, size_t size, off_t offset) {
   104   if (memory_) {
   105     if (offset < 0)
   106       return false;
   107     bool result = true;
   108     if (offset + size > memory_size_) {
   109       if (static_cast<size_t>(offset) >= memory_size_)
   110         return false;
   111       size = memory_size_ - static_cast<size_t>(offset);
   112       result = false;
   113     }
   114     memcpy(buffer, static_cast<char *>(memory_) + offset, size);
   115     return result;
   116   } else {
   117     return pread(file_, buffer, size, offset) == (ssize_t)size;
   118   }
   119 }
   121 bool MachoWalker::CurrentHeader(struct mach_header_64 *header, off_t *offset) {
   122   if (current_header_) {
   123     memcpy(header, current_header_, sizeof(mach_header_64));
   124     *offset = current_header_offset_;
   125     return true;
   126   }
   128   return false;
   129 }
   131 bool MachoWalker::FindHeader(cpu_type_t cpu_type,
   132                              cpu_subtype_t cpu_subtype,
   133                              off_t &offset) {
   134   // Read the magic bytes that's common amongst all mach-o files
   135   uint32_t magic;
   136   if (!ReadBytes(&magic, sizeof(magic), 0))
   137     return false;
   139   offset = sizeof(magic);
   141   // Figure out what type of file we've got
   142   bool is_fat = false;
   143   if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
   144     is_fat = true;
   145   }
   146   else if (magic != MH_MAGIC && magic != MH_CIGAM && magic != MH_MAGIC_64 &&
   147            magic != MH_CIGAM_64) {
   148     return false;
   149   }
   151   if (!is_fat) {
   152     // If we don't have a fat header, check if the cpu type matches the single
   153     // header
   154     struct mach_header header;
   155     if (!ReadBytes(&header, sizeof(header), 0))
   156       return false;
   158     if (magic == MH_CIGAM || magic == MH_CIGAM_64)
   159       swap_mach_header(&header, NXHostByteOrder());
   161     if (cpu_type != header.cputype ||
   162         (cpu_subtype != CPU_SUBTYPE_MULTIPLE &&
   163          cpu_subtype != header.cpusubtype)) {
   164       return false;
   165     }
   167     offset = 0;
   168     return true;
   169   } else {
   170     // Read the fat header and find an appropriate architecture
   171     offset = 0;
   172     struct fat_header fat;
   173     if (!ReadBytes(&fat, sizeof(fat), offset))
   174       return false;
   176     if (NXHostByteOrder() != NX_BigEndian)
   177       swap_fat_header(&fat, NXHostByteOrder());
   179     offset += sizeof(fat);
   181     // Search each architecture for the desired one
   182     struct fat_arch arch;
   183     for (uint32_t i = 0; i < fat.nfat_arch; ++i) {
   184       if (!ReadBytes(&arch, sizeof(arch), offset))
   185         return false;
   187       if (NXHostByteOrder() != NX_BigEndian)
   188         swap_fat_arch(&arch, 1, NXHostByteOrder());
   190       if (arch.cputype == cpu_type &&
   191           (cpu_subtype == CPU_SUBTYPE_MULTIPLE ||
   192            arch.cpusubtype == cpu_subtype)) {
   193         offset = arch.offset;
   194         return true;
   195       }
   197       offset += sizeof(arch);
   198     }
   199   }
   201   return false;
   202 }
   204 bool MachoWalker::WalkHeaderAtOffset(off_t offset) {
   205   struct mach_header header;
   206   if (!ReadBytes(&header, sizeof(header), offset))
   207     return false;
   209   bool swap = (header.magic == MH_CIGAM);
   210   if (swap)
   211     swap_mach_header(&header, NXHostByteOrder());
   213   // Copy the data into the mach_header_64 structure.  Since the 32-bit and
   214   // 64-bit only differ in the last field (reserved), this is safe to do.
   215   struct mach_header_64 header64;
   216   memcpy((void *)&header64, (const void *)&header, sizeof(header));
   217   header64.reserved = 0;
   219   current_header_ = &header64;
   220   current_header_size_ = sizeof(header); // 32-bit, not 64-bit
   221   current_header_offset_ = offset;
   222   offset += current_header_size_;
   223   bool result = WalkHeaderCore(offset, header.ncmds, swap);
   224   current_header_ = NULL;
   225   current_header_size_ = 0;
   226   current_header_offset_ = 0;
   227   return result;
   228 }
   230 bool MachoWalker::WalkHeader64AtOffset(off_t offset) {
   231   struct mach_header_64 header;
   232   if (!ReadBytes(&header, sizeof(header), offset))
   233     return false;
   235   bool swap = (header.magic == MH_CIGAM_64);
   236   if (swap)
   237     breakpad_swap_mach_header_64(&header, NXHostByteOrder());
   239   current_header_ = &header;
   240   current_header_size_ = sizeof(header);
   241   current_header_offset_ = offset;
   242   offset += current_header_size_;
   243   bool result = WalkHeaderCore(offset, header.ncmds, swap);
   244   current_header_ = NULL;
   245   current_header_size_ = 0;
   246   current_header_offset_ = 0;
   247   return result;
   248 }
   250 bool MachoWalker::WalkHeaderCore(off_t offset, uint32_t number_of_commands,
   251                                  bool swap) {
   252   for (uint32_t i = 0; i < number_of_commands; ++i) {
   253     struct load_command cmd;
   254     if (!ReadBytes(&cmd, sizeof(cmd), offset))
   255       return false;
   257     if (swap)
   258       swap_load_command(&cmd, NXHostByteOrder());
   260     // Call the user callback
   261     if (callback_ && !callback_(this, &cmd, offset, swap, callback_context_))
   262       break;
   264     offset += cmd.cmdsize;
   265   }
   267   return true;
   268 }
   270 }  // namespace MacFileUtilities

mercurial