From 18f5da30a93b4b2137b9e83d6ad87a4e87e42b5b Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Wed, 30 Oct 2024 08:25:07 -0400 Subject: [PATCH] Fix ADDRESS instruction overflow. --- prvm_edict.c | 9 +++++++++ sv_main.c | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/prvm_edict.c b/prvm_edict.c index 3d510187..c04f8a24 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -2052,6 +2052,7 @@ void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data char vabuf2[1024]; cvar_t *cvar; int structtype = 0; + int max_safe_edicts; if (prog->loaded) prog->error_cmd("%s: there is already a %s program loaded!", __func__, prog->name); @@ -2718,6 +2719,14 @@ fail: PRVM_FindOffsets(prog); + // Do not allow more than 2^31 total entityfields. Achieve this by limiting maximum edict count. + max_safe_edicts = ((1 << 31) - prog->numglobals) / prog->entityfields; + if (prog->limit_edicts > max_safe_edicts) + { + Con_Printf("%s: reducing maximum entity count to %d to avoid address overflow in %s\n", __func__, max_safe_edicts, prog->name); + prog->limit_edicts = max_safe_edicts; + } + prog->init_cmd(prog); // init mempools diff --git a/sv_main.c b/sv_main.c index 75ee1659..9382865d 100644 --- a/sv_main.c +++ b/sv_main.c @@ -1193,7 +1193,7 @@ static void Download_CheckExtensions(cmd_state_t *cmd) // first reset them all host_client->download_deflate = false; - + for(i = 2; i < argc; ++i) { if(!strcmp(Cmd_Argv(cmd, i), "deflate")) @@ -1237,7 +1237,7 @@ static void SV_Download_f(cmd_state_t *cmd) } is_csqc = (sv.csqc_progname[0] && strcmp(Cmd_Argv(cmd, 1), sv.csqc_progname) == 0); - + if (!sv_allowdownloads.integer && !is_csqc) { SV_ClientPrintf("Downloads are disabled on this server\n"); @@ -1258,17 +1258,17 @@ static void SV_Download_f(cmd_state_t *cmd) { char extensions[MAX_QPATH]; // make sure this can hold all extensions extensions[0] = '\0'; - + if(host_client->download_deflate) dp_strlcat(extensions, " deflate", sizeof(extensions)); - + Con_DPrintf("Downloading %s to %s\n", host_client->download_name, host_client->name); if(host_client->download_deflate && svs.csqc_progdata_deflated) host_client->download_file = FS_FileFromData(svs.csqc_progdata_deflated, svs.csqc_progsize_deflated, true); else host_client->download_file = FS_FileFromData(svs.csqc_progdata, sv.csqc_progsize, true); - + // no, no space is needed between %s and %s :P SV_ClientCommands("\ncl_downloadbegin %i %s%s\n", (int)FS_FileSize(host_client->download_file), host_client->download_name, extensions); @@ -1371,7 +1371,7 @@ static void SV_Download_f(cmd_state_t *cmd) { char extensions[MAX_QPATH]; // make sure this can hold all extensions extensions[0] = '\0'; - + if(host_client->download_deflate) strlcat(extensions, " deflate", sizeof(extensions)); @@ -1721,7 +1721,7 @@ static void SV_Prepare_CSQC(void) svs.csqc_progdata = NULL; svs.csqc_progdata_deflated = NULL; - + sv.csqc_progname[0] = 0; svs.csqc_progdata = FS_LoadFile(csqc_progname.string, sv_mempool, false, &progsize); @@ -2649,7 +2649,7 @@ double SV_Frame(double time) ++sv.perf_acc_offset_samples; sv.perf_acc_offset += offset; sv.perf_acc_offset_squared += offset * offset; - + if(sv.perf_acc_offset_max < offset) sv.perf_acc_offset_max = offset; } -- 2.39.2