thunderbolt: Allow clearing the key
authorBernat, Yehezkel <yehezkel.bernat@intel.com>
Tue, 15 Aug 2017 05:19:20 +0000 (08:19 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 28 Aug 2017 14:21:32 +0000 (16:21 +0200)
If secure authentication of a devices fails, either because the device
already has another key uploaded, or there is some other error sending
challenge to the device, and the user only wants to approve the device
just once (without a new key being uploaded to the device) the current
implementation does not allow this because the key cannot be cleared
once set even if we allow it to be changed.

Make this scenario possible and allow clearing the key by writing
empty string to the key sysfs file.

Signed-off-by: Yehezkel Bernat <yehezkel.bernat@intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/sysfs-bus-thunderbolt
drivers/thunderbolt/switch.c

index 2a98149943ea542868cab5423e28166d4db48a5e..392bef5bd3996f71e5d73f934e701f9396afbf71 100644 (file)
@@ -45,6 +45,8 @@ Contact:      thunderbolt-software@lists.01.org
 Description:   When a devices supports Thunderbolt secure connect it will
                have this attribute. Writing 32 byte hex string changes
                authorization to use the secure connection method instead.
+               Writing an empty string clears the key and regular connection
+               method can be used again.
 
 What:          /sys/bus/thunderbolt/devices/.../device
 Date:          Sep 2017
index 8510abcee5d22241fe648f21fafbd57a116cadb5..53f40c57df59ccaefe0f69ab0d02977b3406e518 100644 (file)
@@ -807,8 +807,11 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr,
        struct tb_switch *sw = tb_to_switch(dev);
        u8 key[TB_SWITCH_KEY_SIZE];
        ssize_t ret = count;
+       bool clear = false;
 
-       if (hex2bin(key, buf, sizeof(key)))
+       if (!strcmp(buf, "\n"))
+               clear = true;
+       else if (hex2bin(key, buf, sizeof(key)))
                return -EINVAL;
 
        if (mutex_lock_interruptible(&switch_lock))
@@ -818,9 +821,13 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr,
                ret = -EBUSY;
        } else {
                kfree(sw->key);
-               sw->key = kmemdup(key, sizeof(key), GFP_KERNEL);
-               if (!sw->key)
-                       ret = -ENOMEM;
+               if (clear) {
+                       sw->key = NULL;
+               } else {
+                       sw->key = kmemdup(key, sizeof(key), GFP_KERNEL);
+                       if (!sw->key)
+                               ret = -ENOMEM;
+               }
        }
 
        mutex_unlock(&switch_lock);