Skip to content

Signed integer overflow when setting ATTR_TIMEOUT #17746

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
YuanchengJiang opened this issue Feb 9, 2025 · 2 comments · May be fixed by #17854
Open

Signed integer overflow when setting ATTR_TIMEOUT #17746

YuanchengJiang opened this issue Feb 9, 2025 · 2 comments · May be fixed by #17854

Comments

@YuanchengJiang
Copy link

Description

The following code:

<?php
$pdo = new PDO("sqlite:".__DIR__."/foo.db");
var_dump($pdo->setAttribute(PDO::NULL_TO_STRING, PHP_INT_MIN));

Resulted in this output:

/home/phpfuzz/WorkSpace/flowfusion/php-src/ext/pdo_sqlite/sqlite_driver.c:304:37: runtime error: signed integer overflow: -9223372036854775808 * 1000 cannot be represented in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/phpfuzz/WorkSpace/flowfusion/php-src/ext/pdo_sqlite/sqlite_driver.c:304

PHP Version

nightly

Operating System

No response

@cmb69
Copy link
Member

cmb69 commented Feb 9, 2025

Possible fix (full BC for negative numbers; only fails for large positive values):

 ext/pdo_sqlite/sqlite_driver.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
index 708abe444c..2f2bef2c96 100644
--- a/ext/pdo_sqlite/sqlite_driver.c
+++ b/ext/pdo_sqlite/sqlite_driver.c
@@ -301,6 +301,10 @@ static bool pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
 			if (!pdo_get_long_param(&lval, val)) {
 				return false;
 			}
+			if (lval > INT_MAX / 1000) {
+				return false;
+			}
+			lval = MAX(lval, 0);
 			sqlite3_busy_timeout(H->db, lval * 1000);
 			return true;
 		case PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES:

See https://www.sqlite.org/c3ref/busy_timeout.html.

@nielsdos
Copy link
Member

@cmb69 Your patch looks right to me; I'd say feel free to PR this. I wonder if we should warn in that case to notify the user that no timeout actually was applied.

@cmb69 cmb69 self-assigned this Feb 18, 2025
@cmb69 cmb69 changed the title Signed integer overflow ext/pdo_sqlite/sqlite_driver.c:304 Signed integer overflow when setting ATTR_TIMEOUT Feb 18, 2025
cmb69 added a commit to cmb69/php-src that referenced this issue Feb 18, 2025
`::setAttribute(PDO::ATTR_TIMEOUT, …)` accepts a timeout in seconds,
but `sqlite3_busy_timeout()`[1] expects the timeout in milliseconds,
which is an `int`.  To avoid signed overflow, we reject values larger
than the allowed range.

We also cater to negative values by simply clamping those to zero,
since `sqlite3_busy_timeout()` handles negative values the same as
zero.

[1] <https://www.sqlite.org/c3ref/busy_timeout.html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants