38 lines
1.3 KiB
C
38 lines
1.3 KiB
C
/*
|
|
* PHP-FPM env_path_info handling — pre-CVE-2019-11043.
|
|
* Reconstruction of fpm_main.c logic that mishandles the path_info pointer
|
|
* when a crafted URL like /index.php/%0a... causes path_info to point
|
|
* BEFORE script_name's start, yielding an out-of-bounds write of a NUL byte.
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
typedef struct {
|
|
char *script_name; /* attacker-controlled (request URI) */
|
|
char *path_info; /* derived from script_name */
|
|
} fcgi_request_t;
|
|
|
|
static int fpm_handle_request(fcgi_request_t *req) {
|
|
char *path_info = req->path_info;
|
|
int path_info_offset;
|
|
|
|
/* Compute offset of path_info into script_name. Normally non-negative. */
|
|
path_info_offset = path_info - req->script_name;
|
|
|
|
/* BUG: when crafted request makes path_info point BEFORE script_name's
|
|
buffer (e.g. due to %0a sequences earlier), path_info_offset becomes
|
|
NEGATIVE. No bounds check below. */
|
|
if (path_info != NULL) {
|
|
/* Original code wrote NUL here:
|
|
script_name[path_info_offset] = '\0';
|
|
which becomes an out-of-bounds write with attacker control of the
|
|
negative index, corrupting memory and enabling RCE via overwriting
|
|
fcgi env table pointers. */
|
|
req->script_name[path_info_offset] = '\0';
|
|
}
|
|
|
|
return 0;
|
|
}
|