summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-07 02:17:23 +0000
committerIan Moffett <ian@osmora.org>2025-07-07 02:33:53 +0000
commit7f7535710b23ec984f1f0fa3dab8ea4a081a0bab (patch)
tree7236dfd38c406e5b9ad1e99ed3e6cb6c01895dff
parent4a004fd4eb1f6d7616e38b1ccb0ec0bf8346d204 (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.c66
-rw-r--r--sys/include/dev/cons/cons.h1
-rw-r--r--sys/include/sys/console.h11
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_ */