qrexec_daemon: add explicite sanitize routine

It sanitizes messages from agent, the only untrusted input. No new
checks have been added, just moved the code.
This commit is contained in:
Rafal Wojtczuk 2011-05-04 10:53:43 +02:00
parent 94c4ca27dd
commit 675d4ce25b

View File

@ -335,11 +335,62 @@ void handle_trigger_exec(int req)
exit(1);
}
void check_clid_in_range(unsigned int untrusted_clid)
{
if (untrusted_clid >= MAX_FDS || untrusted_clid < 0) {
fprintf(stderr, "from agent: clid=%d\n", untrusted_clid);
exit(1);
}
}
void sanitize_message_from_agent(struct server_header *untrusted_header)
{
int untrusted_cmd;
switch (untrusted_header->type) {
case MSG_AGENT_TO_SERVER_TRIGGER_EXEC:
untrusted_cmd = untrusted_header->clid;
if (untrusted_cmd != QREXEC_EXECUTE_FILE_COPY &&
untrusted_cmd != QREXEC_EXECUTE_FILE_COPY_FOR_DISPVM) {
fprintf(stderr,
"received MSG_AGENT_TO_SERVER_TRIGGER_EXEC cmd %d ?\n",
untrusted_cmd);
exit(1);
}
break;
case MSG_AGENT_TO_SERVER_STDOUT:
case MSG_SERVER_TO_CLIENT_STDERR:
case MSG_AGENT_TO_SERVER_EXIT_CODE:
check_clid_in_range(untrusted_header->clid);
if (untrusted_header->len > MAX_DATA_CHUNK
|| untrusted_header->len < 0) {
fprintf(stderr, "agent feeded %d of data bytes?\n",
untrusted_header->len);
exit(1);
}
break;
case MSG_XOFF:
case MSG_XON:
check_clid_in_range(untrusted_header->clid);
break;
default:
fprintf(stderr, "unknown mesage type %d from agent\n",
untrusted_header->type);
exit(1);
}
}
void handle_agent_data()
{
struct client_header hdr;
struct server_header s_hdr;
read_all_vchan_ext(&s_hdr, sizeof s_hdr);
struct server_header s_hdr, untrusted_s_hdr;
read_all_vchan_ext(&untrusted_s_hdr, sizeof untrusted_s_hdr);
/* sanitize start */
sanitize_message_from_agent(&untrusted_s_hdr);
s_hdr = untrusted_s_hdr;
/* sanitize end */
// fprintf(stderr, "got %x %x %x\n", s_hdr.type, s_hdr.clid,
// s_hdr.len);
@ -349,11 +400,6 @@ void handle_agent_data()
return;
}
if (s_hdr.clid >= MAX_FDS || s_hdr.clid < 0) {
fprintf(stderr, "from agent: clid=%d\n", s_hdr.clid);
exit(1);
}
if (s_hdr.type == MSG_XOFF) {
clients[s_hdr.clid].state |= CLIENT_DONT_READ;
return;
@ -373,16 +419,11 @@ void handle_agent_data()
case MSG_AGENT_TO_SERVER_EXIT_CODE:
hdr.type = MSG_SERVER_TO_CLIENT_EXIT_CODE;
break;
default:
default: /* cannot happen */
fprintf(stderr, "from agent: type=%d\n", s_hdr.type);
exit(1);
}
hdr.len = s_hdr.len;
if (hdr.len > MAX_DATA_CHUNK) {
fprintf(stderr, "agent feeded %d of data bytes?\n",
hdr.len);
exit(1);
}
if (clients[s_hdr.clid].state == CLIENT_INVALID) {
// benefit of doubt - maybe client exited earlier
char buf[MAX_DATA_CHUNK];