Merge branch 'configurable-ring-size'

* configurable-ring-size:
  qrexec: add qrexec-client-vm --buffer-size option
This commit is contained in:
Marek Marczykowski-Górecki 2018-03-20 01:15:29 +01:00
commit f8c40aa0f7
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
4 changed files with 61 additions and 21 deletions

View File

@ -8,7 +8,7 @@ qrexec-client-vm - call Qubes RPC service
SYNOPSIS
========
| qrexec-client-vm *target_vmname* *service* [*local_program* [*local program arguments*]]
| qrexec-client-vm [--buffer-size=*BUFFER_SIZE*] *target_vmname* *service* [*local_program* [*local program arguments*]]
DESCRIPTION
===========
@ -27,6 +27,12 @@ stdin/stdout is connected to those of ``qrexec-client-vm``.
OPTIONS
=======
--buffer-size=*BUFFER_SIZE*
Optional buffer size for vchan connection. This size is used as minimum
size for a buffer in each connection direction (read and write).
Default: 64KiB.
*target_vmname*
Name of target VM to which service is requested. Qubes RPC policy may

View File

@ -490,10 +490,14 @@ int process_child_io(libvchan_t *data_vchan,
* MSG_EXEC_CMDLINE - connect to vchan server, fork+exec process given by
* cmdline parameter, pass the data to/from that process, then return local
* process exit code
*
* buffer_size is about vchan buffer allocated (only for vchan server cases),
* use 0 to use built-in default (64k); needs to be power of 2
*/
int handle_new_process_common(int type, int connect_domain, int connect_port,
char *cmdline, int cmdline_len, /* MSG_JUST_EXEC and MSG_EXEC_CMDLINE */
int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */)
int stdin_fd, int stdout_fd, int stderr_fd /* MSG_SERVICE_CONNECT */,
int buffer_size)
{
libvchan_t *data_vchan;
int exit_code = 0;
@ -504,9 +508,12 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
cmdline[cmdline_len-1] = 0;
}
if (buffer_size == 0)
buffer_size = VCHAN_BUFFER_SIZE;
if (type == MSG_SERVICE_CONNECT) {
data_vchan = libvchan_server_init(connect_domain, connect_port,
VCHAN_BUFFER_SIZE, VCHAN_BUFFER_SIZE);
buffer_size, buffer_size);
if (data_vchan)
libvchan_wait(data_vchan);
} else {
@ -563,7 +570,7 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
/* child process */
exit_code = handle_new_process_common(type, connect_domain, connect_port,
cmdline, cmdline_len,
-1, -1, -1);
-1, -1, -1, 0);
exit(exit_code);
/* suppress warning */
@ -572,13 +579,13 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
/* Returns exit code of remote process */
int handle_data_client(int type, int connect_domain, int connect_port,
int stdin_fd, int stdout_fd, int stderr_fd)
int stdin_fd, int stdout_fd, int stderr_fd, int buffer_size)
{
int exit_code;
assert(type == MSG_SERVICE_CONNECT);
exit_code = handle_new_process_common(type, connect_domain, connect_port,
NULL, 0, stdin_fd, stdout_fd, stderr_fd);
NULL, 0, stdin_fd, stdout_fd, stderr_fd, buffer_size);
return exit_code;
}

View File

@ -37,7 +37,8 @@ pid_t handle_new_process(int type,
char *cmdline, int cmdline_len);
int handle_data_client(int type,
int connect_domain, int connect_port,
int stdin_fd, int stdout_fd, int stderr_fd);
int stdin_fd, int stdout_fd, int stderr_fd,
int buffer_size);
struct qrexec_cmd_info {

View File

@ -27,6 +27,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <getopt.h>
#include "libqrexec-utils.h"
#include "qrexec.h"
#include "qrexec-agent.h"
@ -85,6 +86,19 @@ void convert_target_name_keyword(char *target)
target[i] = '@';
}
struct option longopts[] = {
{ "buffer-size", required_argument, 0, 'b' },
{ NULL, 0, 0, 0},
};
_Noreturn void usage(const char *argv0) {
fprintf(stderr,
"usage: %s [--buffer-size=BUFFER_SIZE] target_vmname program_ident [local_program [local program arguments]]\n",
argv0);
fprintf(stderr, "BUFFER_SIZE is minimum vchan buffer size (default: 64k)\n");
exit(2);
}
int main(int argc, char **argv)
{
int trigger_fd;
@ -95,24 +109,36 @@ int main(int argc, char **argv)
char *abs_exec_path;
pid_t child_pid = 0;
int inpipe[2], outpipe[2];
int buffer_size = 0;
int opt;
if (argc < 3) {
fprintf(stderr,
"usage: %s target_vmname program_ident [local_program [local program arguments]]\n",
argv[0]);
exit(1);
while (1) {
opt = getopt_long(argc, argv, "", longopts, NULL);
if (opt == -1)
break;
switch (opt) {
case 'b':
buffer_size = atoi(optarg);
break;
case '?':
usage(argv[0]);
}
}
if (argc > 3) {
if (argc - optind < 2) {
usage(argv[0]);
}
if (argc - optind > 2) {
start_local_process = 1;
}
trigger_fd = connect_unix_socket(QREXEC_AGENT_TRIGGER_PATH);
memset(&params, 0, sizeof(params));
strncpy(params.service_name, argv[2], sizeof(params.service_name));
strncpy(params.service_name, argv[optind + 1], sizeof(params.service_name));
convert_target_name_keyword(argv[1]);
strncpy(params.target_domain, argv[1],
convert_target_name_keyword(argv[optind]);
strncpy(params.target_domain, argv[optind],
sizeof(params.target_domain));
snprintf(params.request_id.ident,
@ -164,9 +190,9 @@ int main(int argc, char **argv)
close(inpipe[0]);
close(outpipe[1]);
abs_exec_path = strdup(argv[3]);
argv[3] = get_program_name(argv[3]);
execv(abs_exec_path, argv + 3);
abs_exec_path = strdup(argv[optind + 2]);
argv[optind + 2] = get_program_name(argv[optind + 2]);
execv(abs_exec_path, argv + optind + 2);
perror("execv");
exit(-1);
}
@ -175,11 +201,11 @@ int main(int argc, char **argv)
ret = handle_data_client(MSG_SERVICE_CONNECT,
exec_params.connect_domain, exec_params.connect_port,
inpipe[1], outpipe[0], -1);
inpipe[1], outpipe[0], -1, buffer_size);
} else {
ret = handle_data_client(MSG_SERVICE_CONNECT,
exec_params.connect_domain, exec_params.connect_port,
1, 0, -1);
1, 0, -1, buffer_size);
}
close(trigger_fd);