Fix multiple security vulnerabilities across C, Python, and Go code

Timing-safe comparisons:
- crypto.c: Replace memcmp with CRYPTO_memcmp for Secret equality,
  require equal lengths before comparing
- remote_control.py: Constant-time password lookup to avoid leaking
  valid passwords via dict hash timing
- file_transmission.py: Use hmac.compare_digest for bypass token
  comparison instead of ==

Memory safety:
- child-monitor.c: Fix inverted condition in write_to_peer that
  prevented memmove from ever executing on partial writes
- ibus_glfw.c: Null-terminate IBUS_ADDRESS copy to prevent string
  overread when strlen >= PATH_MAX
- x11_window.c: Add NULL checks after realloc in clipboard/DnD
  data handling (two sites)
- dnd.c: Cap accepted_mimes at 1MB to prevent unbounded growth,
  fix realloc to not lose the original pointer on failure
- png-reader.c: Cast to size_t before multiplication to prevent
  integer overflow on 32-bit platforms

Secrets hygiene:
- disk-cache.c: Zero encryption_key with explicit_bzero before free

Tar extraction hardening:
- tar.go: Validate hardlink targets against destination prefix to
  prevent writing outside extraction directory
- tar.go: Strip setuid/setgid/sticky bits from extracted files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
z3rco
2026-04-03 16:10:46 +01:00
parent 0619c7e435
commit b39f88c6a2
10 changed files with 44 additions and 19 deletions

4
glfw/ibus_glfw.c vendored
View File

@@ -287,7 +287,9 @@ get_ibus_address_file_name(void) {
addr = getenv("IBUS_ADDRESS");
int offset = 0;
if (addr && addr[0]) {
memcpy(ans, addr, GLFW_MIN(strlen(addr), sizeof(ans)));
size_t len = GLFW_MIN(strlen(addr), sizeof(ans) - 1);
memcpy(ans, addr, len);
ans[len] = '\0';
return ans;
}
const char* disp_num = NULL;

8
glfw/x11_window.c vendored
View File

@@ -937,7 +937,9 @@ get_clipboard_data(const _GLFWClipboardData *cd, const char *mime, char **data)
if (!chunk.sz) break;
if (cap < sz + chunk.sz) {
cap = MAX(cap * 2, sz + 4 * chunk.sz);
buf = realloc(buf, cap * sizeof(buf[0]));
char *new_buf = realloc(buf, cap * sizeof(buf[0]));
if (!new_buf) { free(buf); *data = NULL; cd->get_data(NULL, iter, cd->ctype); return 0; }
buf = new_buf;
}
memcpy(buf + sz, chunk.data, chunk.sz);
sz += chunk.sz;
@@ -3636,7 +3638,9 @@ write_chunk(void *object, const char *data, size_t sz) {
if (data) {
if (cw->cap < cw->sz + sz) {
cw->cap = MAX(cw->cap * 2, cw->sz + 8*sz);
cw->buf = realloc(cw->buf, cw->cap * sizeof(cw->buf[0]));
char *new_buf = realloc(cw->buf, cw->cap * sizeof(cw->buf[0]));
if (!new_buf) return false;
cw->buf = new_buf;
}
memcpy(cw->buf + cw->sz, data, sz);
cw->sz += sz;