jcs
/subtext
/amendments
/344
session: Handle malloc failure, use grow_to_fit
jcs made amendment 344 about 1 year ago
--- session.c Tue Feb 28 09:35:56 2023
+++ session.c Thu Mar 2 09:05:05 2023
@@ -74,15 +74,10 @@ session_create(char *node, char *via, struct node_func
if (nsessions == MAX_SESSIONS)
return NULL;
}
-
- nsessions++;
- session = xmalloczero(sizeof(struct session), "session_create");
- session->uthread = uthread_add(session_run, session);
- if (!session->uthread) {
- xfree(&session);
+ session = xmalloczero(sizeof(struct session));
+ if (session == NULL)
return NULL;
- }
session->node_funcs = node_funcs;
strlcpy(session->node, node, sizeof(session->node));
@@ -91,14 +86,23 @@ session_create(char *node, char *via, struct node_func
session->last_input_at = session->established_at = Time;
for (n = 0; n < MAX_SESSIONS; n++) {
- if (sessions[n] == NULL) {
- sessions[n] = session;
- return session;
+ if (sessions[n] != NULL)
+ continue;
+
+ session->uthread = uthread_add(session_run, session);
+ if (!session->uthread) {
+ xfree(&session);
+ return NULL;
}
+
+ sessions[n] = session;
+ nsessions++;
+ return session;
}
-
- panic("session_create failed to find slot for new session (%d)",
- nsessions);
+
+ /* no room, but how did we get here? */
+ xfree(&session);
+ return NULL;
}
void
@@ -634,7 +638,11 @@ session_output_view_or_printf(struct session *session,
return size;
}
- view = xmalloc(o->size + 1, "session_output_view_or_printf");
+ view = xmalloc(o->size + 1);
+ if (view == NULL) {
+ xfree(&o);
+ return 0;
+ }
size = bile_read_object(db->bile, o, view, o->size);
view[size] = '\0';
xfree(&o);
@@ -838,7 +846,11 @@ session_field_input(struct session *session, unsigned
session->abort_input = false;
- field = xmalloczero(size, "session_field_input");
+ field = xmalloczero(size);
+ if (field == NULL) {
+ session->ending = true;
+ return NULL;
+ }
if (initial_input) {
ipos = ilen = strlcpy(field, initial_input, size);
@@ -988,8 +1000,9 @@ session_login(struct session *s)
if (s->autologin_username[0]) {
session_printf(s, "{{#}}%s\r\n", s->autologin_username);
session_flush(s);
- username = xstrdup(s->autologin_username,
- "session_login username");
+ username = xstrdup(s->autologin_username);
+ if (username == NULL)
+ goto login_bail;
} else {
session_flush(s);
username = session_field_input(s, DB_USERNAME_LENGTH + 1,
@@ -1146,11 +1159,17 @@ session_expand_template(struct session *session, const
varlen = 0;
n++;
} else if (tmpl[n] == '\r' && tmpl[n + 1] != '\n') {
- EXPAND_TO_FIT(data, retsize, retpos, 2, 64);
+ if (!grow_to_fit(&data, &retsize, retpos, 2, 64)) {
+ xfree(&data);
+ break;
+ }
data[retpos++] = '\r';
data[retpos++] = '\n';
} else {
- EXPAND_TO_FIT(data, retsize, retpos, 1, 64);
+ if (!grow_to_fit(&data, &retsize, retpos, 1, 64)) {
+ xfree(&data);
+ break;
+ }
data[retpos++] = tmpl[n];
}
@@ -1217,7 +1236,10 @@ expand_var:
}
if (vallen) {
- EXPAND_TO_FIT(data, retsize, retpos, vallen, 128);
+ if (!grow_to_fit(&data, &retsize, retpos, vallen, 128)) {
+ xfree(&data);
+ break;
+ }
memcpy(data + retpos, val, vallen);
retpos += vallen;
}
@@ -1396,14 +1418,19 @@ session_print_motd(struct session *s, bool force)
last_seen_motd = s->user->last_motd_seen;
o = bile_get_nth_of_type(db->bile, 0, DB_MOTD_RTYPE);
- motd_id = o->id;
- if (o == NULL || (!force && motd_id <= last_seen_motd)) {
+ if (o == NULL || (!force && o->id <= last_seen_motd)) {
if (o)
xfree(&o);
return;
}
+ motd_id = o->id;
- view = xmalloc(o->size + 1, "motd view");
+ view = xmalloc(o->size + 1);
+ if (view == NULL) {
+ s->ending = true;
+ xfree(&o);
+ return;
+ }
size = bile_read_object(db->bile, o, view, o->size);
view[size] = '\0';
xfree(&o);
@@ -1621,8 +1648,9 @@ session_purge_logs(short days)
delta = Time - log.logged_on_at;
if (delta > secs) {
- EXPAND_TO_FIT(ids, size, count * sizeof(unsigned long),
- sizeof(unsigned long), 10 * sizeof(unsigned long));
+ if (!grow_to_fit(&ids, &size, count * sizeof(unsigned long),
+ sizeof(unsigned long), 10 * sizeof(unsigned long)))
+ break;
ids[count++] = obj->id;
}