mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-07-10 09:43:26 +00:00
Merge branch 'security-hardening' of https://github.com/z3rco/kitty
This commit is contained in:
commit
d8f2d703d7
10 changed files with 44 additions and 19 deletions
4
glfw/ibus_glfw.c
vendored
4
glfw/ibus_glfw.c
vendored
|
|
@ -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
8
glfw/x11_window.c
vendored
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1940,7 +1940,7 @@ write_to_peer(Peer *peer) {
|
|||
else if (n < 0) {
|
||||
if (errno != EINTR) { log_error("write() to peer socket failed with error: %s", strerror(errno)); peer->write.used = 0; peer->write.failed = true; }
|
||||
} else {
|
||||
if ((size_t)n > peer->write.used) memmove(peer->write.data, peer->write.data + n, peer->write.used - n);
|
||||
if ((size_t)n < peer->write.used) memmove(peer->write.data, peer->write.data + n, peer->write.used - n);
|
||||
peer->write.used -= n;
|
||||
}
|
||||
talk_mutex(unlock);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <sys/mman.h>
|
||||
#include <structmember.h>
|
||||
|
||||
|
|
@ -72,8 +73,8 @@ dealloc_secret(Secret *self) {
|
|||
|
||||
static int
|
||||
__eq__(Secret *a, Secret *b) {
|
||||
const size_t l = a->secret_len < b->secret_len ? a->secret_len : b->secret_len;
|
||||
return memcmp(a->secret, b->secret, l) == 0;
|
||||
if (a->secret_len != b->secret_len) return 0;
|
||||
return CRYPTO_memcmp(a->secret, b->secret, a->secret_len) == 0;
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "cross-platform-random.h"
|
||||
#include <structmember.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
|
@ -40,7 +41,7 @@ static uint64_t key_hash(KEY_TY k);
|
|||
#define HASH_FN key_hash
|
||||
static bool keys_are_equal(CacheKey a, CacheKey b) { return a.hash_keylen == b.hash_keylen && memcmp(a.hash_key, b.hash_key, a.hash_keylen) == 0; }
|
||||
#define CMPR_FN keys_are_equal
|
||||
static void free_cache_value(CacheValue *cv) { free(cv->data); cv->data = NULL; free(cv); }
|
||||
static void free_cache_value(CacheValue *cv) { explicit_bzero(cv->encryption_key, sizeof(cv->encryption_key)); free(cv->data); cv->data = NULL; free(cv); }
|
||||
static void free_cache_key(CacheKey cv) { free(cv.hash_key); cv.hash_key = NULL; }
|
||||
#define KEY_DTOR_FN free_cache_key
|
||||
#define VAL_DTOR_FN free_cache_value
|
||||
|
|
|
|||
11
kitty/dnd.c
11
kitty/dnd.c
|
|
@ -308,11 +308,12 @@ drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz
|
|||
}
|
||||
}
|
||||
if (payload_sz) {
|
||||
w->drop.accepted_mimes = realloc(w->drop.accepted_mimes, w->drop.accepted_mimes_sz + payload_sz + 2);
|
||||
if (w->drop.accepted_mimes) {
|
||||
memcpy(w->drop.accepted_mimes + w->drop.accepted_mimes_sz, payload, payload_sz);
|
||||
w->drop.accepted_mimes_sz += payload_sz;
|
||||
}
|
||||
if (w->drop.accepted_mimes_sz + payload_sz > 1024 * 1024) return;
|
||||
char *new_buf = realloc(w->drop.accepted_mimes, w->drop.accepted_mimes_sz + payload_sz + 2);
|
||||
if (!new_buf) return;
|
||||
w->drop.accepted_mimes = new_buf;
|
||||
memcpy(w->drop.accepted_mimes + w->drop.accepted_mimes_sz, payload, payload_sz);
|
||||
w->drop.accepted_mimes_sz += payload_sz;
|
||||
}
|
||||
if (!more) {
|
||||
w->drop.accept_in_progress = false;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import errno
|
||||
import hmac
|
||||
import inspect
|
||||
import io
|
||||
import json
|
||||
|
|
@ -572,12 +573,12 @@ def check_bypass(password: str, request_id: str, bypass_data: str) -> bool:
|
|||
delta = time_ns() - int(timestamp)
|
||||
if abs(delta) > 5 * 60 * 1e9:
|
||||
return False
|
||||
return payload == f'{request_id};{password}'
|
||||
return hmac.compare_digest(payload, f'{request_id};{password}')
|
||||
except Exception as err:
|
||||
log_error(f'Invalid file transmission bypass data received: {err}')
|
||||
return False
|
||||
elif protocol == 'sha256':
|
||||
return (encode_bypass(request_id, password) == bypass_data) if password else False
|
||||
return hmac.compare_digest(encode_bypass(request_id, password), bypass_data) if password else False
|
||||
else:
|
||||
log_error(f'Invalid file transmission bypass data received with protocol: {protocol}')
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ inflate_png_inner(png_read_data *d, const uint8_t *buf, size_t bufsz, int max_im
|
|||
png_read_update_info(png, info);
|
||||
|
||||
png_uint_32 rowbytes = png_get_rowbytes(png, info);
|
||||
d->sz = sizeof(png_byte) * rowbytes * d->height;
|
||||
d->sz = (size_t)rowbytes * (size_t)d->height;
|
||||
d->decompressed = malloc(d->sz + 16);
|
||||
if (d->decompressed == NULL) ABRT(ENOMEM, "Out of memory allocating decompression buffer for PNG");
|
||||
d->row_pointers = malloc(d->height * sizeof(png_bytep));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import base64
|
||||
import hmac
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
|
@ -103,6 +104,14 @@ def fnmatch_pattern(pat: str) -> 're.Pattern[str]':
|
|||
return re.compile(translate(pat))
|
||||
|
||||
|
||||
def _ct_password_lookup(passwords: dict[str, Any], pw: str) -> Any:
|
||||
result = None
|
||||
for k, v in passwords.items():
|
||||
if hmac.compare_digest(k, pw):
|
||||
result = v
|
||||
return result
|
||||
|
||||
|
||||
def remote_control_allowed(
|
||||
pcmd: dict[str, Any], remote_control_passwords: dict[str, Sequence[str]] | None,
|
||||
window: Optional['Window'], extra_data: dict[str, Any]
|
||||
|
|
@ -110,7 +119,7 @@ def remote_control_allowed(
|
|||
if not remote_control_passwords:
|
||||
return True
|
||||
pw = pcmd.get('password', '')
|
||||
auth_items = remote_control_passwords.get(pw)
|
||||
auth_items = _ct_password_lookup(remote_control_passwords, pw)
|
||||
if pw == '!':
|
||||
auth_items = None
|
||||
if auth_items is None:
|
||||
|
|
@ -185,10 +194,10 @@ def is_cmd_allowed(pcmd: dict[str, Any], window: Optional['Window'], from_socket
|
|||
return False
|
||||
pa = password_authorizer(auth_items)
|
||||
return pa.is_cmd_allowed(pcmd, window, from_socket, extra_data)
|
||||
q = user_password_allowed.get(pw)
|
||||
q = _ct_password_lookup(user_password_allowed, pw)
|
||||
if q is not None:
|
||||
return q
|
||||
auth_items = get_options().remote_control_password.get(pw)
|
||||
auth_items = _ct_password_lookup(get_options().remote_control_password, pw)
|
||||
if auth_items is None:
|
||||
return None
|
||||
pa = password_authorizer(auth_items)
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ func ExtractAllFromTar(tr *tar.Reader, dest_path string, optss ...TarExtractOpti
|
|||
dest_path = filepath.Clean(dest_path)
|
||||
|
||||
mode := func(hdr int64) fs.FileMode {
|
||||
return fs.FileMode(hdr) & (fs.ModePerm | fs.ModeSetgid | fs.ModeSetuid | fs.ModeSticky)
|
||||
return fs.FileMode(hdr) & fs.ModePerm
|
||||
}
|
||||
|
||||
set_metadata := func(chmod func(mode fs.FileMode) error, hdr_mode int64) (err error) {
|
||||
|
|
@ -250,6 +250,12 @@ func ExtractAllFromTar(tr *tar.Reader, dest_path string, optss ...TarExtractOpti
|
|||
if !filepath.IsAbs(link_target) {
|
||||
link_target = filepath.Join(filepath.Dir(dest), link_target)
|
||||
}
|
||||
if link_target, err = EvalSymlinksThatExist(link_target); err != nil {
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(link_target, needed_prefix) {
|
||||
continue
|
||||
}
|
||||
if err = os.Link(link_target, dest); err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue