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