From 9ff9c206c9e902b361fa8aa847d359c361ff6168 Mon Sep 17 00:00:00 2001 From: Dave Vandervies Date: Sat, 14 Dec 2019 16:16:34 -0500 Subject: [PATCH] Don't leak stack garbage --- character.c | 82 ++++++++++++++++++++++++++--------------------------- chargen.c | 18 ++++++++---- chargen.h | 4 ++- 3 files changed, 56 insertions(+), 48 deletions(-) diff --git a/character.c b/character.c index b0f226a..f70ec59 100644 --- a/character.c +++ b/character.c @@ -319,7 +319,7 @@ void genBackground(){ } } -char * genChar(char* output){ +size_t genChar(char* output, size_t maxlen){ profs = 0; languages = 0; for(int i = 0; i <= 100; i++){ @@ -333,113 +333,113 @@ char * genChar(char* output){ stats[i] = dieroll(3,6); mods[i] = floor((stats[i]/2)-5); } - snprintf(output, 512, "Race = %s\r\nBackground = %s\r\nClass = %s\r\nStr = %d %d\r\nDex = %d %d\r\nCon = %d %d\r\nInt = %d %d\r\nWis = %d %d\r\nCha = %d %d\r\n\r\nHP: %d\r\n", race, background, class, stats[STR], mods[STR], stats[DEX], mods[DEX], stats[CON], mods[CON], stats[INT], mods[INT], stats[WIS], mods[WIS], stats[CHA], mods[CHA], hp); + snprintf(output, maxlen, "Race = %s\r\nBackground = %s\r\nClass = %s\r\nStr = %d %d\r\nDex = %d %d\r\nCon = %d %d\r\nInt = %d %d\r\nWis = %d %d\r\nCha = %d %d\r\n\r\nHP: %d\r\n", race, background, class, stats[STR], mods[STR], stats[DEX], mods[DEX], stats[CON], mods[CON], stats[INT], mods[INT], stats[WIS], mods[WIS], stats[CHA], mods[CHA], hp); - strlcat(output,"Proficiences:\r\n",512); + strlcat(output,"Proficiences:\r\n",maxlen); if((ATHLETICS & profs) != 0){ - strlcat(output,"Athletics\r\n",512); + strlcat(output,"Athletics\r\n",maxlen); } if((ACROBATICS & profs) != 0){ - strlcat(output,"Acrobatics\r\n",512); + strlcat(output,"Acrobatics\r\n",maxlen); } if((SLEIGHTOFHAND & profs) != 0){ - strlcat(output,"Sleight of Hand\r\n",512); + strlcat(output,"Sleight of Hand\r\n",maxlen); } if((STEALTH & profs) != 0){ - strlcat(output,"Stealth\r\n",512); + strlcat(output,"Stealth\r\n",maxlen); } if((ARCANA & profs) != 0){ - strlcat(output,"Arcana\r\n",512); + strlcat(output,"Arcana\r\n",maxlen); } if((HISTORY & profs) != 0){ - strlcat(output,"History\r\n",512); + strlcat(output,"History\r\n",maxlen); } if((INVESTIGATION & profs) != 0){ - strlcat(output,"Investigation\r\n",512); + strlcat(output,"Investigation\r\n",maxlen); } if((NATURE & profs) != 0){ - strlcat(output,"Nature\r\n",512); + strlcat(output,"Nature\r\n",maxlen); } if((RELIGION & profs) != 0){ - strlcat(output,"Regligion\r\n",512); + strlcat(output,"Regligion\r\n",maxlen); } if((ANIMALHANDLING & profs) != 0){ - strlcat(output,"Animal Handling\r\n",512); + strlcat(output,"Animal Handling\r\n",maxlen); } if((INSIGHT & profs) != 0){ - strlcat(output,"Insight\r\n",512); + strlcat(output,"Insight\r\n",maxlen); } if((MEDICINE & profs) != 0){ - strlcat(output,"Medicine\r\n",512); + strlcat(output,"Medicine\r\n",maxlen); } if((PERCEPTION & profs) != 0){ - strlcat(output,"Perception\r\n",512); + strlcat(output,"Perception\r\n",maxlen); } if((SURVIVAL & profs) != 0){ - strlcat(output,"Survival\r\n",512); + strlcat(output,"Survival\r\n",maxlen); } if((DECEPTION & profs) != 0){ - strlcat(output,"Deception\r\n",512); + strlcat(output,"Deception\r\n",maxlen); } if((INTIMIDATION & profs) != 0){ - strlcat(output,"Intimidation\r\n",512); + strlcat(output,"Intimidation\r\n",maxlen); } if((PERFORMANCE & profs) != 0){ - strlcat(output,"Performance\r\n",512); + strlcat(output,"Performance\r\n",maxlen); } if((PERSUASION & profs) != 0){ - strlcat(output,"Persuaion\r\n",512); + strlcat(output,"Persuaion\r\n",maxlen); } - strlcat(output,"\r\nLanguages:\r\nCommon\r\n",512); + strlcat(output,"\r\nLanguages:\r\nCommon\r\n",maxlen); if((ABYSSAL & languages) != 0){ - strlcat(output,"Abyssal\r\n",512); + strlcat(output,"Abyssal\r\n",maxlen); } if((CELESTIAL & languages) != 0){ - strlcat(output,"Celestial\r\n",512); + strlcat(output,"Celestial\r\n",maxlen); } if((DRACONIC & languages) != 0){ - strlcat(output,"Draconic\r\n",512); + strlcat(output,"Draconic\r\n",maxlen); } if((DEEPSPEECH & languages) != 0){ - strlcat(output,"Deep Speech\r\n",512); + strlcat(output,"Deep Speech\r\n",maxlen); } if((INFERNAL & languages) != 0){ - strlcat(output,"Infernal\r\n",512); + strlcat(output,"Infernal\r\n",maxlen); } if((PRIMORDIAL & languages) != 0){ - strlcat(output,"Primordial\r\n",512); + strlcat(output,"Primordial\r\n",maxlen); } if((SYLVAN & languages) != 0){ - strlcat(output,"Sylvan\r\n",512); + strlcat(output,"Sylvan\r\n",maxlen); } if((UNDERCOMMON & languages) != 0){ - strlcat(output,"Undercommon\r\n",512); + strlcat(output,"Undercommon\r\n",maxlen); } if((DWARVISH & languages) != 0){ - strlcat(output,"Dwarvish\r\n",512); + strlcat(output,"Dwarvish\r\n",maxlen); } if((ELVISH & languages) != 0){ - strlcat(output,"Elvish\r\n",512); + strlcat(output,"Elvish\r\n",maxlen); } if((GIANT & languages) != 0){ - strlcat(output,"Giant\r\n",512); + strlcat(output,"Giant\r\n",maxlen); } if((GNOMISH & languages) != 0){ - strlcat(output,"Gnome\r\n",512); + strlcat(output,"Gnome\r\n",maxlen); } if((GOBLIN & languages) != 0){ - strlcat(output,"Goblin\r\n",512); + strlcat(output,"Goblin\r\n",maxlen); } if((HALFLISH & languages) != 0){ - strlcat(output,"Halfling\r\n",512); + strlcat(output,"Halfling\r\n",maxlen); } if((ORC & languages) != 0){ - strlcat(output,"Orcish\r\n",512); + strlcat(output,"Orcish\r\n",maxlen); } - strlcat(output,"\r\nOther Profs: ",512); - strlcat(output,otherprofs,512); - strlcat(output,"\r\n",512); - return output; + strlcat(output,"\r\nOther Profs: ",maxlen); + strlcat(output,otherprofs,maxlen); + strlcat(output,"\r\n",maxlen); + return strlen(output); } diff --git a/chargen.c b/chargen.c index 37b2a03..4ee75b7 100644 --- a/chargen.c +++ b/chargen.c @@ -13,6 +13,11 @@ #include "chargen.h" +enum { + TCP_MAXLEN = 1024, + UDP_MAXLEN = 512, +}; + void usage_and_die(const char *myname, const char *fmt, ...) { if (fmt) @@ -246,9 +251,9 @@ int main(int argc, char **argv) printf("Responding to packet from %s:%s...\n", hbuf, sbuf); //rval = sendto(s, "chargen data\r\n", 14, 0, sa, len); - char character[512]; - genChar(character); - rval = sendto(s, character, 512, 0, sa, len); + char character[UDP_MAXLEN]; + size_t datalen = genChar(character, sizeof character); + rval = sendto(s, character, datalen, 0, sa, len); if (rval == -1) warn("sendto"); } @@ -283,9 +288,10 @@ int main(int argc, char **argv) printf("WTF? i=%u num_stream=%u stream_fds[i]=%d s=%d\n", i, num_stream, stream_fds[i], s); continue; } - char character[512]; - genChar(character); - if (write(s, character, 512) == -1) + char character[TCP_MAXLEN]; + size_t datalen = genChar(character, sizeof character); + /* TODO: Detect short writes and save the rest of the buffer for later */ + if (write(s, character, datalen) == -1) { warn("write"); printf("Closing stream connection\n"); diff --git a/chargen.h b/chargen.h index 334994a..d665842 100644 --- a/chargen.h +++ b/chargen.h @@ -1,6 +1,8 @@ #ifndef H_CHARGEN #define H_CHARGEN -char* genChar(); +#include + +size_t genChar(char *, size_t); #endif