dynamic format strings vulnerable to user input
This adds new utility routine strNsubst(), a more versatile version of the existing strsubst(), that can replace the Nth occurrence of a substring rather than just the first, and replaces all occurrences if N is 0. When working on vampire shape-shifting messages a few days ago I noticed that a constructed pline/sprintf format was vulnerable to the player giving the vampire a name with '%' in it and included a fix for that. This fixes two other instances of the same vulnerability: a monster with reflection triggering a floating eye's gaze and the hero using a silver weapon against a silver- hating monster. I didn't do a lot of experimenting with the failure, just assigned the name "foo%s" to the floating eye or the weapon. The resulting feedback for the relevant messages was garbled due to parameters being substituted in the wrong place. When that caused there to be too few arguments to satisfy the format, the final message included "null" for the missing one rather than triggering a crash while trying to format something arbitrary from the stack. I don't think these bugs provided sufficient user control to be vulnerable to stack manipulation that does something naughty. I found the dynamic format strings by searching for "%%". There may be others scattered around the code which don't have that as an indicator....
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1496531111 2017/06/03 23:05:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.589 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1496860756 2017/06/07 18:39:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.590 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -876,6 +876,7 @@ E boolean FDECL(onlyspace, (const char *));
|
||||
E char *FDECL(tabexpand, (char *));
|
||||
E char *FDECL(visctrl, (CHAR_P));
|
||||
E char *FDECL(strsubst, (char *, const char *, const char *));
|
||||
E int FDECL(strNsubst, (char *, const char *, const char *, int));
|
||||
E const char *FDECL(ordin, (int));
|
||||
E char *FDECL(sitoa, (int));
|
||||
E int FDECL(sgn, (int));
|
||||
|
||||
Reference in New Issue
Block a user