Skip to content

Server: fix idle CPU busy-loop and network-reachable memory-safety bugs - #251

Open
Leproide wants to merge 1 commit into
CTR-tools:mainfrom
Leproide:fix/server-network-memory-safety-and-idle-cpu
Open

Server: fix idle CPU busy-loop and network-reachable memory-safety bugs#251
Leproide wants to merge 1 commit into
CTR-tools:mainfrom
Leproide:fix/server-network-memory-safety-and-idle-cpu

Conversation

@Leproide

@Leproide Leproide commented Aug 9, 2026

Copy link
Copy Markdown

Performance:

  • Main loop used usleep(1) with a non-blocking enet_host_service(..., 0), so it spun millions of times per second and burned about 20% of a core while idle with no clients. Raise the sleep to usleep(1000) (1 ms). A 1 ms tick is far finer than the 30/60 fps network rate; measured idle CPU dropped from about 22% to about 2%.

Network-reachable memory safety (unauthenticated peer, single UDP packet):

  • CG_JOINROOM accepted room == 16, indexing roomInfos[16] one past the 16-entry array and writing through it. Reject room >= 16.
  • ProcessReceiveEvent cast packet->data to message structs without checking packet->dataLength, allowing out-of-bounds reads from truncated packets (reachable pre-join for CG_JOINROOM). Validate the minimum length per type.

Hardening:

  • Player name is now NUL terminated server-side and printed with a bounded %.*s, preventing an over-read of client-controlled bytes.
  • Use fprintf(stderr, ...) instead of printf(stderr, ...).
  • Print build date/time and strftime output through explicit "%s" formats.
  • Check malloc return values in AddPeerLPL and AddIPBanL.

No wire-format or gameplay changes.

Performance:
- Main loop used usleep(1) with a non-blocking enet_host_service(..., 0), so
  it spun millions of times per second and burned about 20% of a core while
  idle with no clients. Raise the sleep to usleep(1000) (1 ms). A 1 ms tick is
  far finer than the 30/60 fps network rate; measured idle CPU dropped from
  about 22% to about 2%.

Network-reachable memory safety (unauthenticated peer, single UDP packet):
- CG_JOINROOM accepted room == 16, indexing roomInfos[16] one past the
  16-entry array and writing through it. Reject room >= 16.
- ProcessReceiveEvent cast packet->data to message structs without checking
  packet->dataLength, allowing out-of-bounds reads from truncated packets
  (reachable pre-join for CG_JOINROOM). Validate the minimum length per type.

Hardening:
- Player name is now NUL terminated server-side and printed with a bounded
  %.*s, preventing an over-read of client-controlled bytes.
- Use fprintf(stderr, ...) instead of printf(stderr, ...).
- Print build date/time and strftime output through explicit "%s" formats.
- Check malloc return values in AddPeerLPL and AddIPBanL.

No wire-format or gameplay changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant