Skip to content

Commit

Permalink
Server: Check for invalid floats in all packets
Browse files Browse the repository at this point in the history
This adds checks for nan/inf in all instances where a float is read
from a packet, and drops it if an invalid value is found.

The vector3f_t check is located in a new file, VectorChecks.c.

Credits to burner (DavidCo113 <davidco7777@protonmail.com>) for telling me about this.
  • Loading branch information
utf-4096 authored and Haxk20 committed Jun 20, 2023
1 parent 7e8999d commit 4b03847
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 16 deletions.
27 changes: 24 additions & 3 deletions Source/Server/Packets/Grenade.c
Expand Up @@ -4,6 +4,7 @@
#include <Util/Checks/PlayerChecks.h>
#include <Util/Checks/PositionChecks.h>
#include <Util/Checks/TimeChecks.h>
#include <Util/Checks/VectorChecks.h>
#include <Util/Enums.h>
#include <Util/Log.h>
#include <Util/Nanos.h>
Expand Down Expand Up @@ -45,31 +46,51 @@ void receive_grenade_packet(server_t* server, player_t* player, stream_t* data)
return;
}

if (player->sprinting) {
return;
}

uint64_t timeNow = get_nanos();
if (!diff_is_older_then(timeNow, &player->timers.since_last_grenade_thrown, NANO_IN_MILLI * 500) ||
!diff_is_older_then_dont_update(timeNow, player->timers.since_possible_spade_nade, (long) NANO_IN_MILLI * 1000))
{
return;
}

if (player->grenades > 0) {
grenade_t* grenade = malloc(sizeof(grenade_t));
if (grenade == NULL) {
LOG_ERROR("Allocation of memory failed. EXITING");
server->running = 0;
return;
}
grenade->fuse = fminf(3.0f, stream_read_f(data));

float fuse = stream_read_f(data);
if (isnan(fuse) || isinf(fuse)) {
free(grenade);
return;
}

grenade->fuse = fminf(3.0f, fuse);
grenade->position.x = stream_read_f(data);
grenade->position.y = stream_read_f(data);
grenade->position.z = stream_read_f(data);
float velX = stream_read_f(data), velY = stream_read_f(data), velZ = stream_read_f(data);
if (player->sprinting) {

if (!valid_vec3f(grenade->position)) {
free(grenade);
return;
}

float velX = stream_read_f(data), velY = stream_read_f(data), velZ = stream_read_f(data);
grenade->velocity.x = velX;
grenade->velocity.y = velY;
grenade->velocity.z = velZ;

if (!valid_vec3f(grenade->velocity)) {
free(grenade);
return;
}

vector3f_t velocity = {grenade->velocity.x - player->movement.velocity.x,
grenade->velocity.y - player->movement.velocity.y,
grenade->velocity.z - player->movement.velocity.z};
Expand Down
32 changes: 19 additions & 13 deletions Source/Server/Packets/OrientationData.c
@@ -1,29 +1,35 @@
#include <Server/Packets/ReceivePackets.h>
#include <Server/Server.h>
#include <Util/Checks/VectorChecks.h>
#include <Util/Physics.h>
#include <math.h>

void receive_orientation_data(server_t* server, player_t* player, stream_t* data)
{
(void) server;
float x, y, z;
x = stream_read_f(data);
y = stream_read_f(data);
z = stream_read_f(data);
if ((x + y + z) == 0) {

vector3f_t orientation = {stream_read_f(data), stream_read_f(data), stream_read_f(data)};

if ((orientation.x + orientation.y + orientation.z) == 0) {
return;
}
float length = sqrt((x * x) + (y * y) + (z * z));
float norm_legnth = 1 / length;

if (!valid_vec3f(orientation)) {
return;
}

float length = sqrt((orientation.x * orientation.x) + (orientation.y * orientation.y) + (orientation.z * orientation.z));
float norm_length = 1 / length;

// Normalize the vectors if their length > 1
if (length > 1.f) {
player->movement.forward_orientation.x = x * norm_legnth;
player->movement.forward_orientation.y = y * norm_legnth;
player->movement.forward_orientation.z = z * norm_legnth;
player->movement.forward_orientation.x = orientation.x * norm_length;
player->movement.forward_orientation.y = orientation.y * norm_length;
player->movement.forward_orientation.z = orientation.z * norm_length;
} else {
player->movement.forward_orientation.x = x;
player->movement.forward_orientation.y = y;
player->movement.forward_orientation.z = z;
player->movement.forward_orientation.x = orientation.x;
player->movement.forward_orientation.y = orientation.y;
player->movement.forward_orientation.z = orientation.z;
}

physics_reorient_player(player, &player->movement.forward_orientation);
Expand Down
5 changes: 5 additions & 0 deletions Source/Server/Packets/PositionData.c
@@ -1,5 +1,6 @@
#include <Server/Server.h>
#include <Util/Checks/PositionChecks.h>
#include <Util/Checks/VectorChecks.h>

void send_position_packet(server_t* server, player_t* player, float x, float y, float z)
{
Expand All @@ -21,6 +22,10 @@ void receive_position_data(server_t* server, player_t* player, stream_t* data)
{
vector3f_t position = {stream_read_f(data), stream_read_f(data), stream_read_f(data)};

if(!valid_vec3f(position)) {
return;
}

if (distance_in_3d(player->movement.position, position) >= 3) {
send_position_packet(
server, player, player->movement.position.x, player->movement.position.y, player->movement.position.z);
Expand Down
2 changes: 2 additions & 0 deletions Source/Util/CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ set(CHECKS_HEADERS
Checks/PositionChecks.h
Checks/TimeChecks.h
Checks/WeaponChecks.h
Checks/VectorChecks.h
)

set(CHECKS_SOURCES
Expand All @@ -20,6 +21,7 @@ set(CHECKS_SOURCES
Checks/PositionChecks.c
Checks/TimeChecks.c
Checks/WeaponChecks.c
Checks/VectorChecks.c
)

set(MT_HEADERS
Expand Down
9 changes: 9 additions & 0 deletions Source/Util/Checks/VectorChecks.c
@@ -0,0 +1,9 @@
#include <Util/Checks/VectorChecks.h>
#include <Util/Types.h>
#include <math.h>

inline uint8_t valid_vec3f(vector3f_t vec)
{
return !(isnan(vec.x) || isnan(vec.y) || isnan(vec.z) ||
isinf(vec.x) || isinf(vec.y) || isinf(vec.z));
}
8 changes: 8 additions & 0 deletions Source/Util/Checks/VectorChecks.h
@@ -0,0 +1,8 @@
#ifndef VECTOR_CHECKS_H
#define VECTOR_CHECKS_H

#include <Util/Types.h>

uint8_t valid_vec3f(vector3f_t vec);

#endif

0 comments on commit 4b03847

Please sign in to comment.