Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Zend/zend_permissions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "zend.h"
#include "zend_API.h"
#include "zend_exceptions.h"
#include "Zend/zend_permissions.h"

ZEND_API zend_result zend_validate_file_permission(
zend_long permission,
zend_long arg_num,
const char *name
)
{
if (permission < 0 || (permission & ~07777) != 0) {
zend_argument_value_error(
arg_num,
"Invalid %s value (must be between 0 and 07777)",
name
);
return FAILURE;
}

return SUCCESS;
}
16 changes: 16 additions & 0 deletions Zend/zend_permissions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef ZEND_PERMISSIONS_H
#define ZEND_PERMISSIONS_H

#include "zend.h"

BEGIN_EXTERN_C()

ZEND_API zend_result zend_validate_file_permission(
zend_long permission,
zend_long arg_num,
const char *name
);

END_EXTERN_C()

#endif /* ZEND_PERMISSIONS_H */
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
zend_ini_parser.c
zend_ini_scanner.c
zend_ini.c
zend_permissions.c
zend_interfaces.c
zend_iterators.c
zend_language_parser.c
Expand Down
7 changes: 6 additions & 1 deletion ext/dba/dba.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#ifdef HAVE_DBA

#include "php_ini.h"
#include "Zend/zend_permissions.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef HAVE_SYS_FILE_H
Expand Down Expand Up @@ -563,7 +564,11 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, bool persistent)
zend_argument_must_not_be_empty_error(3);
RETURN_THROWS();
}
// TODO Check Value for permission

if (zend_validate_file_permission(permission, 4, "file permission") == FAILURE) {
RETURN_THROWS();
}

if (map_size < 0) {
zend_argument_value_error(5, "must be greater than or equal to 0");
RETURN_THROWS();
Expand Down
49 changes: 49 additions & 0 deletions ext/dba/tests/dba_permission.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
DBA permission validation (invalid bits check)
--EXTENSIONS--
dba
--SKIPIF--
<?php
if (!in_array('flatfile', dba_handlers())) die('skip flatfile handler not available');
?>
--FILE--
<?php

$filename = __DIR__ . DIRECTORY_SEPARATOR . 'test.db';

function test($permission, $filename) {
try {
dba_open($filename, "c", "flatfile", $permission);
echo "OK\n";
} catch (ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}

@unlink($filename);
}

/* valid permissions */
test(0777, $filename);
test(0755, $filename);
test(0644, $filename);
test(0000, $filename);

/* invalid permissions */
test(010000, $filename);
test(020000, $filename);
test(-1, $filename);

?>
--EXPECT--
OK
OK
OK
OK
dba_open(): Argument #4 ($permission) Invalid file permission value (must be between 0 and 07777)
dba_open(): Argument #4 ($permission) Invalid file permission value (must be between 0 and 07777)
dba_open(): Argument #4 ($permission) Invalid file permission value (must be between 0 and 07777)
--CLEAN--
<?php
$filename = __DIR__ . DIRECTORY_SEPARATOR . 'test.db';
@unlink($filename);
?>
6 changes: 6 additions & 0 deletions ext/ftp/php_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "ext/standard/file.h"
#include "Zend/zend_attributes.h"
#include "Zend/zend_exceptions.h"
#include "Zend/zend_permissions.h"


#include "php_ftp.h"
#include "ftp.h"
Expand Down Expand Up @@ -419,6 +421,10 @@ PHP_FUNCTION(ftp_chmod)
}
GET_FTPBUF(ftp, z_ftp);

if (zend_validate_file_permission(mode, 2, "mode") == FAILURE) {
RETURN_THROWS();
}

if (!ftp_chmod(ftp, mode, filename, filename_len)) {
if (*ftp->inbuf) {
php_error_docref(NULL, E_WARNING, "%s", ftp->inbuf);
Expand Down
5 changes: 5 additions & 0 deletions ext/standard/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ext/standard/basic_functions.h"
#include "php_ini.h"
#include "zend_smart_str.h"
#include "zend_permissions.h"

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -1131,6 +1132,10 @@ PHP_FUNCTION(mkdir)
Z_PARAM_RESOURCE_OR_NULL(zcontext)
ZEND_PARSE_PARAMETERS_END();

if (zend_validate_file_permission(mode, 4, "mode") == FAILURE) {
RETURN_THROWS();
}

context = php_stream_context_from_zval(zcontext, 0);

php_stream_error_operation_begin();
Expand Down
5 changes: 5 additions & 0 deletions ext/standard/filestat.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "php.h"
#include "fopen_wrappers.h"
#include "php_globals.h"
#include "Zend/zend_permissions.h"

#include <stdlib.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -569,6 +570,10 @@ PHP_FUNCTION(chmod)
Z_PARAM_LONG(mode)
ZEND_PARSE_PARAMETERS_END();

if (zend_validate_file_permission(mode, 2, "mode") == FAILURE) {
RETURN_THROWS();
}

wrapper = php_stream_locate_url_wrapper(filename, NULL, 0);
if(wrapper != &php_plain_files_wrapper || strncasecmp("file://", filename, 7) == 0) {
if(wrapper && wrapper->wops->stream_metadata) {
Expand Down
40 changes: 14 additions & 26 deletions ext/standard/tests/file/006_variation2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ foreach($perms_array as $permission) {
printf("%o", fileperms($file_name) );
echo "\n";
clearstatcache();
} catch (TypeError $e) {
} catch (TypeError|ValueError $e) {
echo $e->getMessage(), "\n";
}

Expand All @@ -63,7 +63,7 @@ foreach($perms_array as $permission) {
printf("%o", fileperms($dir_name) );
echo "\n";
clearstatcache();
} catch (TypeError $e) {
} catch (TypeError|ValueError $e) {
echo $e->getMessage(), "\n";
}
$count++;
Expand Down Expand Up @@ -97,45 +97,33 @@ bool(true)
bool(true)
41000
-- Iteration 4 --
bool(true)
101111
bool(true)
41111
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 5 --
bool(true)
107001
bool(true)
47001
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 6 --
bool(true)
100001
bool(true)
40001
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 7 --
bool(true)
101411
bool(true)
41411
-- Iteration 8 --
bool(true)
107141
bool(true)
47141
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 9 --
bool(true)
100637
bool(true)
40637
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 10 --
bool(true)
103567
bool(true)
43567
-- Iteration 11 --
bool(true)
103567
bool(true)
43567
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
-- Iteration 12 --
chmod(): Argument #2 ($permissions) must be of type int, string given
chmod(): Argument #2 ($permissions) must be of type int, string given
Expand Down
7 changes: 6 additions & 1 deletion ext/standard/tests/file/copy_variation15.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ var_dump( copy($file, $dir."/copy_copy_variation15.tmp") );
var_dump( file_exists($dir."/copy_copy_variation15_dir.tmp") );
var_dump( filesize($file) ); //size of source

chmod($dir, $old_perms);
try {
chmod($dir, $old_perms);
} catch (TypeError|ValueError $e) {
echo $e->getMessage(), "\n";
}

echo "*** Done ***\n";
?>
Expand All @@ -46,4 +50,5 @@ Warning: copy(%s): %s
bool(false)
bool(false)
int(300)
chmod(): Argument #2 ($permissions) Invalid mode value (must be between 0 and 07777)
*** Done ***
19 changes: 18 additions & 1 deletion main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "zend.h"
#include "zend_types.h"
#include "zend_extensions.h"
#include "zend_permissions.h"
#include "php_ini.h"
#include "php_globals.h"
#include "php_main.h"
Expand Down Expand Up @@ -772,6 +773,22 @@ static PHP_INI_MH(OnChangeMailForceExtra)
}
/* }}} */

/* {{{ PHP_INI_MH */
static PHP_INI_MH(OnUpdateFilePermission)
{
zend_long value = zend_ini_parse_quantity_warn(new_value, entry->name);

if (zend_validate_file_permission(value, 1, ZSTR_VAL(entry->name)) == FAILURE) {
return FAILURE;
}

zend_long *p = ZEND_INI_GET_ADDR();
*p = value;

return SUCCESS;
}
/* }}} */

/* defined in browscap.c */
PHP_INI_MH(OnChangeBrowscap);

Expand Down Expand Up @@ -837,7 +854,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("input_encoding", NULL, PHP_INI_ALL, OnUpdateInputEncoding, input_encoding, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("output_encoding", NULL, PHP_INI_ALL, OnUpdateOutputEncoding, output_encoding, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("error_log", NULL, PHP_INI_ALL, OnUpdateErrorLog, error_log, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("error_log_mode", "0644", PHP_INI_ALL, OnUpdateLong, error_log_mode, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("error_log_mode", "0644", PHP_INI_ALL, OnUpdateFilePermission, error_log_mode, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("extension_dir", PHP_EXTENSION_DIR, PHP_INI_SYSTEM, OnUpdateStringUnempty, extension_dir, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("sys_temp_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, sys_temp_dir, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("include_path", PHP_INCLUDE_PATH, PHP_INI_ALL, OnUpdateStringUnempty, include_path, php_core_globals, core_globals)
Expand Down
2 changes: 1 addition & 1 deletion win32/build/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \
zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \
zend_hash.c zend_list.c zend_builtin_functions.c zend_attributes.c \
zend_ini.c zend_sort.c zend_multibyte.c \
zend_ini.c zend_sort.c zend_multibyte.c zend_permissions.c \
zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
zend_object_handlers.c zend_objects_API.c \
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \
Expand Down
Loading