| 1884 | | static zend_op_array *xc_compile_file_ex(xc_compiler_t *compiler, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
| | 1896 | typedef struct xc_sandboxed_compiler_t { /* {{{ */ |
| | 1897 | xc_compiler_t *compiler; |
| | 1898 | /* input */ |
| | 1899 | zend_file_handle *h; |
| | 1900 | int type; |
| | 1901 | |
| | 1902 | /* sandbox output */ |
| | 1903 | xc_entry_php_t *stored_entry; |
| | 1904 | xc_entry_data_php_t *stored_php; |
| | 1905 | } xc_sandboxed_compiler_t; /* {{{ */ |
| | 1906 | |
| | 1907 | static zend_op_array *xc_compile_file_sandboxed(void *data TSRMLS_DC) /* {{{ */ |
| | 1908 | { |
| | 1909 | xc_sandboxed_compiler_t *sandboxed_compiler = (xc_sandboxed_compiler_t *) data; |
| | 1910 | xc_compiler_t *compiler = sandboxed_compiler->compiler; |
| | 1911 | zend_bool catched = 0; |
| | 1912 | xc_cache_t *cache = xc_php_caches[compiler->entry_hash.cacheid]; |
| | 1913 | xc_entry_php_t *stored_entry; |
| | 1914 | xc_entry_data_php_t *stored_php; |
| | 1915 | |
| | 1916 | /* {{{ compile */ |
| | 1917 | /* make compile inside sandbox */ |
| | 1918 | #ifdef HAVE_XCACHE_CONSTANT |
| | 1919 | compiler->new_php.constinfos = NULL; |
| | 1920 | #endif |
| | 1921 | compiler->new_php.funcinfos = NULL; |
| | 1922 | compiler->new_php.classinfos = NULL; |
| | 1923 | #ifdef ZEND_ENGINE_2_1 |
| | 1924 | compiler->new_php.autoglobals = NULL; |
| | 1925 | #endif |
| | 1926 | memset(&compiler->new_php.op_array_info, 0, sizeof(compiler->new_php.op_array_info)); |
| | 1927 | |
| | 1928 | XG(initial_compile_file_called) = 0; |
| | 1929 | zend_try { |
| | 1930 | compiler->new_php.op_array = NULL; |
| | 1931 | xc_compile_php(compiler, sandboxed_compiler->h, sandboxed_compiler->type TSRMLS_CC); |
| | 1932 | } zend_catch { |
| | 1933 | catched = 1; |
| | 1934 | } zend_end_try(); |
| | 1935 | |
| | 1936 | if (catched |
| | 1937 | || !compiler->new_php.op_array /* possible ? */ |
| | 1938 | || !XG(initial_compile_file_called)) { |
| | 1939 | goto err_aftersandbox; |
| | 1940 | } |
| | 1941 | |
| | 1942 | /* }}} */ |
| | 1943 | #ifdef SHOW_DPRINT |
| | 1944 | compiler->new_entry.php = &compiler->new_php; |
| | 1945 | xc_dprint(&compiler->new_entry, 0 TSRMLS_CC); |
| | 1946 | #endif |
| | 1947 | |
| | 1948 | stored_entry = NULL; |
| | 1949 | stored_php = NULL; |
| | 1950 | ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ |
| | 1951 | /* php_store */ |
| | 1952 | stored_php = xc_php_store_unlocked(cache, &compiler->new_php TSRMLS_CC); |
| | 1953 | if (!stored_php) { |
| | 1954 | /* error */ |
| | 1955 | break; |
| | 1956 | } |
| | 1957 | /* entry_store */ |
| | 1958 | compiler->new_entry.php = stored_php; |
| | 1959 | stored_entry = xc_entry_php_store_unlocked(cache, compiler->entry_hash.entryslotid, &compiler->new_entry TSRMLS_CC); |
| | 1960 | if (stored_entry) { |
| | 1961 | xc_php_addref_unlocked(stored_php); |
| | 1962 | TRACE(" cached %d:%s, holding", compiler->new_entry.file_inode, stored_entry->entry.name.str.val); |
| | 1963 | xc_entry_hold_php_unlocked(cache, stored_entry TSRMLS_CC); |
| | 1964 | } |
| | 1965 | } LEAVE_LOCK_EX(cache); |
| | 1966 | /* }}} */ |
| | 1967 | TRACE("%s", stored_entry ? "stored" : "store failed"); |
| | 1968 | |
| | 1969 | if (catched || !stored_php) { |
| | 1970 | goto err_aftersandbox; |
| | 1971 | } |
| | 1972 | |
| | 1973 | cache->compiling = 0; |
| | 1974 | xc_free_php(&compiler->new_php TSRMLS_CC); |
| | 1975 | |
| | 1976 | if (stored_entry) { |
| | 1977 | if (compiler->new_php.op_array) { |
| | 1978 | #ifdef ZEND_ENGINE_2 |
| | 1979 | destroy_op_array(compiler->new_php.op_array TSRMLS_CC); |
| | 1980 | #else |
| | 1981 | destroy_op_array(compiler->new_php.op_array); |
| | 1982 | #endif |
| | 1983 | efree(compiler->new_php.op_array); |
| | 1984 | compiler->new_php.op_array = NULL; |
| | 1985 | sandboxed_compiler->h = NULL; |
| | 1986 | } |
| | 1987 | sandboxed_compiler->stored_entry = stored_entry; |
| | 1988 | sandboxed_compiler->stored_php = stored_php; |
| | 1989 | /* sandbox no install */ |
| | 1990 | return NULL; |
| | 1991 | } |
| | 1992 | else { |
| | 1993 | /* install it with sandbox */ |
| | 1994 | return compiler->new_php.op_array; |
| | 1995 | } |
| | 1996 | |
| | 1997 | err_aftersandbox: |
| | 1998 | xc_free_php(&compiler->new_php TSRMLS_CC); |
| | 1999 | |
| | 2000 | cache->compiling = 0; |
| | 2001 | if (catched) { |
| | 2002 | cache->errors ++; |
| | 2003 | zend_bailout(); |
| | 2004 | } |
| | 2005 | return compiler->new_php.op_array; |
| | 2006 | } /* }}} */ |
| | 2007 | static zend_op_array *xc_compile_file_cached(xc_compiler_t *compiler, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ |
| 2004 | | /* {{{ compile */ |
| 2005 | | /* make compile inside sandbox */ |
| 2006 | | |
| 2007 | | #ifdef HAVE_XCACHE_CONSTANT |
| 2008 | | compiler->new_php.constinfos = NULL; |
| 2009 | | #endif |
| 2010 | | compiler->new_php.funcinfos = NULL; |
| 2011 | | compiler->new_php.classinfos = NULL; |
| 2012 | | #ifdef ZEND_ENGINE_2_1 |
| 2013 | | compiler->new_php.autoglobals = NULL; |
| 2014 | | #endif |
| 2015 | | memset(&compiler->new_php.op_array_info, 0, sizeof(compiler->new_php.op_array_info)); |
| 2016 | | |
| 2017 | | XG(initial_compile_file_called) = 0; |
| 2018 | | zend_try { |
| 2019 | | xc_sandbox_init(&sandbox, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); |
| 2020 | | compiler->new_php.op_array = NULL; |
| 2021 | | xc_compile_php(compiler, h, type TSRMLS_CC); |
| 2022 | | } zend_catch { |
| 2023 | | catched = 1; |
| 2024 | | } zend_end_try(); |
| 2025 | | |
| 2026 | | if (catched |
| 2027 | | || !compiler->new_php.op_array /* possible ? */ |
| 2028 | | || !XG(initial_compile_file_called)) { |
| 2029 | | goto err_aftersandbox; |
| 2030 | | } |
| 2031 | | |
| 2032 | | /* }}} */ |
| 2033 | | #ifdef SHOW_DPRINT |
| 2034 | | compiler->new_entry.php = &compiler->new_php; |
| 2035 | | xc_dprint(&compiler->new_entry, 0 TSRMLS_CC); |
| 2036 | | #endif |
| 2037 | | ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ |
| 2038 | | /* php_store */ |
| 2039 | | stored_php = xc_php_store_unlocked(cache, &compiler->new_php TSRMLS_CC); |
| 2040 | | if (!stored_php) { |
| 2041 | | /* error */ |
| 2042 | | break; |
| 2043 | | } |
| 2044 | | /* entry_store */ |
| 2045 | | compiler->new_entry.php = stored_php; |
| 2046 | | stored_entry = xc_entry_php_store_unlocked(cache, compiler->entry_hash.entryslotid, &compiler->new_entry TSRMLS_CC); |
| 2047 | | if (stored_entry) { |
| 2048 | | xc_php_addref_unlocked(stored_php); |
| 2049 | | TRACE(" cached %d:%s, holding", compiler->new_entry.file_inode, stored_entry->entry.name.str.val); |
| 2050 | | xc_entry_hold_php_unlocked(cache, stored_entry TSRMLS_CC); |
| 2051 | | } |
| 2052 | | } LEAVE_LOCK_EX(cache); |
| 2053 | | /* }}} */ |
| 2054 | | TRACE("%s", stored_entry ? "stored" : "store failed"); |
| 2055 | | |
| 2056 | | if (catched || !stored_php) { |
| 2057 | | goto err_aftersandbox; |
| 2058 | | } |
| 2059 | | |
| 2060 | | cache->compiling = 0; |
| 2061 | | xc_free_php(&compiler->new_php TSRMLS_CC); |
| 2062 | | |
| 2063 | | if (stored_entry) { |
| 2064 | | if (compiler->new_php.op_array) { |
| 2065 | | #ifdef ZEND_ENGINE_2 |
| 2066 | | destroy_op_array(compiler->new_php.op_array TSRMLS_CC); |
| 2067 | | #else |
| 2068 | | destroy_op_array(compiler->new_php.op_array); |
| 2069 | | #endif |
| 2070 | | efree(compiler->new_php.op_array); |
| 2071 | | compiler->new_php.op_array = NULL; |
| 2072 | | h = NULL; |
| 2073 | | } |
| 2074 | | xc_sandbox_free(&sandbox, XC_NoInstall TSRMLS_CC); |
| | 2131 | sandboxed_compiler.compiler = compiler; |
| | 2132 | sandboxed_compiler.h = h; |
| | 2133 | sandboxed_compiler.type = type; |
| | 2134 | sandboxed_compiler.stored_php = NULL; |
| | 2135 | sandboxed_compiler.stored_entry = NULL; |
| | 2136 | op_array = xc_sandbox(xc_compile_file_sandboxed, (void *) &sandboxed_compiler, h->opened_path ? h->opened_path : h->filename TSRMLS_CC); |
| | 2137 | if (sandboxed_compiler.stored_entry) { |