From a27df15eff8b9d971e0c2c7730125b5cf99dc683 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 24 May 2016 07:01:21 +0100 Subject: adding pledge's call wrapper, allowing most of the promises. this promises list might need to be adjusted over time. --- config.m4 | 2 +- php_suhosin.h | 1 + pledge.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pledge.h | 29 ++++++++++++++ suhosin.c | 1 + 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 pledge.c create mode 100644 pledge.h diff --git a/config.m4 b/config.m4 index c908de9..3c4c89d 100644 --- a/config.m4 +++ b/config.m4 @@ -5,7 +5,7 @@ PHP_ARG_ENABLE(suhosin, whether to enable suhosin support, [ --enable-suhosin Enable suhosin support]) if test "$PHP_SUHOSIN" != "no"; then - PHP_NEW_EXTENSION(suhosin, suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c, $ext_shared) + PHP_NEW_EXTENSION(suhosin, suhosin.c sha256.c memory_limit.c treat_data.c ifilter.c post_handler.c ufilter.c rfc1867_new.c log.c header.c execute.c ex_imp.c session.c aes.c crypt.c pledge.c, $ext_shared) fi PHP_ARG_ENABLE(suhosin-experimental, whether to enable experimental suhosin features, diff --git a/php_suhosin.h b/php_suhosin.h index 824ce21..b228d48 100644 --- a/php_suhosin.h +++ b/php_suhosin.h @@ -383,6 +383,7 @@ void suhosin_unhook_header_handler(); void suhosin_hook_session(TSRMLS_D); void suhosin_unhook_session(TSRMLS_D); void suhosin_hook_sha256(TSRMLS_D); +void suhosin_hook_pledge(TSRMLS_D); void suhosin_hook_ex_imp(TSRMLS_D); void suhosin_hook_treat_data(); void suhosin_hook_memory_limit(TSRMLS_D); diff --git a/pledge.c b/pledge.c new file mode 100644 index 0000000..b5ceaf8 --- /dev/null +++ b/pledge.c @@ -0,0 +1,126 @@ +/* + +----------------------------------------------------------------------+ + | Suhosin Version 1 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2007 The Hardened-PHP Project | + | Copyright (c) 2007-2015 SektionEins GmbH | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Stefan Esser | + +----------------------------------------------------------------------+ +*/ + +/* $Id: pledge.c $ */ + +#include +#ifdef __OpenBSD__ +#include +#include "php.h" +#include "ext/standard/info.h" +#include "ext/standard/php_string.h" +#include "ext/standard/php_smart_str.h" + +#include "pledge.h" + +const char *promises_defined[] = { + "rpath", + "wpath", + "cpath", + "tmppath", + "inet", + "flock", + "unix", + "dns", + "sendfd", + "recvfd", + "proc", + "exec", + NULL +}; + +/* {{{ proto string pledge(string str [, bool raw_output]) + Wrapper around pledge call. Hence subsequent calls are + allowed only to diminish the permissions. */ +static PHP_FUNCTION(suhosin_pledge) +{ + zval *promises, **current; + HashTable *hashp; + HashPosition hashpos; + const char *pm; + int ret; + smart_str promisesbuf = { 0 }; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &promises) == FAILURE) { + return; + } + + /* PHP needs at least few functions from this promise */ + smart_str_appends(&promisesbuf, "stdio"); + hashp = Z_ARRVAL_P(promises); + for (zend_hash_internal_pointer_reset_ex(hashp, &hashpos); + zend_hash_get_current_data_ex(hashp, (void **)¤t, &hashpos) == SUCCESS; + zend_hash_move_forward_ex(hashp, &hashpos)) { + if (Z_TYPE_PP(current) != IS_STRING) + continue; + pm = NULL; + const char **ptr = promises_defined; + char *pp = Z_STRVAL_PP(current); + char *p = php_trim(pp, strlen(pp), " ", 1, NULL, 3); + while (*ptr) { + if (strcmp(*ptr, p) == 0) { + pm = *ptr; + break; + } + ptr ++; + } + if (pm == NULL) { + if (strcmp(p, "stdio") != 0) + php_error_docref(NULL TSRMLS_CC, E_WARNING, "pledge: %s invalid or forbidden promise", p); + continue; + } + efree(p); + smart_str_appends(&promisesbuf, " "); + smart_str_appends(&promisesbuf, pm); + } + + smart_str_0(&promisesbuf); + ret = pledge(promisesbuf.c, NULL); + smart_str_free(&promisesbuf); + + if (ret == -1) + php_error_docref(NULL TSRMLS_CC, E_ERROR, "pledge failed: %s", strerror(errno)); + + RETVAL_LONG(ret); +} + +/* }}} */ + +/* {{{ suhosin_pledge_functions[] + */ +static zend_function_entry suhosin_pledge_functions[] = { + PHP_NAMED_FE(pledge, PHP_FN(suhosin_pledge), NULL) + {NULL, NULL, NULL} +}; +/* }}} */ + +void suhosin_hook_pledge(TSRMLS_D) +{ + zend_register_functions(NULL, suhosin_pledge_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ +#endif diff --git a/pledge.h b/pledge.h new file mode 100644 index 0000000..2666e41 --- /dev/null +++ b/pledge.h @@ -0,0 +1,29 @@ +/* + +----------------------------------------------------------------------+ + | Suhosin Version 1 | + +----------------------------------------------------------------------+ + | Copyright (c) 2006-2007 The Hardened-PHP Project | + | Copyright (c) 2007-2015 SektionEins GmbH | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Stefan Esser | + +----------------------------------------------------------------------+ +*/ + +/* $Id: pledge.h $ */ + +#ifndef PLEDGE_H +#define PLEDGE_H + +#include "ext/standard/basic_functions.h" +#ifdef __OpenBSD__ + +#endif +#endif diff --git a/suhosin.c b/suhosin.c index d95b92f..abe79df 100644 --- a/suhosin.c +++ b/suhosin.c @@ -1051,6 +1051,7 @@ PHP_MINIT_FUNCTION(suhosin) suhosin_hook_memory_limit(TSRMLS_C); suhosin_hook_sha256(TSRMLS_C); suhosin_hook_ex_imp(TSRMLS_C); + suhosin_hook_pledge(TSRMLS_C); #if PHP_VERSION_ID < 50500 /* register the logo for phpinfo */ -- cgit v1.3