s390/hvc_iucv: add simple wildcard matches to the iucv allow filter
[firefly-linux-kernel-4.4.55.git] / drivers / tty / hvc / hvc_iucv.c
index ea74460f363862507cbf85af2b2873ae8208ae72..f78a87b07872ffad69234d680953e1236f8dad81 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * hvc_iucv.c - z/VM IUCV hypervisor console (HVC) device driver
+ * z/VM IUCV hypervisor console (HVC) device driver
  *
  * This HVC device driver provides terminal access using
  * z/VM IUCV communication paths.
  *
- * Copyright IBM Corp. 2008, 2009
+ * Copyright IBM Corp. 2008, 2013
  *
  * Author(s):  Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  */
@@ -102,6 +102,7 @@ static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
 #define IUCV_HVC_CON_IDX       (0)
 /* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
 #define MAX_VMID_FILTER                (500)
+#define FILTER_WILDCARD_CHAR   '*'
 static size_t hvc_iucv_filter_size;
 static void *hvc_iucv_filter;
 static const char *hvc_iucv_filter_string;
@@ -734,20 +735,31 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
  * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
  * @ipvmid:    Originating z/VM user ID (right padded with blanks)
  *
- * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
- * non-zero.
+ * Returns 0 if the z/VM user ID that is specified with @ipvmid is permitted to
+ * connect, otherwise non-zero.
  */
 static int hvc_iucv_filter_connreq(u8 ipvmid[8])
 {
-       size_t i;
+       const char *wildcard, *filter_entry;
+       size_t i, len;
 
        /* Note: default policy is ACCEPT if no filter is set */
        if (!hvc_iucv_filter_size)
                return 0;
 
-       for (i = 0; i < hvc_iucv_filter_size; i++)
-               if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+       for (i = 0; i < hvc_iucv_filter_size; i++) {
+               filter_entry = hvc_iucv_filter + (8 * i);
+
+               /* If a filter entry contains the filter wildcard character,
+                * reduce the length to match the leading portion of the user
+                * ID only (wildcard match).  Characters following the wildcard
+                * are ignored.
+                */
+               wildcard = strnchr(filter_entry, 8, FILTER_WILDCARD_CHAR);
+               len = (wildcard) ? wildcard - filter_entry : 8;
+               if (0 == memcmp(ipvmid, filter_entry, len))
                        return 0;
+       }
        return 1;
 }
 
@@ -1166,6 +1178,7 @@ static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv)
 /**
  * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
  * @filter:    String containing a comma-separated list of z/VM user IDs
+ * @dest:      Location where to store the parsed z/VM user ID
  */
 static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
 {
@@ -1188,6 +1201,10 @@ static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
        if (filter[len - 1] == '\n')
                len--;
 
+       /* prohibit filter entries containing the wildcard character only */
+       if (len == 1 && *filter == FILTER_WILDCARD_CHAR)
+               return ERR_PTR(-EINVAL);
+
        if (len > 8)
                return ERR_PTR(-EINVAL);