Skip to content

lib/vector/vlib: Fix possible null pointer dereference - #4638

Open
ymdatta wants to merge 5 commits into
OSGeo:mainfrom
ymdatta:lib_vector_cats
Open

ymdatta wants to merge 5 commits into
OSGeo:mainfrom
ymdatta:lib_vector_cats

Conversation

@ymdatta

@ymdatta ymdatta commented Nov 2, 2024

Copy link
Copy Markdown
Contributor

In the function Vect_cat_list_to_array, as part of the execution, if list turns out to not contain any numbers, cats internal variable is not changed from NULL. Without checking if cats is NULL or not, qsort or first elemnt of it is accessed, which can lead to null pointer dereference.

To fix that issue, only access cats if it's not NULL.

This issue was found using cppcheck tool.

In the function `Vect_cat_list_to_array`, as part of the
execution, if list turns out to not contain any numbers,
`cats` internal variable is not changed from NULL. Without
checking if `cats` is NULL or not, qsort or first elemnt of
it is accessed, which can lead to null pointer dereference.

To fix that issue, only access cats if it's not NULL.

This issue was found using cppcheck tool.

Signed-off-by: Mohan Yelugoti <ymdatta.work@gmail.com>
@github-actions github-actions Bot added vector Related to vector data processing C Related code is in C libraries labels Nov 2, 2024
@nilason nilason changed the title lib:vector:vlib: Fix possible null pointer dereference lib/vector/vlib: Fix possible null pointer dereference Nov 5, 2024
@nilason nilason added this to the 8.5.0 milestone Nov 5, 2024
ymdatta added a commit to ymdatta/grass that referenced this pull request Nov 27, 2024
Documented each supression issue with comments to distinguish between
false positives and true positives awaiting resolution.

For the false positives supressions, appropriate information is
provided on why those were considered as false positive.

True positives will be removed from the suppression file once
their corresponding fixes(OSGeo#4702, OSGeo#4638, OSGeo#4500, OSGeo#4499) are merged.

Run:

`cppcheck --suppressions-list=.cppcheck-supressions <path>`

Signed-off-by: Mohan Yelugoti <ymdatta.work@gmail.com>
ymdatta added a commit to ymdatta/grass that referenced this pull request Nov 27, 2024
Documented each suppression issue with comments to distinguish between
false positives and true positives awaiting resolution.

For the false positives suppressions, appropriate information is
provided on why those were considered as false positive.

True positives will be removed from the suppression file once
their corresponding fixes(OSGeo#4702, OSGeo#4638, OSGeo#4500, OSGeo#4499) are merged.

Run:

`cppcheck --suppressions-list=.cppcheck-suppressions <path>`

Signed-off-by: Mohan Yelugoti <ymdatta.work@gmail.com>
Comment thread lib/vector/Vlib/cats.c
*nvals = n_cats = 0;
*nvals = n_cats = n_ucats = 0;
cats = NULL;
for (i = 0; i < list->n_ranges; i++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems to me to be a better solution to make an early exit before this for statement, with something like:

if (list->n_ranges <= 0)
    return -1;

If list->n_ranges is 0 or less, cats and n_cats are never set... and the rest doesn't make any sense.

@metzm Perhaps you may have some insight in this?

@ymdatta ymdatta Dec 11, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@nilason : Thanks for the review.

But, I am worried that '-1' indicates that something has gone wrong while converting using Vect_cat_list_to_array function, but here there is nothing wrong and it's just that the argument has no elements in it. What do you think about it?

@metzm metzm May 11, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would suggest to make an early exit just before qsort, like

if (n_cats == 0) {
    return 0;
}

This is not a failure, there would be simply no entries in the list.

@nilason nilason modified the milestones: 8.5.0, 8.5.1 Feb 12, 2026
@Valyrian-Code

Valyrian-Code commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Not a maintainer, just going through old unreviewed PRs. The bug is real, but I think the fix leaves a problem in the same path.

ucats is uninitialised at line 490 and this patch only assigns it inside if (cats). So when cats is NULL, which is the case being fixed, it still reaches G_realloc(ucats, ...) and *vals = ucats with the pointer never set. n_ucats = 0 makes the size 0 but the pointer argument is still garbage. Setting ucats = NULL next to cats = NULL would cover it.

Easiest trigger is a list straight from Vect_new_cat_list(), which sets n_ranges = 0, so the loop never runs.

Read from source, I have not built it.

@echoix

echoix commented Sep 12, 2026

Copy link
Copy Markdown
Member

Not a maintainer, just going through old unreviewed PRs. The bug is real, but I think the fix leaves a problem in the same path.

ucats is uninitialised at line 490 and this patch only assigns it inside if (cats). So when cats is NULL, which is the case being fixed, it still reaches G_realloc(ucats, ...) and *vals = ucats with the pointer never set. n_ucats = 0 makes the size 0 but the pointer argument is still garbage. Setting ucats = NULL next to cats = NULL would cover it.

Easiest trigger is a list straight from Vect_new_cat_list(), which sets n_ranges = 0, so the loop never runs.

Read from source, I have not built it.

Whats your opinion on #7835 compared to this one then?

@Valyrian-Code

Valyrian-Code commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

I think #7835 is better. It returns -1 for an empty list where this one returns 0 with an array the caller reads. copy.c:717 is the only in-tree caller and its else branch, for a NULL cat_list, copies everything, so an empty selection handed back as an array risks copying all categories instead of none.

#7835 also removes the two cppcheck suppressions, and this one would still need ucats = NULL to be correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C libraries vector Related to vector data processing

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants