/ tools / FunctionAllowlist.cpp
FunctionAllowlist.cpp
  1  /*
  2   * Copyright (C) 2014-2020 Apple Inc. 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
  6   * are met:
  7   * 1. Redistributions of source code must retain the above copyright
  8   *    notice, this list of conditions and the following disclaimer.
  9   * 2. Redistributions in binary form must reproduce the above copyright
 10   *    notice, this list of conditions and the following disclaimer in the
 11   *    documentation and/or other materials provided with the distribution.
 12   *
 13   * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23   * THE POSSIBILITY OF SUCH DAMAGE.
 24   */
 25  
 26  #include "config.h"
 27  #include "FunctionAllowlist.h"
 28  
 29  #if ENABLE(JIT)
 30  
 31  #include "CodeBlock.h"
 32  #include <stdio.h>
 33  #include <string.h>
 34  
 35  namespace JSC {
 36  
 37  FunctionAllowlist::FunctionAllowlist(const char* filename)
 38  {
 39      if (!filename)
 40          return;
 41  
 42      FILE* f = fopen(filename, "r");
 43      if (!f) {
 44          if (errno == ENOENT) {
 45              m_hasActiveAllowlist = true;
 46              m_entries.add(filename);
 47          } else
 48              dataLogF("Failed to open file %s. Did you add the file-read-data entitlement to WebProcess.sb? Error code: %s\n", filename, strerror(errno));
 49          return;
 50      }
 51  
 52      m_hasActiveAllowlist = true;
 53  
 54      char* line;
 55      char buffer[BUFSIZ];
 56      while ((line = fgets(buffer, sizeof(buffer), f))) {
 57          if (strstr(line, "//") == line)
 58              continue;
 59  
 60          // Get rid of newlines at the ends of the strings.
 61          size_t length = strlen(line);
 62          if (line[length - 1] == '\n') {
 63              line[length - 1] = '\0';
 64              length--;
 65          }
 66  
 67          // Skip empty lines.
 68          if (!length)
 69              continue;
 70          
 71          m_entries.add(String(line, length));
 72      }
 73  
 74      int result = fclose(f);
 75      if (result)
 76          dataLogF("Failed to close file %s: %s\n", filename, strerror(errno));
 77  }
 78  
 79  bool FunctionAllowlist::contains(CodeBlock* codeBlock) const
 80  {
 81      if (!m_hasActiveAllowlist)
 82          return true;
 83  
 84      if (m_entries.isEmpty())
 85          return false;
 86  
 87      String name = String::fromUTF8(codeBlock->inferredName());
 88      if (m_entries.contains(name))
 89          return true;
 90  
 91      String hash = String::fromUTF8(codeBlock->hashAsStringIfPossible());
 92      if (m_entries.contains(hash))
 93          return true;
 94  
 95      return m_entries.contains(name + '#' + hash);
 96  }
 97  
 98  } // namespace JSC
 99  
100  #endif // ENABLE(JIT)
101