diff options
author | Ian Moffett <ian@osmora.org> | 2025-07-07 02:17:23 +0000 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-07-07 02:33:53 +0000 |
commit | 7f7535710b23ec984f1f0fa3dab8ea4a081a0bab (patch) | |
tree | 7236dfd38c406e5b9ad1e99ed3e6cb6c01895dff | |
parent | 4a004fd4eb1f6d7616e38b1ccb0ec0bf8346d204 (diff) |
kernel: cons: Introduce /ctl/console/attr
In a lot of existing systems, ANSI escape sequences are used to
control console attributes such as cursor position, style, etc. However,
too many sequences for too many things are implemented at once. If a
program has neglected to properly sanitize input coming in (e.g., from a
network). Stray sequences may be injected into the receiving console.
One may disable the ANSI state machine using the 'ansi_esc' bit within
/ctl/console/feat, completely eradicating such issues, while being able
to still control various console attributes through /ctl/console/attr.
This commit also keeps the builtin ANSI escape sequence parser as simple
as possible.
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r-- | sys/dev/cons/cons.c | 66 | ||||
-rw-r--r-- | sys/include/dev/cons/cons.h | 1 | ||||
-rw-r--r-- | sys/include/sys/console.h | 11 |
3 files changed, 77 insertions, 1 deletions
diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index 9921ff8..5a59e3d 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -64,6 +64,7 @@ struct cons_screen g_root_scr = {0}; static struct cdevsw cons_cdevsw; static struct ctlops cons_feat_ctl; +static struct ctlops cons_attr_ctl; static void cons_draw_cursor(struct cons_screen *scr, uint32_t color); static int cons_handle_special(struct cons_screen *scr, char c); @@ -469,6 +470,57 @@ ctl_feat_write(struct ctlfs_dev *cdp, struct sio_txn *sio) return sio->len; } +static int +ctl_attr_read(struct ctlfs_dev *cdp, struct sio_txn *sio) +{ + struct cons_screen *scr = &g_root_scr; + struct console_attr *attrp; + + if (sio->buf == NULL || sio->len == 0) { + return -EINVAL; + } + + attrp = &scr->attr; + if (sio->len > sizeof(*attrp)) { + sio->len = sizeof(*attrp); + } + + memcpy(sio->buf, attrp, sio->len); + return sio->len; +} + +static int +ctl_attr_write(struct ctlfs_dev *cdp, struct sio_txn *sio) +{ + struct cons_screen *scr = &g_root_scr; + struct console_attr *attrp; + + attrp = &scr->attr; + if (sio->len > sizeof(*attrp)) { + sio->len = sizeof(*attrp); + } + + memcpy(attrp, sio->buf, sio->len); + spinlock_acquire(&scr->lock); + + /* Clip the x/y positions */ + if (attrp->cursor_x >= scr->ncols) + attrp->cursor_x = scr->ncols - 1; + if (attrp->cursor_y >= scr->nrows) + attrp->cursor_y = scr->nrows - 1; + + /* Update cursor */ + HIDE_CURSOR(scr); + scr->curs_col = attrp->cursor_x; + scr->curs_row = attrp->cursor_y; + scr->ch_col = attrp->cursor_x; + scr->ch_row = attrp->cursor_y; + SHOW_CURSOR(scr); + + spinlock_release(&scr->lock); + return sio->len; +} + /* * Detach the currently running process from the * console. @@ -654,12 +706,19 @@ cons_expose(void) dev_register(major, dev, &cons_cdevsw); devfs_create_entry(devname, major, dev, 0444); - /* Register the control file */ + /* Register feat ctl */ ctl.mode = 0666; ctlfs_create_node(devname, &ctl); ctl.devname = devname; ctl.ops = &cons_feat_ctl; ctlfs_create_entry("feat", &ctl); + + /* Register attr ctl */ + ctl.mode = 0666; + ctlfs_create_node(devname, &ctl); + ctl.devname = devname; + ctl.ops = &cons_attr_ctl; + ctlfs_create_entry("attr", &ctl); once ^= 1; } @@ -672,3 +731,8 @@ static struct ctlops cons_feat_ctl = { .read = ctl_feat_read, .write = ctl_feat_write }; + +static struct ctlops cons_attr_ctl = { + .read = ctl_attr_read, + .write = ctl_attr_write +}; diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h index c82c3c5..bc868b4 100644 --- a/sys/include/dev/cons/cons.h +++ b/sys/include/dev/cons/cons.h @@ -51,6 +51,7 @@ struct cons_screen { struct fbdev fbdev; struct ansi_state ansi_s; struct console_feat feat; /* Features */ + struct console_attr attr; /* Attributes */ struct proc *atproc; /* Attached proc */ struct mutex *atproc_lock; uint32_t fg; diff --git a/sys/include/sys/console.h b/sys/include/sys/console.h index c912d28..d0b89a8 100644 --- a/sys/include/sys/console.h +++ b/sys/include/sys/console.h @@ -43,4 +43,15 @@ struct console_feat { uint8_t show_curs : 1; }; +/* + * Console attributes + * + * @cursor_x: Cursor x position + * @cursor_y: Cursor y position + */ +struct console_attr { + uint32_t cursor_x; + uint32_t cursor_y; +}; + #endif /* !_SYS_CONSOLE_H_ */ |