Skip to content

Fix GH-16959: snmpget modifies the object_id (as array). #16969

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

Closed
wants to merge 1 commit into from

Conversation

devnexen
Copy link
Member

Instead of modifying the zval, we use the zend_try_get_string.

@devnexen devnexen linked an issue Nov 27, 2024 that may be closed by this pull request
@devnexen devnexen marked this pull request as ready for review November 27, 2024 21:18
@devnexen devnexen marked this pull request as draft November 27, 2024 21:46
@devnexen devnexen force-pushed the gh16959 branch 8 times, most recently from dc73754 to e2691d8 Compare November 28, 2024 12:26
@nielsdos
Copy link
Member

Feel free to ping me if this needs a re-review

@devnexen
Copy link
Member Author

No need to get into too much details yet but is there room for improvements or does this approach look terrible ?

Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the right approach. Preliminary review without checking the details

ext/snmp/snmp.c Outdated
@@ -728,19 +728,22 @@ static bool php_snmp_parse_oid(
zval new;
ZVAL_COPY_VALUE(&new, tmp_type);
if (!try_convert_to_string(&new)) {
zend_string_release(tmp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect these to get freed by php_free_objid_query (ditto below)

ext/snmp/snmp.c Outdated
@@ -728,19 +728,22 @@ static bool php_snmp_parse_oid(
zval new;
ZVAL_COPY_VALUE(&new, tmp_type);
if (!try_convert_to_string(&new)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not zval_try_get_string? By using COPY_VALUE with a conversion you probably reach RC0 too soon.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was planning to go back to trying that again.

echo $e->getMessage() . PHP_EOL;
}
try {
snmp2_set($hostname, $communityWrite, $bad_object_ids, array("toolongtype"), array(null));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a test with a non-interned string.
A trick to make one is using str_repeat("my string", random_int(1, 1)).

ext/snmp/snmp.c Outdated
if (session_less_mode) {
netsnmp_session_free(&session);
} else {
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, glob_snmp_object.enum_print);
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, glob_snmp_object.quick_print);
netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, glob_snmp_object.oid_output_format);
}

php_free_objid_query(&objid_query, oid_ht, value_str, value_ht, st);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this was moved to the bottom of the function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At one point with CI, it was complaining that glob_snmp_object would be used uninitialised.

@devnexen devnexen force-pushed the gh16959 branch 7 times, most recently from 30c826c to 215f9a9 Compare November 30, 2024 17:06
@devnexen devnexen requested a review from nielsdos November 30, 2024 17:53
ext/snmp/snmp.c Outdated
static void php_snmp_zend_string_release_from_char_pointer(char *ptr) {
if (ptr) {
zend_string *pptr = (zend_string *)(ptr - XtOffsetOf(zend_string, val));
if (GC_REFCOUNT(pptr)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you do this check?

ext/snmp/snmp.c Outdated
Comment on lines 649 to 651
uint32_t i = 0, count = zend_hash_num_elements(oid_ht);

while (i < count) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a for loop with extra steps imho

ext/snmp/snmp.c Outdated
if (!arg->oid) {
break;
}
PHP_FREE_OBJID_VAL(arg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a macro is not necessary here

ext/snmp/snmp.c Outdated
if (value_ht && !value_str) { \
php_snmp_zend_string_release_from_char_pointer(arg->value); \
} \
php_snmp_zend_string_release_from_char_pointer(&arg->type); \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, type is a char, this line should not be here

ext/snmp/snmp.c Outdated
zend_value_error("Type must be a single character");
efree(objid_query->vars);
zend_string_release(type);
Copy link
Member

@nielsdos nielsdos Nov 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly GH does not allow me to make suggestions here, but you're leaking memory and making it too complicated.
Place this release above the if on line 748. Then, prior to releasing: read the first character and put it in a variable. Then remove pptr = ZSTR_VAL(type); and put the read character in line 755 by using the variable.

ext/snmp/snmp.c Outdated
}
}

static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid_ht, zend_string *value_str, HashTable *value_ht, int st) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea to make value_ht and value_str const to indicate to the programmer that they are just used for checking.

@devnexen devnexen marked this pull request as ready for review November 30, 2024 20:56
Copy link
Member

@nielsdos nielsdos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one suggestion that you should verify, but otherwise lgtm

ext/snmp/snmp.c Outdated
if (!arg->oid) {
break;
}
if (value_ht && !value_str) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you only need to check value_ht, and then you can remove the value_str argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ll check a bit later, it s mainly because this but we ll see.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I see, but note that the way the arguments are parsed only value_ht or value_str can be non-NULL:

Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str)

Instead of modifying the zval, we use the zend_try_get_string.
@devnexen devnexen closed this in 73ebc92 Dec 1, 2024
charmitro pushed a commit to wasix-org/php that referenced this pull request Mar 13, 2025
Instead of modifying the zval, we use the zend_try_get_string.

close phpGH-16969
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Segmentation fault in snmpget
2 participants