php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59881 The extension keeps global error state which is not cleaned
Submitted: 2011-08-02 15:54 UTC Modified: 2015-06-05 12:29 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: stas@php.net Assigned: rahulpriyadarshi (profile)
Status: Closed Package: ibm_db2 (PECL)
PHP Version: 5_4 SVN-2011-08-02 (dev) OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: stas@php.net
New email:
PHP Version: OS:

 

 [2011-08-02 15:54 UTC] stas@php.net
Description:
------------
The extension uses global error state __php_stmt_err_state 
and  __php_stmt_err_msg which is used when db2_stmt_error() 
is used without parameters. This state is cleaned only when 
db2_prepare() and db2_exec() is called and is never cleaned 
otherwise - not on connection and not on new request. 

This lead to the situation when if you connect to a new 
connection and call db2_stmt_error() it will give you the 
error state of the last query of the last connection run in 
this process. This is obviously wrong and may also be a 
security problem as last connection's error message could 
contain parts of the query which may contain sensitive data 
and it will be available to an application in a new request 
that may belong to somebody else. 

What should be done is at least to clean all error states at 
the beginning of the request (RINIT phase) and it also may 
make sense to clean it on new connection. 

It would also make sense to give some way to clear the error 
state - right now, unlike most other DB APIs, 
db2_stmt_error() does not clean the error state when called, 
so there's no way to remove the error once it is in 
__php_stmt_err_state without connecting and doing a query.


Patches

db2-bugfix (last revision 2014-07-09 07:52 UTC by stas@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-12-11 19:44 UTC] stas@php.net
-Assigned To: +Assigned To: ambrish
 [2012-03-16 04:02 UTC] ambrish@php.net
-Assigned To: ambrish +Assigned To: rahulpriyadarshi
 [2012-03-23 05:58 UTC] rahulpriyadarshi@php.net
If we clean the global error message and state at the beginning of the every request or at the time of new connection then also this will not solve your problem. Because it may possible that in current process you already have more than one connections and they are still sharing the stmt error information of each other, this can also lead the security problem.

One option you already have to remove this security problem. If you call db2_stmt_error() with stmt resource then it will always give you stmt error information of this particular stmt resource.

We can enhance db2_stmt_error() function to allow connection object, and in this case if you will pass a connection object while calling db2_stmt_error() then it give you error message of last query of the this particular connection.

Please let me know, enhancement of db2_stmt_error() function will solve your problem or not.
 [2012-03-23 06:10 UTC] stas@php.net
Two connections should not be a problem as the state would be returned of the 
last query/statement. The problem here is that even before we did any statements 
- say if we only connected - the state is not clean. So if we have generic error 
checking code that checks db2_stmt_error(), we're getting errors from old 
request. If they were cleaned up, we'd get "no error", which would be 100% fine. 
Since we call db2_stmt_error() only immediately after we do something with the 
DB, we'd always have the right status, so cleaning it up at RINIT would be 
enough for us.

As for improving db2_stmt_error(), we don't have specific requests. On general 
note, I think adding connection object may make sense, but it is not required 
for us, and also has backward-compatibility problem - if your code uses this 
functionality, it won't be able to run on old versions of DB2 driver.
 [2012-03-27 04:03 UTC] Dallas at ekkysoftware dot com
I’m having similar problem with the global memory, in the apache shared mod environment.

Worker process starts and calls:-
PHP_MINT_FUNCITON() {  EXTENSION_NAME_G(global_variable) = 5;}
PHP_RINT_FUNCTION(); 
PHP_METHOD(Class, __construct){ EXTENSION_NAME_G(global_variable) += 1;} 
PHP_RSHUTDOWN_FUNCTION ();

Repeat page request over & over, and the global_variable will start at 5 and increment up until something happens and from no real reason it’s set back to its original value of 5. 

I have added a log file code in MINT function and it’s not being called more than once, the using ps –u apache, the worker process has not been replaced, but for some reason the global memory has been reset back to its original state without calling MINT.

