This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Possible Stack Based Buffer Overflow at Programs/_freeze_importlib.c
Type: security Stage:
Components: Library (Lib) Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: demonia, gvanrossum
Priority: normal Keywords:

Created on 2021-05-23 15:47 by demonia, last changed 2022-04-11 14:59 by admin.

Messages (1)
msg394203 - (view) Author: Mohammed Dief (demonia) * Date: 2021-05-23 15:47
When you open Programs/_freeze_importlib.c code, you will get the main function that gets executed when the C binary is running. That proves the first point that that's the function that is gonna be used when this code is getting built or used on other functions. at the first variables define lines you will find that there's a variable called: `buf` with memory limit of 100 bytes: https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Programs/_freeze_importlib.c#L37

If you continue tracking the `buf` variable usage, you will get that the first function it's used in is `sprintf` at: https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Programs/_freeze_importlib.c#L102 and as we all know, sprintf isn't a memory secure function on C. and when the memory size isn't validated then BOFs can happen in this case.

The sprintf function is using a variable called: `name` to store it's value to the buf variable, in this case the name variable is a constant variable that is defined as char with *name. then on https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Programs/_freeze_importlib.c#L51 the name variable value is set based on the first argument of the program.

That means, running a program with 96 'A' characters on the first argument can exceed the 100 bytes on the memory limit causing possible arbitrary code execution and DOS on the binary.
Once again, it's just a code review process. I dunno where the code is running but if you think this issue is invalid i would like to know where the code is running so I can dig deeper over there.

Here's some code tests that proves my point here too:
main.c:

#include<stdlib.h>
#include<stdio.h>

int main(int argc, char *argv[]){
    int i;
    const char *name;
    char buf[100];

    for(i=1; i < argc; i++) {
        name = argv[i];
        sprintf(buf, "<frozen %s>", name);
        puts(buf);
    }

    return 0;
}

shell:
gcc main.c -o main
./main $(python3 -c "print('A'*100)")

This issue was reported to PSRT, and they said the code is an internal tool that's used by developers not end-users. and asked me to open an issue here.
History
Date User Action Args
2022-04-11 14:59:46adminsetgithub: 88384
2021-05-23 16:53:07gvanrossumsetnosy: + gvanrossum
2021-05-23 15:47:04demoniacreate