Skip to content

Commit

Permalink
feat: hard cap the size of a session chat log to 100 MiB
Browse files Browse the repository at this point in the history
This mitigates a potential DOS attack vector.
  • Loading branch information
JFreegman committed Feb 28, 2024
1 parent 149ef9d commit 68beece
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
24 changes: 21 additions & 3 deletions src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,13 @@ static int init_logging_session(const Client_Config *c_config, const char *name,
return 0;
}

#define LOG_FLUSH_LIMIT 1 /* limits calls to fflush to a max of one per LOG_FLUSH_LIMIT seconds */
/* limits calls to fflush to a max of one per LOG_FLUSH_LIMIT seconds */
#define LOG_FLUSH_LIMIT 1

/* We stop writing to the log after we've written at least this many bytes during the current session.
* A new session is started with `log_enable()`, and ended with `log_disable()`.
*/
#define LOG_BYTES_THRESHOLD ((1024 << 10) * 100) // 100 MiB

int write_to_log(struct chatlog *log, const Client_Config *c_config, const char *msg, const char *name,
bool is_event, Log_Hint log_hint)
Expand All @@ -142,6 +148,11 @@ int write_to_log(struct chatlog *log, const Client_Config *c_config, const char
return -1;
}

if (log->bytes_written >= LOG_BYTES_THRESHOLD) {
fprintf(stderr, "Warning: Log file is full (%u bytes written)\n", log->bytes_written);
return -1;
}

char name_frmt[TOXIC_MAX_NAME_LENGTH + 3];

if (name != NULL) {
Expand All @@ -156,17 +167,23 @@ int write_to_log(struct chatlog *log, const Client_Config *c_config, const char
char s[MAX_STR_SIZE];
get_time_str(s, sizeof(s), t);

int bytes_written;

if (name == NULL) {
fprintf(log->file, "{%d} %s %s\n", log_hint, s, msg);
bytes_written = fprintf(log->file, "{%d} %s %s\n", log_hint, s, msg);
} else {
fprintf(log->file, "{%d} %s %s %s\n", log_hint, s, name_frmt, msg);
bytes_written = fprintf(log->file, "{%d} %s %s %s\n", log_hint, s, name_frmt, msg);
}

if (timed_out(log->lastwrite, LOG_FLUSH_LIMIT)) {
fflush(log->file);
log->lastwrite = get_unix_time();
}

if (bytes_written > 0) {
log->bytes_written += bytes_written;
}

return 0;
}

Expand All @@ -183,6 +200,7 @@ void log_disable(struct chatlog *log)

log->lastwrite = 0;
log->log_on = false;
log->bytes_written = 0;
}

int log_enable(struct chatlog *log)
Expand Down
10 changes: 8 additions & 2 deletions src/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct chatlog {
time_t lastwrite;
char path[MAX_STR_SIZE];
bool log_on; /* specific to current chat window */
uint32_t bytes_written;
};

typedef enum Log_Type {
Expand Down Expand Up @@ -75,14 +76,19 @@ int log_init(struct chatlog *log, const Client_Config *c_config, const char *nam
int write_to_log(struct chatlog *log, const Client_Config *c_config, const char *msg, const char *name,
bool is_event, Log_Hint log_hint);

/* enables logging for specified log.
/* Enables logging for specified log.
*
* Calling this function on a log that's already enabled has no effect.
*
* Returns 0 on success.
* Returns -1 on failure.
*/
int log_enable(struct chatlog *log);

/* disables logging for specified log and closes file */
/* Disables logging for specified log and closes file.
*
* Calling this function on a log that's already disabled has no effect.
*/
void log_disable(struct chatlog *log);

/* Loads chat log history and prints it to `self` window.
Expand Down

0 comments on commit 68beece

Please sign in to comment.