jcs
/subtext
/amendments
/429
serial: Add error checking, session buf canaries to try to find bug
Something is overwriting things in the session and trashing ibuflen
or obuflen, so add canaries in between struct members to try to find
where they get trashed.
jcs made amendment 429 about 1 year ago
--- serial.c Thu Feb 23 10:46:30 2023
+++ serial.c Wed Mar 15 21:14:56 2023
@@ -249,9 +249,14 @@ void
serial_flush(void)
{
long len;
+ short error;
for (;;) {
- SerGetBuf(serial_in_refnum, &len);
+ error = SerGetBuf(serial_in_refnum, &len);
+ if (error != 0) {
+ warn("SerGetBuf returned %d", error);
+ return;
+ }
if (!len)
break;
if (len > sizeof(serial_input_buf))
@@ -321,11 +326,16 @@ serial_get_line(bool wait)
size_t n;
long len, rem;
unsigned long started = Time;
-
+ short error;
+
maybe_read:
/* append as much new data as we can fit */
if (serial_input_buf_len < sizeof(serial_input_buf)) {
- SerGetBuf(serial_in_refnum, &len);
+ error = SerGetBuf(serial_in_refnum, &len);
+ if (error != 0) {
+ warn("SerGetBuf returned %d", error);
+ return NULL;
+ }
if (len) {
len = MIN(len, sizeof(serial_input_buf) - serial_input_buf_len);
FSRead(serial_in_refnum, &len,
@@ -416,10 +426,12 @@ serial_idle(void)
char *line;
SerStatus(serial_in_refnum, &status);
+#if 0
if (status.ctsHold != 0)
logger_printf("[modem] CTS set");
if (status.xOffHold != 0)
logger_printf("[modem] XOFF set");
+#endif
if (status.cumErrs != 0)
logger_printf("[modem] Reported errors: %d", status.cumErrs);
@@ -484,7 +496,8 @@ serial_input(struct session *session)
{
long len;
short error, n;
-
+ short lenwas = session->ibuflen;
+
if (session->ending)
return 0;
@@ -498,20 +511,37 @@ serial_input(struct session *session)
memmove(serial_input_buf, serial_input_buf + n,
serial_input_buf_len - n);
serial_input_buf_len -= n;
+
+ if (session->ibuflen < lenwas)
+ panic("serial ibuflen shrank");
+ if (session->ibuflen > sizeof(session->ibuf))
+ panic("serial ibuflen bogus");
+ session_check_buf_canaries(session);
+
return n;
}
-
- SerGetBuf(serial_in_refnum, &len);
+
+ error = SerGetBuf(serial_in_refnum, &len);
+ if (error != 0) {
+ warn("SerGetBuf returned %d", error);
+ return 0;
+ }
if (!len)
return 0;
len = MIN(len, sizeof(session->ibuf) - session->ibuflen);
error = FSRead(serial_in_refnum, &len,
- &session->ibuf + session->ibuflen);
+ session->ibuf + session->ibuflen);
+ session_check_buf_canaries(session);
if (error == noErr)
session->ibuflen += len;
else
logger_printf("[modem] Error from FSRead: %d", error);
+
+ if (session->ibuflen < lenwas)
+ panic("serial ibuflen shrank");
+ if (session->ibuflen > sizeof(session->ibuf))
+ panic("serial ibuflen bogus");
return len;
}
@@ -545,6 +575,7 @@ serial_output(struct session *session)
if (serial_write_pbr.ioParam.ioReqCount > session->obuflen)
warn("serial wrote more than obuflen?");
session->obuflen -= serial_write_pbr.ioParam.ioReqCount;
+ session_check_buf_canaries(session);
return serial_write_pbr.ioParam.ioReqCount;
}
--- session.h Fri Mar 10 16:22:44 2023
+++ session.h Wed Mar 15 18:37:35 2023
@@ -70,9 +70,13 @@ struct session {
char node[16];
char via[16];
unsigned char obuf[512];
+ unsigned long obuf_canary;
unsigned char ibuf[512];
+ unsigned long ibuf_canary;
short obuflen;
+ unsigned long obuflen_canary;
short ibuflen;
+ unsigned long ibuflen_canary;
short ibufoff;
unsigned long established_at;
char autologin_username[DB_USERNAME_LENGTH + 1];
@@ -147,6 +151,7 @@ void session_who(struct session *s);
char session_menu(struct session *s, char *title, char *prompt,
const struct session_menu_option *opts, size_t nopts, bool show_opts,
char *number_prompt, short *ret_number);
-void session_purge_logs(short days);
+void session_prune_logs(short days);
+void session_check_buf_canaries(struct session *session);
#endif /* __SESSION_H__ */