I have not tried using standard C style static global memory, tried dynamically allocating memory on the heap, no matter what I do all global memory eventually gets reset back to the MINT state. Mostly happens when there is a 10 second delay between page requests, but not always.
 [2012-08-01 08:12 UTC] rahulpriyadarshi@php.net
Hi stas,
 Why you are trying access statement error message just after creating a new connection. If you do any query/prepare/next_result then only global stmt error message will get cleaned, which is correct in my opinion. 
Just after creating any new connection you should check db2_conn_error(), because only connection error will occur during new connection function call. and it gets cleaned at the time of new connection. so if there is no error occurred during the new connection, you will get no connection error message. 

Thanks,
Rahul
 [2012-08-02 19:36 UTC] stas@php.net
Presence of db2_conn_error() is not the reason to not clean the error state from 
previous connection and even previous request. This is obviously a bug, error 
information should not leak between the requests.
 [2013-07-05 19:23 UTC] stas@php.net
No comment almost 2 years after submitting the bug. Is this extension still maintained?
 [2014-07-08 07:14 UTC] rahulpriyadarshi@php.net
It is not making us any sense to call db2_stmt_error() just after creating new connection, even before execution any statement. It is the issue of uses of APIs in wrong order. 

If you want we can accept a request to accept db2_stmt_error() a connection object also, else we are going to close this issue.
 [2014-07-08 22:17 UTC] stas@php.net
As I already wrote in the initial report, I think if you have the global state (which can not be per connection since there is only one __php_stmt_err_state) then it should be reset at the beginning of the request. It is pretty simple to do and I can submit a patch if needed. I am surprised why there is resistance to this simple solution to what looks like an obvious omission to me. Is there any reason to keep the global error state after the request has already finished? 

I'm not sure what having db2_stmt_error() to get connection object would achieve, as this function is meant to work with statements, not connections, and the problem is not in that it does not get the connection object but that it retains error state from the previous request.
 [2014-07-09 06:25 UTC] rahulpriyadarshi@php.net
>>>
As I already wrote in the initial report, I think if you have the global state (which can not be per connection since there is only one __php_stmt_err_state) then it should be reset at the beginning of the request.
<<<
Correct, it should be reset at the beginning of the request, and since it a stmt error message it should be reset at beginning of every new stmt request. And this feature is already present in the driver

>>>
Is there any reason to keep the global error state after the request has already finished?
<<<
During the stmt prepare/execution only any one can get stmt errors, and user may wants to do some cleanup before fetching the errors.

Why you are calling the db2_stmt_error(), just after making new connection without executing any statement.

Do you wants clear_global_stmt_errors like feature to clear the global error message whenever you wants?
 [2014-07-09 07:51 UTC] stas@php.net
Adding a feature to clear error state would be a good idea, but this also should happen automatically at the end of the request or at the beginning of the new one. See the attached patch for example. 

Calling db2_stmt_error() may be needed for generic error handling in API library, where we do not know if we executed any statements already or just tried to connect. 


But it does not matter why anybody is calling it, whatever is the reason for calling it returning error from previous request is clearly not the correct behavior. It may pose security risks if the message from the previous request contained sensitive data (such as part of the query) from different security context and in general it is just wrong to retain globals information between requests, no extension in PHP does that.
 [2014-07-09 07:52 UTC] stas@php.net
The following patch has been added/updated:

Patch Name: db2-bugfix
Revision:   1404892352
URL:        https://bugs.php.net/patch-display.php?bug=59881&patch=db2-bugfix&revision=1404892352
 [2014-07-20 16:01 UTC] rahulpriyadarshi@php.net
I am going to add the feature to clear error state at the end of the request. and thinking of to deprecate current implementation of error message reporting which gives last error state if you not the connection of statement, and will add methods in which at least connection object is mandatory to get last stmt error message.
 [2015-06-05 12:29 UTC] rahulpriyadarshi@php.net
-Status: Assigned +Status: Closed
 [2015-06-05 12:29 UTC] rahulpriyadarshi@php.net
The changes are released with ibm_db2-1.9.6
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Apr 05 11:01:23 2020 UTC