From 3e1642e28847218d89d1bec2f8b035c10359ac91 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 13 Jul 2021 13:34:52 +0100 Subject: [PATCH] fixed heap-use-after-free in solidgen --- csrDraw.h | 22 ++++++++++++++++ csrMath.h | 73 +++++----------------------------------------------- csrMem.h | 1 + makeradar.sh | 2 +- vmf.h | 66 +++++++++++++---------------------------------- 5 files changed, 49 insertions(+), 115 deletions(-) diff --git a/csrDraw.h b/csrDraw.h index 14c91c2..f2b007f 100644 --- a/csrDraw.h +++ b/csrDraw.h @@ -2,6 +2,25 @@ typedef struct csr_frag csr_frag; typedef struct csr_target csr_target; typedef struct csr_filter csr_filter; +// MSAA patterns +v2f csr_msaa_1[] = +{ + {0.f, 0.f} +}; + +v2f csr_msaa_2x2[] = +{ + { 0.25f, 0.25f }, + { 0.25f, -0.25f }, + { -0.25f, -0.25f }, + { -0.25f, 0.25f } +}; + +v2f csr_msaa_2x2rgss[] = +{ + +}; + struct csr_frag { v3f co; @@ -202,6 +221,8 @@ void csr_draw( csr_target *rt, vmf_vert *triangles, u32 triangle_count, m4x3f tr // Derive normal matrix m4x3_to_3x3( transform, normal ); + + // NOTE: This isn't strictly necessary since CS:GO only uses uniform scaling. m3x3_inv_transpose( normal, normal ); for( u32 i = 0; i < triangle_count; i ++ ) @@ -263,6 +284,7 @@ void draw_vmf_group( csr_target *rt, vmf_map *map, vdf_node *root, csr_filter *f if( filter_visgroups && !vmf_visgroup_match( brush, group_id ) ) continue; + // TODO: heap-use-after-free solidgen_push( &solid, brush ); } } diff --git a/csrMath.h b/csrMath.h index c14234f..5a55ef2 100644 --- a/csrMath.h +++ b/csrMath.h @@ -3,34 +3,28 @@ #define CSR_PIf 3.14159265358979323846264338327950288f +// Simple min/max replacements float csr_minf( float a, float b ) { - if( a < b ) - return a; - return b; + return a < b? a: b; } float csr_maxf( float a, float b ) { - if( a > b ) - return a; - return b; + return a > b? a: b; } int csr_min( int a, int b ) { - if( a < b ) - return a; - return b; + return a < b? a: b; } int csr_max( int a, int b ) { - if( a > b ) - return a; - return b; + return a > b? a: b; } +// Convert double precision vec3 into single void v3d_v3f( double a[3], float b[3] ) { b[0] = a[0]; @@ -38,6 +32,7 @@ void v3d_v3f( double a[3], float b[3] ) b[2] = a[2]; } +// Convert degrees to radians float csr_rad( float deg ) { return deg * CSR_PIf / 180.0f; @@ -491,57 +486,3 @@ double plane_polarity( double p[4], double a[3] ) -(p[0]*p[3] * p[0] + p[1]*p[3] * p[1] + p[2]*p[3] * p[2]) ; } - -// Raycasting -// ================================================================================================================== - -int csr_slabs( v3f box[2], v3f o, v3f id ) -{ - v3f t0; v3f t1; - v3f tmin; v3f tmax; - - v3_sub( box[0], o, t0 ); - v3_sub( box[1], o, t1 ); - v3_mul( t0, id, t0 ); - v3_mul( t1, id, t1 ); - - v3_minv( t0, t1, tmin ); - v3_maxv( t0, t1, tmax ); - - return v3_maxf( tmin ) <= v3_minf( tmax ); -} - -float csr_ray_tri( v3f o, v3f d, v3f v0, v3f v1, v3f v2, float *u, float *v ) -{ - float const k_cullEpsilon = 0.000001f; - - v3f v0v1; - v3f v0v2; - v3f p; - float det, inv; - - v3f tv; - v3f qv; - - v3_sub( v1, v0, v0v1 ); - v3_sub( v2, v0, v0v2 ); - v3_cross( d, v0v2, p ); - - det = v3_dot( v0v1, p ); - - if( det < k_cullEpsilon ) return -INFINITY; - - inv = 1.f / det; - - v3_sub( o, v0, tv ); - *u = v3_dot( tv, p ) * inv; - - if( *u < 0.f || *u > 1.f ) return -INFINITY; - - v3_cross( tv, v0v1, qv ); - *v = v3_dot( d, qv ) * inv; - - if( *v < 0.f || *u + *v > 1.f ) return -INFINITY; - - return v3_dot( v0v2, qv ) * inv; -} diff --git a/csrMem.h b/csrMem.h index 2c12e44..25913be 100644 --- a/csrMem.h +++ b/csrMem.h @@ -50,6 +50,7 @@ void csr_sb_inc( void *arr, u32 amt ) raw[1] += amt; } +__attribute__((warn_unused_result)) void *csr_sb_reserve( void *arr, u32 amt, u32 esize ) { u32 cap = arr? csr_sb_cap( arr ): 0; diff --git a/makeradar.sh b/makeradar.sh index 85ae274..a2e3e8d 100755 --- a/makeradar.sh +++ b/makeradar.sh @@ -1 +1 @@ -./csRadar cs_apollo.vmf -g "/home/harry/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/gameinfo.txt" tar_layout +./csRadar cs_apollo.vmf -g "/home/harry/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo/gameinfo.txt" diff --git a/vmf.h b/vmf.h index ff3804d..c3abc2a 100644 --- a/vmf.h +++ b/vmf.h @@ -280,34 +280,12 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) { ESolidResult flag = k_ESolidResult_valid; + double planes[ SOLID_MAX_SIDES*4 ]; vmf_face faces[ SOLID_MAX_SIDES ]; - int is_displacement = 0; + int is_displacement = solid_has_displacement( node ); int num_planes = 0; - // TODO: What is this for again? surely it should be the other way around... i think... - if( solid_has_displacement( node ) ) - { - is_displacement = 1; - /* - - printf( "solid_has_displacement\n" ); - num_planes = vmf_api.bisectors; - - // Add dummy stuff for globals - // ??? - for( int k = 0; k < vmf_api.bisectors; k ++ ) - { - vmf_face *dummy = faces + k; - dummy->indices = NULL; - dummy->dispinfo = NULL; - dummy->material = NULL; - } - - is_displacement = 1; - */ - } - int it = 0; vdf_node *pSide; while( (pSide = vdf_next(node, "side", &it)) ) @@ -329,7 +307,7 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) kv_double_array( pSide, "plane", 9, points ); - tri_to_plane( points+6, points+3, points+0, vmf_api.planes + num_planes * 4 ); + tri_to_plane( points+6, points+3, points+0, planes + num_planes * 4 ); num_planes ++; } @@ -349,14 +327,14 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) if( (faces[ i[0] ].blacklisted && faces[ i[1] ].blacklisted && faces[ i[2] ].blacklisted) ) continue; - if( !plane_intersect( vmf_api.planes+i[0]*4, vmf_api.planes+i[1]*4, vmf_api.planes+i[2]*4, p ) ) + if( !plane_intersect( planes+i[0]*4, planes+i[1]*4, planes+i[2]*4, p ) ) continue; // Check for illegal verts (eg: got clipped by bisectors) int valid = 1; for( int m = 0; m < num_planes; m ++ ) { - if( plane_polarity( vmf_api.planes+m*4, p ) > 1e-6f ) + if( plane_polarity( planes+m*4, p ) > 1e-6f ) { valid = 0; break; @@ -381,7 +359,7 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) face_add_indice( faces + i[k], c ); v3d_v3f( p, ctx->verts[ c ].co ); - v3d_v3f( vmf_api.planes+i[k]*4, ctx->verts[ c ].nrm ); + v3d_v3f( planes+i[k]*4, ctx->verts[ c ].nrm ); csr_sb_inc( ctx->verts, 1 ); } @@ -398,7 +376,7 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) } // Sort each faces and trianglulalate them - for( int k = vmf_api.bisectors; k < num_planes; k ++ ) + for( int k = 0; k < num_planes; k ++ ) { vmf_face *face = faces + k; @@ -406,18 +384,15 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) if( csr_sb_count( face->indices ) < 3 ) { - if( !vmf_api.bisectors ) - { - flag = k_ESolidResult_degenerate; - fprintf( stderr, "Skipping degenerate face\n" ); - } + flag = k_ESolidResult_degenerate; + fprintf( stderr, "Skipping degenerate face\n" ); continue; } // Sort only if there is no displacements, or if this side is if( !is_displacement || ( is_displacement && face->dispinfo ) ) { - sort_coplanar( vmf_api.planes+k*4, ctx->verts, face->indices, csr_sb_count( face->indices ) ); + sort_coplanar( planes+k*4, ctx->verts, face->indices, csr_sb_count( face->indices ) ); } if( is_displacement ) @@ -427,13 +402,8 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) { if( csr_sb_count( face->indices ) != 4 ) { - // Mute error if we have global planes cause they - // are of course gonna fuck things up here - if( !vmf_api.bisectors ) - { - flag = k_ESolidResult_degenerate; - fprintf( stderr, "Skipping degenerate displacement\n" ); - } + flag = k_ESolidResult_degenerate; + fprintf( stderr, "Skipping degenerate displacement\n" ); continue; } @@ -458,12 +428,6 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) } } - // Get corners of displacement - float *SW = ctx->verts[ face->indices[ sw ] ].co; - float *NW = ctx->verts[ face->indices[ (sw+1) % 4] ].co; - float *NE = ctx->verts[ face->indices[ (sw+2) % 4] ].co; - float *SE = ctx->verts[ face->indices[ (sw+3) % 4] ].co; - // Can be either 5, 9, 17 numpoints = pow( 2, kv_get_int( dispinfo, "power", 2 ) ) + 1; u32 reqverts = numpoints*numpoints; @@ -471,6 +435,12 @@ ESolidResult solidgen_push( vmf_solid *ctx, vdf_node *node ) ctx->verts = csr_sb_reserve( ctx->verts, reqverts, sizeof( vmf_vert ) ); ctx->indices = csr_sb_reserve( ctx->indices, reqidx, sizeof( u32 ) ); + + // Get corners of displacement + float *SW = ctx->verts[ face->indices[ sw ] ].co; + float *NW = ctx->verts[ face->indices[ (sw+1) % 4] ].co; + float *NE = ctx->verts[ face->indices[ (sw+2) % 4] ].co; + float *SE = ctx->verts[ face->indices[ (sw+3) % 4] ].co; float normals[ 17*3 ]; float distances[ 17 ]; -- 2.25.1