]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Fix ADDRESS instruction overflow.
authorRudolf Polzer <divVerent@gmail.com>
Wed, 30 Oct 2024 12:25:07 +0000 (08:25 -0400)
committerdivVerent <divVerent@gmail.com>
Tue, 12 Nov 2024 17:49:21 +0000 (12:49 -0500)
prvm_edict.c
sv_main.c

index 3d51018765899e2db0411169a7578cf602293747..d219d0b698b1f07a49d6759333df319bc27b0da0 100644 (file)
@@ -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
index f75a8d25cd47770d4e0dffbd59c5c2733c8fa5ac..5fded4c8b7a05e534a89a550dcf27f0abc984ebc 100644 (file)
--- 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;
                }