iucvterm/iucvtty: Validate TERM environment name

Improve handling of TERM environment processing by validating
the received terminal name.  If the terminal name is not valid,
a message will be displayed and the default terminal will be used.

Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Hendrik Brueckner
2026-07-06 11:30:56 +02:00
committed by Jan Höppner
parent da4b881eac
commit c85b4e54dd
4 changed files with 44 additions and 5 deletions

View File

@@ -62,6 +62,7 @@ extern ssize_t __write(int, const void*, size_t);
extern int strmatch(const char *, const char *);
extern int is_regex_valid(const char *);
extern int is_client_allowed(const char *, const struct iucvterm_cfg *);
extern int is_term_valid(const char *term, size_t len);
extern void userid_cpy(char [9], const char [8]);
extern void iucv_msg_error(const char *, uint32_t);

View File

@@ -86,7 +86,7 @@ static inline struct iucvtty_msg *msg_alloc(uint8_t type, uint16_t size)
{
struct iucvtty_msg *m;
m = malloc(size + MSG_DATA_OFFSET);
m = calloc(1, size + MSG_DATA_OFFSET);
if (m != NULL) {
m->version = MSG_VERSION;
m->type = type;

View File

@@ -8,6 +8,7 @@
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <stdio.h>
@@ -148,10 +149,12 @@ int iucvtty_rx_termenv(int fd, void *buf, size_t len)
rc = iucvtty_read_msg(fd, msg, msg_size(msg), &skip);
iucvtty_skip_msg_residual(fd, &skip);
if (!rc) {
if (msg->datalen == 0)
if (msg->datalen == 0) {
memset(buf, 0, MIN(1u, len));
else
} else {
msg_cpy_to(msg, buf, len);
memset(buf + MIN(msg->datalen, len - 1), 0, 1);
}
}
msg_free(msg);
return rc;
@@ -501,6 +504,31 @@ int is_client_allowed(const char *client, const struct iucvterm_cfg *cfg)
return strmatch(client, cfg->client_re);
}
/**
* is_term_valid() - Validate TERM environment value
* @term: Terminal environment name to validate
* @len: Maximum number of characters to validate
*/
int is_term_valid(const char *term, size_t len)
{
const char *c;
if (term == NULL || *term == '\0')
return 0;
for (c = term; *c != '\0'; c++) {
if ((size_t)(c - term) >= len)
return 0;
if (!isalnum((unsigned char)*c) &&
*c != '.' &&
*c != '_' &&
*c != '-')
return 0;
}
return 1;
}
/**
* userid_cpy() - Copy z/VM user ID and skip trailing spaces.
* @dest: Destination buffer

View File

@@ -69,6 +69,10 @@ static int exec_login_prog(char *cmd[])
* @master: PTY master file descriptor
* @slave: PTY slave file descriptor
* @cfg: IUCV TTY configuration structure.
*
* Unlike the HVC IUCV terminal device driver, iucvtty expects to
* receive the TERM environment first. This is necessary to correctly
* set up the login program.
*/
static int iucvtty_worker(int client, int master, int slave,
const struct iucvterm_cfg *cfg)
@@ -84,9 +88,15 @@ static int iucvtty_worker(int client, int master, int slave,
/* flush pending terminal data */
tcflush(master, TCIOFLUSH);
/* read terminal parameters from client */
/* read and validate terminal parameters from client */
memset(term_env, 0, sizeof(term_env));
if (iucvtty_rx_termenv(client, term_env, TERM_BUFSIZE))
sprintf(term_env, TERM_DEFAULT);
snprintf(term_env, sizeof(term_env), "%s", TERM_DEFAULT);
if (!is_term_valid(term_env, sizeof(term_env))) {
print_error("Ignoring received TERM env due to invalid character(s)");
snprintf(term_env, sizeof(term_env), "%s", TERM_DEFAULT);
}
/* start login program */
child = fork();