From 2db618ae2da445cf21a420c53e0297471a1a8ff1 Mon Sep 17 00:00:00 2001
From: Rob Swindell <rob@synchro.net>
Date: Sun, 3 Jul 2022 15:47:02 -0700
Subject: [PATCH] Fix smb.subnum corruption in writemsg()

Fix issue introduced 9 years ago that could cause a crash after replying to a post via email or netmail and then displaying the header of a poll message or a normal message with votes:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f9f9569a317 in sbbs_t::show_msg (this=0x7f9f70c56880,
    smb=0x7f9f70c5e4e0, msg=0x7f9ebadf08b0, p_mode=4, post=0x7f9f18071a24)
    at getmsg.cpp:255
255                                             ,cfg.sub[smb->subnum]->misc&SUB_                                                                              NAME ? useron.name : useron.alias, NET_NONE, NULL);
[Current thread is 1 (Thread 0x7f9ebadf3700 (LWP 23279))]
(gdb) print smb->subnum
$1 = 4294967295
(gdb) bt
#0  0x00007f9f9569a317 in sbbs_t::show_msg (this=0x7f9f70c56880,
    smb=0x7f9f70c5e4e0, msg=0x7f9ebadf08b0, p_mode=4, post=0x7f9f18071a24)
    at getmsg.cpp:255
#1  0x00007f9f957b2aee in sbbs_t::scanposts (this=0x7f9f70c56880, subnum=9,
    mode=2, find=0x7f9ebadf1270 "") at readmsgs.cpp:670
#2  0x00007f9f957bb75a in sbbs_t::scanallsubs (this=0x7f9f70c56880, mode=2)
    at scansubs.cpp:219
#3  0x00007f9f9568c948 in sbbs_t::exec_msg (this=0x7f9f70c56880,
    csi=0x7f9f70c64768) at execmsg.cpp:315
#4  0x00007f9f95683129 in sbbs_t::exec_function (this=0x7f9f70c56880,
    csi=0x7f9f70c64768) at execfunc.cpp:422
#5  0x00007f9f95679450 in sbbs_t::exec (this=0x7f9f70c56880,
    csi=0x7f9f70c64768) at exec.cpp:1199
#6  0x00007f9f9577d742 in node_thread (arg=0x7f9f70c56880) at main.cpp:4364

writemsg() was changing the global smb.subnum and when writing an email or netmail, that subnum value is -1 (since it's not a sub-board) and then later show_msg() is using the smb.subnum as a index into scfg.sub[] when determining if the current user already voted on the message being displayed and then: bang, crash, fall down, go boom.

Simply saving and restoring the smb.subnum when executing an external editor is all that was needed here. And this is the first use of the C++ "auto" keyword in Synchronet!
---
 src/sbbs3/writemsg.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index f06d8fc76d..e740547bf9 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -516,7 +516,6 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode,
 	}
 
 	editor_details[0] = 0;
-	smb.subnum = subnum;	/* Allow JS msgeditors to use bbs.smb_sub* */
 
 	if(console&CON_RAW_IN) {
 
@@ -596,8 +595,11 @@ bool sbbs_t::writemsg(const char *fname, const char *top, char *subj, long mode,
 
 		CLS;
 		rioctl(IOCM|PAUSE|ABORT);
+		auto savsubnum = smb.subnum;
+		smb.subnum = subnum;	/* Allow JS msgeditors to use bbs.smb_sub* */
 		const char* cmd = cmdstr(cfg.xedit[useron_xedit-1]->rcmd, msgtmp, nulstr, NULL, ex_mode);
 		int result = external(cmd, ex_mode, cfg.node_dir);
+		smb.subnum = savsubnum;
 		lprintf(LOG_DEBUG, "'%s' returned %d", cmd, result);
 		rioctl(IOSM|PAUSE|ABORT); 
 
-- 
GitLab