Skip to content

Commit

Permalink
Make maximum clipboard buffer lenght configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
alimirjamali committed Oct 7, 2024
1 parent 9966538 commit 3b1dedd
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 8 deletions.
5 changes: 5 additions & 0 deletions gui-daemon/guid.conf
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,9 @@ global: {
# Timeout when waiting for qubes-gui-agent
#
# startup_timeout = 45;

# Inter-qube clipboard maximum character limit. This could be between
# 256 to 256000 characters. Default is 64000 characters.
#
# max_clipboard_size = 64000
}
Binary file added gui-daemon/qubes-guid
Binary file not shown.
41 changes: 33 additions & 8 deletions gui-daemon/xside.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
/* Supported protocol version */

#define PROTOCOL_VERSION_MAJOR UINT32_C(1)
#define PROTOCOL_VERSION_MINOR UINT32_C(7)
#define PROTOCOL_VERSION_MINOR UINT32_C(8)
#define PROTOCOL_VERSION(x, y) ((x) << 16 | (y))

#if !(PROTOCOL_VERSION_MAJOR == QUBES_GUID_PROTOCOL_VERSION_MAJOR && \
Expand Down Expand Up @@ -939,8 +939,8 @@ static int run_clipboard_rpc(Ghandles * g, enum clipboard_op op) {
}
umask(old_umask);
if (op == CLIPBOARD_COPY) {
rl.rlim_cur = MAX_CLIPBOARD_SIZE;
rl.rlim_max = MAX_CLIPBOARD_SIZE;
rl.rlim_cur = g->clipboard_buffer_size;
rl.rlim_max = g->clipboard_buffer_size;
setrlimit(RLIMIT_FSIZE, &rl);
}
dup2(fd, 1);
Expand Down Expand Up @@ -1013,16 +1013,17 @@ static void handle_clipboard_data(Ghandles * g, unsigned int untrusted_len)
FILE *file;
char *untrusted_data;
size_t untrusted_data_sz;
bool clipboard_buffer_exceeded = false;
Time clipboard_file_xevent_time;
mode_t old_umask;

if (g->log_level > 0)
fprintf(stderr, "handle_clipboard_data, len=0x%x\n",
untrusted_len);
if (untrusted_len > MAX_CLIPBOARD_SIZE) {
fprintf(stderr, "clipboard data len 0x%x?\n",
if (untrusted_len > g->clipboard_buffer_size) {
clipboard_buffer_exceeded = true;
fprintf(stderr, "clipboard data len 0x%x exceeds maximum allowed!\n",
untrusted_len);
exit(1);
}
/* now sanitized */
untrusted_data_sz = untrusted_len;
Expand Down Expand Up @@ -1057,7 +1058,8 @@ static void handle_clipboard_data(Ghandles * g, unsigned int untrusted_len)
show_error_message(g, "secure copy: failed to open file " QUBES_CLIPBOARD_FILENAME);
goto error;
}
if (fwrite(untrusted_data, 1, untrusted_data_sz, file) != untrusted_data_sz) {
if (! clipboard_buffer_exceeded) // do not write anything to output if size exceeds limit
if (fwrite(untrusted_data, 1, untrusted_data_sz, file) != untrusted_data_sz) {
fclose(file);
show_error_message(g, "secure copy: failed to write to file " QUBES_CLIPBOARD_FILENAME);
goto error;
Expand Down Expand Up @@ -3778,6 +3780,7 @@ struct option longopts[] = {
{ "trayicon-mode", required_argument, NULL, opt_trayicon_mode },
{ "screensaver-name", required_argument, NULL, opt_screensaver_name },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' }, // V is virtual and not a short option
{ 0, 0, 0, 0 },
};
static const char optstring[] = "+C:d:t:N:c:l:i:K:vqQnafIp:Th";
Expand Down Expand Up @@ -3807,6 +3810,8 @@ static void usage(FILE *stream)
fprintf(stream, " --title-name, -T\tprefix window titles with VM name\n");
fprintf(stream, " --trayicon-mode\ttrayicon coloring mode (see below); default: tint\n");
fprintf(stream, " --screensaver-name\tscreensaver window name, can be repeated, default: xscreensaver\n");
fprintf(stream, " --help, -h\tshow command help\n");
fprintf(stream, " --version\tshow program version\n");
fprintf(stream, " --override-redirect=disabled\tdisable the “override redirect” flag (will likely break applications)\n");
fprintf(stream, "\n");
fprintf(stream, "Log levels:\n");
Expand Down Expand Up @@ -3842,6 +3847,11 @@ static void parse_cmdline_config_path(Ghandles * g, int argc, char **argv)
} else if (opt == 'h') {
usage(stdout);
exit(0);
} else if (opt == 'V') {
fprintf(stdout, "Qubes GUI Daemon v%d.%d\n",
PROTOCOL_VERSION_MAJOR,
PROTOCOL_VERSION_MINOR);
exit(0);
}
}
}
Expand Down Expand Up @@ -4119,6 +4129,7 @@ static void load_default_config_values(Ghandles * g)
g->copy_seq_key = XK_c;
g->paste_seq_mask = ControlMask | ShiftMask;
g->paste_seq_key = XK_v;
g->clipboard_buffer_size = DEFAULT_CLIPBOARD_BUFFER_SIZE;
g->allow_fullscreen = 0;
g->override_redirect_protection = 1;
g->startup_timeout = 45;
Expand Down Expand Up @@ -4190,6 +4201,20 @@ static void parse_vm_config(Ghandles * g, config_setting_t * group)
&g->paste_seq_mask, &g->paste_seq_key);
}

