php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15516 odbc_execute() param clobber fix (Patch included)
Submitted: 2002-02-11 22:08 UTC Modified: 2002-02-15 12:24 UTC
From: torben@php.net Assigned:
Status: Closed Package: ODBC related
PHP Version: 4.0CVS-2002-02-1 OS: Debian testing
Private report: No CVE-ID: None
 [2002-02-11 22:08 UTC] torben@php.net
-----------------------------------------------------
Synopsis: 

odbc_execute() has some undocumented functionality:
if a parameter is given enclosed in single-quotes, that
param is taken as the name of a file to read and send 
instead of the actual parameter string.

In the above case, odbc_execute() will replace the last 
character of the passed parameter with \0.


-----------------------------------------------------
Test script:

<?php /* -*- mode: c++; minor-mode: font -*- */ 
error_reporting(E_ALL);

/* Just using the default test settings for now. */
if (!$dbh = odbc_connect('myodbc3', 'root', '')) {
    echo "Could not connect: error: " . odbc_errormsg() . "\n";
}

$query = 'insert into phptest (c) values(?)';

if (!$stmt = odbc_prepare($dbh, $query)) {
    echo "Prepare failed: error: " . odbc_errormsg() . "\n";
}

$filename = "'/home/torben/odbc.ini'";
$params = array($filename);

echo "Before: " . addslashes($filename) . "\n";

if (!$res = odbc_execute($stmt, $params)) {
    echo "Execute failed: error: " . odbc_errormsg() . "\n";
}

echo "After: " . addslashes($filename) . "\n";

odbc_close($dbh);

?>


-----------------------------------------------------
Output:

Before: \'/home/torben/odbc.ini\'
After: \'/home/torben/odbc.ini\0


-----------------------------------------------------
Patch:

Index: php_odbc.c
===================================================================
RCS file: /repository/php4/ext/odbc/php_odbc.c,v
retrieving revision 1.115
diff -u -r1.115 php_odbc.c
--- php_odbc.c	30 Jan 2002 21:54:54 -0000	1.115
+++ php_odbc.c	12 Feb 2002 02:41:25 -0000
@@ -943,12 +943,13 @@
 			else
 				ctype = SQL_C_CHAR;
 
-			if (Z_STRVAL_PP(tmp)[0] == '\'' && 
+			if (Z_STRLEN_PP(tmp) > 2 &&
+                Z_STRVAL_PP(tmp)[0] == '\'' && 
 				Z_STRVAL_PP(tmp)[Z_STRLEN_PP(tmp) - 1] == '\'') {
-				filename = &Z_STRVAL_PP(tmp)[1];
-				filename[Z_STRLEN_PP(tmp) - 2] = '\0';
+				filename = estrndup(&Z_STRVAL_PP(tmp)[1], Z_STRLEN_PP(tmp) - 2);
+				filename[strlen(filename)] = '\0';
 
-                if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
+				if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
 					php_error(E_WARNING,"Can't open file %s", filename);
 					SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
 					for(i = 0; i < result->numparams; i++) {
@@ -957,8 +958,11 @@
 						}
 					}
 					efree(params);
+					efree(filename);
 					RETURN_FALSE;
 				}
+
+				efree(filename);
 
 				params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-02-11 22:14 UTC] jimw@php.net
along similar lines, it would be nice to change that open() call to the php wrapper which enables safe-mode checking. (there was a bug filed recently about this, i think. or maybe just a message on php-dev.)
 [2002-02-13 06:12 UTC] torben@php.net
Good point. OK, this one fixes the clobber problem and 
checks for safe_mode and open_basedir.


Torben


Index: php_odbc.c
===================================================================
RCS file: /repository/php4/ext/odbc/php_odbc.c,v
retrieving revision 1.115
diff -u -r1.115 php_odbc.c
--- php_odbc.c	30 Jan 2002 21:54:54 -0000	1.115
+++ php_odbc.c	13 Feb 2002 08:52:27 -0000
@@ -943,12 +943,23 @@
 			else
 				ctype = SQL_C_CHAR;
 
-			if (Z_STRVAL_PP(tmp)[0] == '\'' && 
+			if (Z_STRLEN_PP(tmp) > 2 &&
+				Z_STRVAL_PP(tmp)[0] == '\'' && 
 				Z_STRVAL_PP(tmp)[Z_STRLEN_PP(tmp) - 1] == '\'') {
-				filename = &Z_STRVAL_PP(tmp)[1];
-				filename[Z_STRLEN_PP(tmp) - 2] = '\0';
+				filename = estrndup(&Z_STRVAL_PP(tmp)[1], Z_STRLEN_PP(tmp) - 2);
+				filename[strlen(filename)] = '\0';
 
-                if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
+				/* Check for safe mode. */
+				if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
+					RETURN_FALSE;
+				}
+				
+				/* Check the basedir */
+				if (php_check_open_basedir(filename TSRMLS_CC)) {
+					RETURN_FALSE;
+				}
+
+				if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
 					php_error(E_WARNING,"Can't open file %s", filename);
 					SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
 					for(i = 0; i < result->numparams; i++) {
@@ -957,8 +968,11 @@
 						}
 					}
 					efree(params);
+					efree(filename);
 					RETURN_FALSE;
 				}
+
+				efree(filename);
 
 				params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
 

 [2002-02-15 12:24 UTC] kalowsky@php.net
This bug has been fixed in CVS.

thanks for the patch it should be in cvs in a few seconds...whenever CVS commit finalizes....
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri May 10 07:01:31 2024 UTC