Skip to content

Commit 52169a7

Browse files
committed
Fix: signed integer overflow when mixing in server seed value.
sysopt.serverseed is a plain int filled across the full positive range [1, INT_MAX] (the install-time generator uses v % 2147483647 and read_serverseed_file() accepts any val up to INT_MAX), so signed arithmetic that adds to it can overflow. On a build compiled with -fsanitize=undefined -fno-sanitize-recover=all this aborts the game outright; a player hit it at new-game start, where any seed in (INT_MAX - 8000000, INT_MAX] overflowed. The only real consumer, coord_hash(), already reads the value as unsigned int, so the overflow served no functional purpose. * src/allmain.c: newgame() did sysopt.serverseed += rn2(8000000), overflowing int for seeds near INT_MAX and aborting under UBSan at new-game start. Compute the sum as unsigned and mask with 0x7fffffff so the result stays a non-negative int. * src/shknam.c: the shopkeeper-name seed (int)((long)ubirthday/257L) + sysopt.serverseed had the same latent overflow. Promote the addition to unsigned and cast back; nseed is used only via % 13 and % 5 with an existing negative-result guard, so the defined wraparound is harmless and the non-overflowing value is unchanged.
1 parent 70aea70 commit 52169a7

3 files changed

Lines changed: 8 additions & 3 deletions

File tree

‎doc/evilhack-changelog.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5470,4 +5470,5 @@ The following changes to date are:
54705470
- Fix: aasimar race receiving Angelslayer as a sacrifice gift
54715471
- Gate artifact surge-suppression on weapon skill as well as blessing
54725472
- Aasimar monsters can invoke an aura of light; attribute light deaths
5473+
- Fix: signed integer overflow when mixing in server seed value
54735474

‎src/allmain.c‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,8 +1250,11 @@ newgame()
12501250
context.next_moloch_offering = 6000; /* give a grace period before
12511251
* the first sacrifice */
12521252

1253-
/* Extra entropy added to sysopt.serverseed */
1254-
sysopt.serverseed += rn2(8000000);
1253+
/* Extra entropy added to sysopt.serverseed; compute the sum as
1254+
unsigned and mask to a non-negative int so a seed already near
1255+
INT_MAX cannot overflow */
1256+
sysopt.serverseed = (int) (((unsigned) sysopt.serverseed
1257+
+ (unsigned) rn2(8000000)) & 0x7fffffff);
12551258

12561259
for (i = LOW_PM; i < NUMMONS; i++)
12571260
mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;

‎src/shknam.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,8 @@ const char *const *nlp;
514514
and restore support which would be necessary for randomization;
515515
try not to make too many assumptions about time_t's internals;
516516
use ledger_no rather than depth to keep mine town distinct. */
517-
int nseed = (int) ((long) ubirthday / 257L) + sysopt.serverseed;
517+
int nseed = (int) ((unsigned) ((long) ubirthday / 257L)
518+
+ (unsigned) sysopt.serverseed);
518519

519520
name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5);
520521
if (name_wanted < 0)

0 commit comments

Comments
 (0)