All of lore.kernel.org
 help / color / mirror / Atom feed
From: Remi Pommarel <repk@triplefau.lt>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>,
	linux-kernel@vger.kernel.org
Cc: Alexander Viro <viro@zeniv.linux.org.uk>,
	Kees Cook <keescook@chromium.org>,
	Elie Roudninski <xademax@gmail.com>,
	Remi Pommarel <repk@triplefau.lt>
Subject: [PATCH 1/4] drivers/tty/vt/keyboard.c: refactor getting/setting a keymap entry
Date: Tue, 11 Sep 2018 22:23:56 +0200	[thread overview]
Message-ID: <3ee65938bc6bcab7c0dc6bf3dd55f7bff41406eb.1536695071.git.repk@triplefau.lt> (raw)
In-Reply-To: <cover.1536695070.git.repk@triplefau.lt>

In order to ease the addition of the ability of an input to use a
different key configuration (keycode to keysym map), the operations of
getting and setting an entry in a key map is moved in respective
functions.

Signed-off-by: Remi Pommarel <repk@triplefau.lt>
Tested-by: Elie Roudninski <xademax@gmail.com>
---
 drivers/tty/vt/keyboard.c | 201 ++++++++++++++++++++++----------------
 1 file changed, 118 insertions(+), 83 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 88312c6c92cc..89fabb8ae04e 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1874,115 +1874,150 @@ int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
 	return kc;
 }
 
-#define i (tmp.kb_index)
-#define s (tmp.kb_table)
-#define v (tmp.kb_value)
+#define i (kbe->kb_index)
+#define s (kbe->kb_table)
+#define v (kbe->kb_value)
 
-int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
-						int console)
+/*
+ * Get a keysym value from a key map
+ *
+ * @kb: Virtual console structure
+ * @kmaps: Key map array
+ * @kbe : Entry to find in key map
+ */
+static ushort __kdsk_getent(struct kbd_struct const *kb, ushort **kmaps,
+		struct kbentry const *kbe)
 {
-	struct kbd_struct *kb = kbd_table + console;
-	struct kbentry tmp;
-	ushort *key_map, *new_map, val, ov;
+	ushort *key_map, val;
 	unsigned long flags;
 
-	if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
-		return -EFAULT;
+	/* Ensure another thread doesn't free it under us */
+	spin_lock_irqsave(&kbd_event_lock, flags);
+	key_map = kmaps[s];
+	if (key_map) {
+		val = U(key_map[i]);
+		if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
+			val = K_HOLE;
+	} else
+		val = (i ? K_HOLE : K_NOSUCHMAP);
+	spin_unlock_irqrestore(&kbd_event_lock, flags);
 
-	if (!capable(CAP_SYS_TTY_CONFIG))
-		perm = 0;
+	return val;
+}
 