if ((setting =
config_setting_get_member(group, "max_clipboard_size"))) {
int value = config_setting_get_int(setting);
if (value > MAX_CLIPBOARD_BUFFER_SIZE || value < MIN_CLIPBOARD_BUFFER_SIZE) {
fprintf(stderr,
"unsupported value ‘%d’ for max_clipboard_size "
"(must be between %d to %d characters.\n",
value, MAX_CLIPBOARD_BUFFER_SIZE, MIN_CLIPBOARD_BUFFER_SIZE);
exit(1);
} else {
g->clipboard_buffer_size = value;
}
}

if ((setting =
config_setting_get_member(group, "allow_utf8_titles"))) {
g->allow_utf8_titles = config_setting_get_bool(setting);
Expand Down Expand Up @@ -4237,7 +4262,7 @@ static void parse_vm_config(Ghandles * g, config_setting_t * group)
g->disable_override_redirect = 0;
else {
fprintf(stderr,
"unsupported value ‘%s’ for override_redirect (must be ‘disabled’ or ‘allow’\n",
"unsupported value ‘%s’ for override_redirect (must be ‘disabled’ or ‘allow’)\n",
value);
exit(1);
}
Expand Down
6 changes: 6 additions & 0 deletions gui-daemon/xside.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@
#include <qubes-gui-protocol.h>
#include "util.h"

/* default, minimum and maximum clipboard buffer lenght */
#define DEFAULT_CLIPBOARD_BUFFER_SIZE 64000 // make this 1000 bytes so it works with older vmside agent
#define MIN_CLIPBOARD_BUFFER_SIZE 256
#define MAX_CLIPBOARD_BUFFER_SIZE MAX_CLIPBOARD_SIZE

#define QUBES_POLICY_EVAL_SIMPLE_SOCKET ("/etc/qubes-rpc/" QUBES_SERVICE_EVAL_SIMPLE)
#define QREXEC_PRELUDE_CLIPBOARD_PASTE (QUBES_SERVICE_EVAL_SIMPLE "+" QUBES_SERVICE_CLIPBOARD_PASTE " dom0 keyword adminvm")

Expand Down Expand Up @@ -218,6 +223,7 @@ struct _global_handles {
KeySym copy_seq_key; /* key for secure-copy key sequence */
int paste_seq_mask; /* modifiers mask for secure-paste key sequence */
KeySym paste_seq_key; /* key for secure-paste key sequence */
unsigned int clipboard_buffer_size; /* maximum clipboard character limit */
int qrexec_clipboard; /* 0: use GUI protocol to fetch/put clipboard, 1: use qrexec */
int use_kdialog; /* use kdialog for prompts (default on KDE) or zenity (default on non-KDE) */
int prefix_titles; /* prefix windows titles with VM name (for WM without support for _QUBES_VMNAME property) */
Expand Down

0 comments on commit 3b1dedd

Please sign in to comment.