server/client: harden reading of initialization data, and make async

* Client terminal initialization data is now received
  asynchronously. To facilitate this, a couple of minor changes to the
  protocol was made:
    - The client now starts with sending a 4-byte unsigned integer
      with the *total* size of the initialization data (*not*
      including the size field itself.
    - Strings (TERM variable + argv) are now sent NULL-terminated

* The server allocates a single buffer, and fills it
  asynchronously. When full (as indicated by the initial 'total size'
  integer), we parse it (taking care not to read outside boundaries
  etc, and verifies the lengths (of the TERM variable and argv array)
  indicated by the client matches the actual lengths of the strings
  received.

* The server now ignores 'unexpected' data received from the client,
  after the terminal has been instantiated.
This commit is contained in:
Daniel Eklöf 2019-11-05 10:08:30 +01:00
parent 5b3fe4492c
commit 9abc5ca971
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 122 additions and 44 deletions

View file

@ -107,7 +107,26 @@ main(int argc, char *const *argv)
}
}
uint16_t term_len = strlen(term);
const uint16_t term_len = strlen(term) + 1;
uint32_t total_len = 0;
/* Calculate total length */
total_len += sizeof(term_len) + term_len;
total_len += sizeof(argc);
for (int i = 0; i < argc; i++) {
uint16_t len = strlen(argv[i]) + 1;
total_len += sizeof(len) + len;
}
LOG_DBG("term-len: %hu, argc: %d, total-len: %u",
term_len, argc, total_len);
if (send(fd, &total_len, sizeof(total_len), 0) != sizeof(total_len)) {
LOG_ERRNO("failed to send total length to server");
goto err;
}
if (send(fd, &term_len, sizeof(term_len), 0) != sizeof(term_len) ||
send(fd, term, term_len, 0) != term_len)
{
@ -122,7 +141,7 @@ main(int argc, char *const *argv)
}
for (int i = 0; i < argc; i++) {
uint16_t len = strlen(argv[i]);
uint16_t len = strlen(argv[i]) + 1;
LOG_DBG("argv[%d] = %s (%hu)", i, argv[i], len);