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
libxls test.c and test2.c - NULL pointer dereference vulnerability due to xls_parseWorkSheet() misuse #94
Comments
|
Hi, thank you for the extensive report. However I believe that your concerns are somewhat misplaced; the library behaves as intended, returning NULL from getWorkSheet for a non-existent sheet index. There is indeed a bug in test2.c inasmuch as it should ensure that sheets.count > 0 before calling xls_getWorkSheet with an index of 0. However, this bug represents a misuse of the library, rather than a problem in the library itself. You can see an example of correct library usage in fuzz/fuzz_xls.c. I will be happy to entertain a pull request that modifies test2.c to use the library correctly. Because test2.c is not considered production code, I do not see a DoS attack vector based on the current report. |
|
Hi, Actually for (i = 0; i < pWB->sheets.count; i++) {If no loop there, it would be the same as test2.c. The bug has been reproduced in both test and test2. The bug can be reproduced just with the following steps when opening a zero-sheet XLS file:
As you say, programmers when using the library should take care about:
Both Also it would be better to add a NULL pointer check at the beginning of I'll change title to a more proper problem description Thanks |
|
UPDATE: Requested 3 Pull requests
I leave the solution for the decision of accepting pull requests or not. Closing this issue Thanks |
libxls xls_parseWorkSheet() - NULL pointer dereference
INTRODUCTION
A NULL pointer dereference vulnerability has been detected in the function
xls_parseWorkSheet()when trying to access therdiregister that is NULL at that time.Looking at the code we can realize it is because of trying to access
long offset = pWS->filepos;to that pointer, which is the argument for the function.The argument for
xls_parseWorkSheet()comes from the return value ofxls_getWorkSheet():If we enter the function
xls_getWorkSheet():We can easily deduce that if either
numis less than 0, ornumis greater thanpWB->sheets.countthe conditional won't succeed, thus returningpWSdirectly without assigning it a heap chunk.As the pointer has been initialized with NULL, a NULL pointer is returned, which will be the argument for the next function, and the program will crash when trying to access it.
REPRODUCE
To reproduce this crash, the
test2_libxlsfile has been used with a specially crafted XLS file.The crafted file needs to have no
BoundSheet8records to makepWB->sheets.countbe 0.ANALYSIS
As I explained in the Introduction section, we need
numto be less than 0 or greater thanpWB->sheets.count. Having one (or both) of those requirements can trigger the NULL pointer dereference.In
main():The first condition will never fail as
iwill always be greater or equal to 0.Also,
icannot be greater thanpWB->sheets.countas depends on it's value to be incremented.But... what if
pWB->sheets.countis equal to 0? Theniwill be 0 too.In the conditional
iwon't be less thanpWB->sheets.count, but equal, thus failing the conditional.The function
xls_addSheet(), responsible for incrementing thepWB->sheets.countvalue is never executed with the current PoC xls file, thus keeping until crash time the value which the program gave it when being initialized atxls_open_ole():But how do we make the program to not execute
xls_addSheet()?We initially need to avoid any
XLS_RECORD_BOUNDSHEETrecord.If we craft an XLS file that do not contain any
BoundSheet8record, this code will never reached:And
pWB->sheets.countwill be 0 when reaching the conditional code.The result is a SIGSEGV (Segmentation fault) interruption crashing the program trying to access non-mapped memory:
IMPACT
The most common issue with this type of vulnerability is a Denial of Service (DoS) once a crash has been triggered as demonstrated above with the crash PoC.
SOLUTION
A solution for this issue could be adding a pointer check before using it, and change the actions once a pointer is detected to be NULL.
Patch example:
Obviously, the pointer is used multiple times in the code, so having it NULL is something not expected. A more complex patch is needed to avoid unexpected results for the next functions to be executed instead of just returning if a NULL pointer is detected.
Anyway, a better solution for this patch is update the conditional at
xls_getWorkSheet()to this:This time, if
numis equal topWB->sheets.countthe heap chunk will be returned avoiding a NULL pointer being returned.The text was updated successfully, but these errors were encountered: