36 lines
1.2 KiB
C
36 lines
1.2 KiB
C
/*
|
|
* GNU patch ed-mode dispatch — pre-CVE-2018-1000156 simplification.
|
|
* The `patch` utility invokes /bin/ed when the patch file declares ed-mode.
|
|
* The path passed to ed is derived from the patch header's "Index:" / "+++"
|
|
* line without sanitisation; attacker controls it via the patchfile.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
static char *target_path_from_patch_header(const char *patch_line) {
|
|
/* Strips "+++ " prefix and returns a malloc'd copy. No validation. */
|
|
const char *space = strchr(patch_line, ' ');
|
|
if (!space) return NULL;
|
|
return strdup(space + 1);
|
|
}
|
|
|
|
int apply_ed_patch(const char *patch_header_line, const char *patch_body_path) {
|
|
char *target = target_path_from_patch_header(patch_header_line);
|
|
if (!target) return -1;
|
|
|
|
/*
|
|
* BUG: target is attacker-controlled and contains arbitrary characters,
|
|
* including shell metacharacters like backticks and $(). This string is
|
|
* concatenated directly into a shell command that runs /bin/ed.
|
|
*/
|
|
char cmd[4096];
|
|
snprintf(cmd, sizeof(cmd), "ed -s %s < %s", target, patch_body_path);
|
|
int rc = system(cmd);
|
|
|
|
free(target);
|
|
return rc;
|
|
}
|