From: Rudolf Polzer Date: Wed, 30 Oct 2024 12:25:07 +0000 (-0400) Subject: Fix ADDRESS instruction overflow. X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=107fb2d13d4c3980d22f7624918f8ffc319eeea9;p=xonotic%2Fdarkplaces.git Fix ADDRESS instruction overflow. --- diff --git a/prvm_edict.c b/prvm_edict.c index 3d510187..d219d0b6 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,15 @@ fail: PRVM_FindOffsets(prog); + // Do not allow more than 2^31 total entityfields. Achieve this by limiting maximum edict count. + // TODO: For PRVM_64, this can be relaxes. May require changing some types away from int. + 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 f75a8d25..5fded4c8 100644 --- a/sv_main.c +++ b/sv_main.c @@ -1195,7 +1195,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")) @@ -1239,7 +1239,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"); @@ -1260,17 +1260,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); @@ -1373,7 +1373,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)); @@ -1723,7 +1723,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); @@ -2651,7 +2651,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; }