-	switch (cmd) {
-	case KDGKBENT:
-		/* Ensure another thread doesn't free it under us */
+/*
+ * Set a keysym value in a key map
+ *
+ * @kb: Virtual console structure
+ * @kmaps: Key map array
+ * @kbe : Entry to set in key map
+ */
+static int __kdsk_setent(struct kbd_struct const *kb, ushort **kmaps,
+		struct kbentry const *kbe)
+{
+	ushort *key_map, *new_map, ov;
+	unsigned long flags;
+
+	if (!i && v == K_NOSUCHMAP) {
 		spin_lock_irqsave(&kbd_event_lock, flags);
-		key_map = key_maps[s];
-		if (key_map) {
-		    val = U(key_map[i]);
-		    if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
-			val = K_HOLE;
-		} else
-		    val = (i ? K_HOLE : K_NOSUCHMAP);
-		spin_unlock_irqrestore(&kbd_event_lock, flags);
-		return put_user(val, &user_kbe->kb_value);
-	case KDSKBENT:
-		if (!perm)
-			return -EPERM;
-		if (!i && v == K_NOSUCHMAP) {
-			spin_lock_irqsave(&kbd_event_lock, flags);
-			/* deallocate map */
-			key_map = key_maps[s];
-			if (s && key_map) {
-			    key_maps[s] = NULL;
-			    if (key_map[0] == U(K_ALLOCATED)) {
-					kfree(key_map);
-					keymap_count--;
-			    }
+		/* deallocate map */
+		key_map = kmaps[s];
+		if (s && key_map) {
+			kmaps[s] = NULL;
+			if (key_map[0] == U(K_ALLOCATED)) {
+				kfree(key_map);
+				keymap_count--;
 			}
-			spin_unlock_irqrestore(&kbd_event_lock, flags);
-			break;
 		}
+		spin_unlock_irqrestore(&kbd_event_lock, flags);
+		return 0;
+	}
 
-		if (KTYP(v) < NR_TYPES) {
-		    if (KVAL(v) > max_vals[KTYP(v)])
-				return -EINVAL;
-		} else
-		    if (kb->kbdmode != VC_UNICODE)
-				return -EINVAL;
+	if (KTYP(v) < NR_TYPES) {
+		if (KVAL(v) > max_vals[KTYP(v)])
+			return -EINVAL;
+	} else if (kb->kbdmode != VC_UNICODE)
+		return -EINVAL;
 
-		/* ++Geert: non-PC keyboards may generate keycode zero */
+	/* ++Geert: non-PC keyboards may generate keycode zero */
 #if !defined(__mc68000__) && !defined(__powerpc__)
-		/* assignment to entry 0 only tests validity of args */
-		if (!i)
-			break;
+	/* assignment to entry 0 only tests validity of args */
+	if (!i)
+		return 0;
 #endif
 
-		new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
-		if (!new_map)
-			return -ENOMEM;
-		spin_lock_irqsave(&kbd_event_lock, flags);
-		key_map = key_maps[s];
-		if (key_map == NULL) {
-			int j;
-
-			if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
-			    !capable(CAP_SYS_RESOURCE)) {
-				spin_unlock_irqrestore(&kbd_event_lock, flags);
-				kfree(new_map);
-				return -EPERM;
-			}
-			key_maps[s] = new_map;
-			key_map = new_map;
-			key_map[0] = U(K_ALLOCATED);
-			for (j = 1; j < NR_KEYS; j++)
-				key_map[j] = U(K_HOLE);
-			keymap_count++;
-		} else
-			kfree(new_map);
+	new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+	spin_lock_irqsave(&kbd_event_lock, flags);
+	key_map = kmaps[s];
+	if (key_map == NULL) {
+		int j;
 
-		ov = U(key_map[i]);
-		if (v == ov)
-			goto out;
-		/*
-		 * Attention Key.
-		 */
-		if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
+		if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
+				!capable(CAP_SYS_RESOURCE)) {
 			spin_unlock_irqrestore(&kbd_event_lock, flags);
+			kfree(new_map);
 			return -EPERM;
 		}
-		key_map[i] = U(v);
-		if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
-			do_compute_shiftstate();
-out:
+		kmaps[s] = new_map;
+		key_map = new_map;
+		key_map[0] = U(K_ALLOCATED);
+		for (j = 1; j < NR_KEYS; j++)
+			key_map[j] = U(K_HOLE);
+		keymap_count++;
+	} else
+		kfree(new_map);
+
+	ov = U(key_map[i]);
+	if (v == ov)
+		goto out;
+	/*
+	 * Attention Key.
+	 */
+	if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
 		spin_unlock_irqrestore(&kbd_event_lock, flags);
-		break;
+		return -EPERM;
 	}
+	key_map[i] = U(v);
+	if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
+		do_compute_shiftstate();
+out:
+	spin_unlock_irqrestore(&kbd_event_lock, flags);
 	return 0;
 }
 #undef i
 #undef s
 #undef v
 
+int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
+						int console)
+{
+	struct kbd_struct *kb = kbd_table + console;
+	struct kbentry tmp;
+	ushort val;
+	int ret = 0;
+
+	if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
+		return -EFAULT;
+
+	if (!capable(CAP_SYS_TTY_CONFIG))
+		perm = 0;
+
+	switch (cmd) {
+	case KDGKBENT:
+		val = __kdsk_getent(kb, key_maps, &tmp);
+		ret = put_user(val, &user_kbe->kb_value);
+		break;
+	case KDSKBENT:
+		if (!perm)
+			return -EPERM;
+		ret = __kdsk_setent(kb, key_maps, &tmp);
+		break;
+	}
+	return ret;
+}
+
 /* FIXME: This one needs untangling and locking */
 int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
 {
-- 
2.18.0


  reply	other threads:[~2018-09-11 20:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-11 20:23 [PATCH 0/4] Add specific vt input's key map Remi Pommarel
2018-09-11 20:23 ` Remi Pommarel [this message]
2018-09-11 20:23 ` [PATCH 2/4] drivers/tty/vt/keyboard.c: add keyboard config for each vt's input Remi Pommarel
2018-09-11 20:23 ` [PATCH 3/4] drivers/tty/vt/keyboard.c: Make key_down[] bitmap input dependent Remi Pommarel
2018-09-11 20:23 ` [PATCH 4/4] drivers/tty/vt: add ioctl to manage input specific keyboard configs Remi Pommarel
2018-09-12 14:35 ` [PATCH 0/4] Add specific vt input's key map Alan Cox
2018-09-12 17:03   ` Remi Pommarel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3ee65938bc6bcab7c0dc6bf3dd55f7bff41406eb.1536695071.git.repk@triplefau.lt \
    --to=repk@triplefau.lt \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=xademax@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.