linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address
@ 2019-12-01 21:57 Mike Ryan
  2019-12-02  4:34 ` kbuild test robot
  0 siblings, 1 reply; 4+ messages in thread
From: Mike Ryan @ 2019-12-01 21:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: mike

In order to facilitate impersonation attacks against devices using
resolvable private addresses (RPAs), this debugfs entry allows the user
to set a fixed RPA that is used during undirected and directed
advertising. Writing 00:00:00:00:00:00 disables the forced address and
will resume generating valid RPAs.

Signed-off-by: Mike Ryan <mike@ice9.us>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_debugfs.c      | 54 ++++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_request.c      | 15 ++++++++---
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b689aceb6..a822914d7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -428,6 +428,7 @@ struct hci_dev {
 	__u32			rpa_timeout;
 	struct delayed_work	rpa_expired;
 	bdaddr_t		rpa;
+	bdaddr_t		force_rpa;
 
 #if IS_ENABLED(CONFIG_BT_LEDS)
 	struct led_trigger	*power_led;
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 402e2cc54..1efefe82c 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -710,6 +710,58 @@ static const struct file_operations force_static_address_fops = {
 	.llseek		= default_llseek,
 };
 
+static ssize_t force_rpa_read(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[19];
+	bdaddr_t *ba = &hdev->force_rpa;
+
+	sprintf(buf, "%pMR\n", ba);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t force_rpa_write(struct file *file, const char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[18];
+	size_t buf_size = min(count, (sizeof(buf)-1));
+	bdaddr_t rpa;
+
+	if (test_bit(HCI_UP, &hdev->flags))
+		return -EBUSY;
+
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	buf[buf_size] = '\0';
+	if (str2ba(buf, &rpa))
+		return -EINVAL;
+
+	/* The two most significant bits shall be 01 unless the address is
+	 * 00:00:00:00:00:00.
+         */
+	if ((rpa.b[5] & 0xc0) != 0x40 && bacmp(&rpa, BDADDR_ANY))
+		return -EINVAL;
+
+	if (!bacmp(&hdev->force_rpa, &rpa))
+		return -EALREADY;
+
+	bacpy(&hdev->force_rpa, &rpa);
+
+	return count;
+}
+
+static const struct file_operations force_rpa_fops = {
+	.open		= simple_open,
+	.read		= force_rpa_read,
+	.write		= force_rpa_write,
+	.llseek		= default_llseek,
+};
+
 static int white_list_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
@@ -1026,6 +1078,8 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
 				    hdev->debugfs, hdev,
 				    &force_static_address_fops);
 
+	debugfs_create_file("force_rpa", 0644, hdev->debugfs, hdev,
+			    &force_rpa_fops);
 	debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
 			  &hdev->le_white_list_size);
 	debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 2a1b64dbf..63f4d5c16 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1914,10 +1914,17 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
 		    !bacmp(&hdev->random_addr, &hdev->rpa))
 			return 0;
 
-		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
-		if (err < 0) {
-			bt_dev_err(hdev, "failed to generate new RPA");
-			return err;
+		/* If force_rpa is set to 00:00:00:00:00:00, generate a valid
+		 * RPA using IRK. Otherwise use the forced value.
+		 */
+		if (!bacmp(&hdev->force_rpa, BDADDR_ANY)) {
+			err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
+			if (err < 0) {
+				bt_dev_err(hdev, "failed to generate new RPA");
+				return err;
+			}
+		} else {
+			bacpy(&hdev->rpa, &hdev->force_rpa);
 		}
 
 		set_random_addr(req, &hdev->rpa);
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address
  2019-12-01 21:57 [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address Mike Ryan
@ 2019-12-02  4:34 ` kbuild test robot
  0 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2019-12-02  4:34 UTC (permalink / raw)
  To: Mike Ryan; +Cc: kbuild-all, linux-bluetooth, mike

[-- Attachment #1: Type: text/plain, Size: 2631 bytes --]

Hi Mike,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[cannot apply to bluetooth/master v5.4 v5.4-rc8 v5.4-rc7 next-20191129 v5.4 next-20191129]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Mike-Ryan/Bluetooth-Expose-debugfs-entry-to-force-resolvable-private-address/20191202-055959
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gcc (GCC) 7.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.4.0 make.cross ARCH=sparc64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   net/bluetooth/hci_debugfs.c: In function 'force_rpa_write':
>> net/bluetooth/hci_debugfs.c:741:6: error: implicit declaration of function 'str2ba'; did you mean 'strspn'? [-Werror=implicit-function-declaration]
     if (str2ba(buf, &rpa))
         ^~~~~~
         strspn
   cc1: some warnings being treated as errors

vim +741 net/bluetooth/hci_debugfs.c

   725	
   726	static ssize_t force_rpa_write(struct file *file, const char __user *user_buf,
   727				       size_t count, loff_t *ppos)
   728	{
   729		struct hci_dev *hdev = file->private_data;
   730		char buf[18];
   731		size_t buf_size = min(count, (sizeof(buf)-1));
   732		bdaddr_t rpa;
   733	
   734		if (test_bit(HCI_UP, &hdev->flags))
   735			return -EBUSY;
   736	
   737		if (copy_from_user(buf, user_buf, buf_size))
   738			return -EFAULT;
   739	
   740		buf[buf_size] = '\0';
 > 741		if (str2ba(buf, &rpa))
   742			return -EINVAL;
   743	
   744		/* The two most significant bits shall be 01 unless the address is
   745		 * 00:00:00:00:00:00.
   746	         */
   747		if ((rpa.b[5] & 0xc0) != 0x40 && bacmp(&rpa, BDADDR_ANY))
   748			return -EINVAL;
   749	
   750		if (!bacmp(&hdev->force_rpa, &rpa))
   751			return -EALREADY;
   752	
   753		bacpy(&hdev->force_rpa, &rpa);
   754	
   755		return count;
   756	}
   757	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 59416 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address
  2019-11-11  5:22 mike
@ 2019-11-19 17:01 ` Marcel Holtmann
  0 siblings, 0 replies; 4+ messages in thread
From: Marcel Holtmann @ 2019-11-19 17:01 UTC (permalink / raw)
  To: mike; +Cc: Bluez mailing list

Hi Mike,

> In order to facilitate impersonation attacks against devices using
> resolvable private addresses (RPAs), this debugfs entry allows the user
> to set a fixed RPA that is used during undirected and directed
> advertising. Writing 00:00:00:00:00:00 disables the forced address and
> will resume generating valid RPAs.
> 
> Signed-off-by: Mike Ryan <mike@ice9.us>
> ---
> include/net/bluetooth/bluetooth.h |  1 +
> include/net/bluetooth/hci_core.h  |  1 +
> net/bluetooth/hci_debugfs.c       | 53 +++++++++++++++++++++++++++++++++++++++
> net/bluetooth/hci_request.c       | 23 +++++++++++------
> net/bluetooth/lib.c               | 52 ++++++++++++++++++++++++++++++++++++++
> 5 files changed, 123 insertions(+), 7 deletions(-)
> 
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index fabee6db0..c6417d15c 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -237,6 +237,7 @@ static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
> }
> 
> void baswap(bdaddr_t *dst, const bdaddr_t *src);
> +int str2ba(const char *str, bdaddr_t *ba);
> 
> /* Common socket structures and functions */
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index b689aceb6..a822914d7 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -428,6 +428,7 @@ struct hci_dev {
> 	__u32			rpa_timeout;
> 	struct delayed_work	rpa_expired;
> 	bdaddr_t		rpa;
> +	bdaddr_t		force_rpa;
> 
> #if IS_ENABLED(CONFIG_BT_LEDS)
> 	struct led_trigger	*power_led;
> diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
> index 402e2cc54..2363ae9bb 100644
> --- a/net/bluetooth/hci_debugfs.c
> +++ b/net/bluetooth/hci_debugfs.c
> @@ -710,6 +710,57 @@ static const struct file_operations force_static_address_fops = {
> 	.llseek		= default_llseek,
> };
> 
> +static ssize_t force_rpa_read(struct file *file,
> +					 char __user *user_buf,
> +					 size_t count, loff_t *ppos)
> +{
> +	struct hci_dev *hdev = file->private_data;
> +	char buf[19];
> +	bdaddr_t *ba = &hdev->force_rpa;
> +
> +	sprintf(buf, "%pMR\n", ba);
> +
> +	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
> +}
> +
> +static ssize_t force_rpa_write(struct file *file, const char __user *user_buf,
> +			       size_t count, loff_t *ppos)
> +{
> +	struct hci_dev *hdev = file->private_data;
> +	char buf[18];
> +	size_t buf_size = min(count, (sizeof(buf)-1));
> +	bdaddr_t rpa;
> +
> +	if (test_bit(HCI_UP, &hdev->flags))
> +		return -EBUSY;
> +
> +	if (copy_from_user(buf, user_buf, buf_size))
> +		return -EFAULT;
> +
> +	buf[buf_size] = '\0';
> +	if (str2ba(buf, &rpa))
> +		return -EINVAL;
> +
> +	// the two most significant bits shall be 01 unless the address is
> +	// 00:00:00:00:00:00

comment style is 

	/* foo */

Or 

	/* foo
	 * bar */

> +	if ((rpa.b[5] & 0xc0) != 0x40 && bacmp(&rpa, BDADDR_ANY))
> +		return -EINVAL;
> +
> +	if (!bacmp(&hdev->force_rpa, &rpa))
> +		return -EALREADY;
> +
> +	bacpy(&hdev->force_rpa, &rpa);
> +
> +	return count;
> +}

Lets use scanf here instead of truing to copy str2ba from userspace.

> +
> +static const struct file_operations force_rpa_fops = {
> +	.open		= simple_open,
> +	.read		= force_rpa_read,
> +	.write		= force_rpa_write,
> +	.llseek		= default_llseek,
> +};
> +
> static int white_list_show(struct seq_file *f, void *ptr)
> {
> 	struct hci_dev *hdev = f->private;
> @@ -1026,6 +1077,8 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
> 				    hdev->debugfs, hdev,
> 				    &force_static_address_fops);
> 
> +	debugfs_create_file("force_rpa", 0644, hdev->debugfs, hdev,
> +			    &force_rpa_fops);
> 	debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
> 			  &hdev->le_white_list_size);
> 	debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
> diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
> index 2a1b64dbf..8fabb1bb1 100644
> --- a/net/bluetooth/hci_request.c
> +++ b/net/bluetooth/hci_request.c
> @@ -1910,14 +1910,23 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
> 
> 		*own_addr_type = ADDR_LE_DEV_RANDOM;
> 
> -		if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
> -		    !bacmp(&hdev->random_addr, &hdev->rpa))
> -			return 0;
> +		/* If force_rpa is set to 00:00:00:00:00:00, generate a valid
> +		 * RPA using IRK. Otherwise use the forced value.
> +		 */
> +		if (!bacmp(&hdev->force_rpa, BDADDR_ANY)) {
> +			if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
> +			    !bacmp(&hdev->random_addr, &hdev->rpa))
> +				return 0;
> 
> -		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
> -		if (err < 0) {
> -			bt_dev_err(hdev, "failed to generate new RPA");
> -			return err;
> +			err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
> +			if (err < 0) {
> +				bt_dev_err(hdev, "failed to generate new RPA");
> +				return err;
> +			}
> +		} else {
> +			if (!bacmp(&hdev->rpa, &hdev->force_rpa))
> +				return 0;
> +			bacpy(&hdev->rpa, &hdev->force_rpa);
> 		}

Isn’t this going to be enough (minus the required comment).

-               err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
-               if (err < 0) {
-                       bt_dev_err(hdev, "failed to generate new RPA");
-                       return err;
+               if (!bacmp(&hdev->force_rpa, BDADDR_ANY)) {
+                       err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
+                       if (err < 0) {
+                               bt_dev_err(hdev, "failed to generate new RPA");
+                               return err;
+                       }
+               } else {
+                       bacpy(&hdev->rpa, &hdev->force_rpa);
                }

Regards

Marcel


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address
@ 2019-11-11  5:22 mike
  2019-11-19 17:01 ` Marcel Holtmann
  0 siblings, 1 reply; 4+ messages in thread
From: mike @ 2019-11-11  5:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: mike

From: Mike Ryan <mike@ice9.us>

In order to facilitate impersonation attacks against devices using
resolvable private addresses (RPAs), this debugfs entry allows the user
to set a fixed RPA that is used during undirected and directed
advertising. Writing 00:00:00:00:00:00 disables the forced address and
will resume generating valid RPAs.

Signed-off-by: Mike Ryan <mike@ice9.us>
---
 include/net/bluetooth/bluetooth.h |  1 +
 include/net/bluetooth/hci_core.h  |  1 +
 net/bluetooth/hci_debugfs.c       | 53 +++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_request.c       | 23 +++++++++++------
 net/bluetooth/lib.c               | 52 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 123 insertions(+), 7 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index fabee6db0..c6417d15c 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -237,6 +237,7 @@ static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src)
 }
 
 void baswap(bdaddr_t *dst, const bdaddr_t *src);
+int str2ba(const char *str, bdaddr_t *ba);
 
 /* Common socket structures and functions */
 
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b689aceb6..a822914d7 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -428,6 +428,7 @@ struct hci_dev {
 	__u32			rpa_timeout;
 	struct delayed_work	rpa_expired;
 	bdaddr_t		rpa;
+	bdaddr_t		force_rpa;
 
 #if IS_ENABLED(CONFIG_BT_LEDS)
 	struct led_trigger	*power_led;
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 402e2cc54..2363ae9bb 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -710,6 +710,57 @@ static const struct file_operations force_static_address_fops = {
 	.llseek		= default_llseek,
 };
 
+static ssize_t force_rpa_read(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[19];
+	bdaddr_t *ba = &hdev->force_rpa;
+
+	sprintf(buf, "%pMR\n", ba);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t force_rpa_write(struct file *file, const char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[18];
+	size_t buf_size = min(count, (sizeof(buf)-1));
+	bdaddr_t rpa;
+
+	if (test_bit(HCI_UP, &hdev->flags))
+		return -EBUSY;
+
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	buf[buf_size] = '\0';
+	if (str2ba(buf, &rpa))
+		return -EINVAL;
+
+	// the two most significant bits shall be 01 unless the address is
+	// 00:00:00:00:00:00
+	if ((rpa.b[5] & 0xc0) != 0x40 && bacmp(&rpa, BDADDR_ANY))
+		return -EINVAL;
+
+	if (!bacmp(&hdev->force_rpa, &rpa))
+		return -EALREADY;
+
+	bacpy(&hdev->force_rpa, &rpa);
+
+	return count;
+}
+
+static const struct file_operations force_rpa_fops = {
+	.open		= simple_open,
+	.read		= force_rpa_read,
+	.write		= force_rpa_write,
+	.llseek		= default_llseek,
+};
+
 static int white_list_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
@@ -1026,6 +1077,8 @@ void hci_debugfs_create_le(struct hci_dev *hdev)
 				    hdev->debugfs, hdev,
 				    &force_static_address_fops);
 
+	debugfs_create_file("force_rpa", 0644, hdev->debugfs, hdev,
+			    &force_rpa_fops);
 	debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
 			  &hdev->le_white_list_size);
 	debugfs_create_file("white_list", 0444, hdev->debugfs, hdev,
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 2a1b64dbf..8fabb1bb1 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -1910,14 +1910,23 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
 
 		*own_addr_type = ADDR_LE_DEV_RANDOM;
 
-		if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
-		    !bacmp(&hdev->random_addr, &hdev->rpa))
-			return 0;
+		/* If force_rpa is set to 00:00:00:00:00:00, generate a valid
+		 * RPA using IRK. Otherwise use the forced value.
+		 */
+		if (!bacmp(&hdev->force_rpa, BDADDR_ANY)) {
+			if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
+			    !bacmp(&hdev->random_addr, &hdev->rpa))
+				return 0;
 
-		err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
-		if (err < 0) {
-			bt_dev_err(hdev, "failed to generate new RPA");
-			return err;
+			err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
+			if (err < 0) {
+				bt_dev_err(hdev, "failed to generate new RPA");
+				return err;
+			}
+		} else {
+			if (!bacmp(&hdev->rpa, &hdev->force_rpa))
+				return 0;
+			bacpy(&hdev->rpa, &hdev->force_rpa);
 		}
 
 		set_random_addr(req, &hdev->rpa);
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
index 63e65d9b4..933d9dd48 100644
--- a/net/bluetooth/lib.c
+++ b/net/bluetooth/lib.c
@@ -27,6 +27,7 @@
 #define pr_fmt(fmt) "Bluetooth: " fmt
 
 #include <linux/export.h>
+#include <linux/ctype.h>
 
 #include <net/bluetooth/bluetooth.h>
 
@@ -41,6 +42,57 @@ void baswap(bdaddr_t *dst, const bdaddr_t *src)
 }
 EXPORT_SYMBOL(baswap);
 
+static int bachk(const char *str)
+{
+	if (!str)
+		return -1;
+
+	if (strlen(str) != 17)
+		return -1;
+
+	while (*str) {
+		if (!isxdigit(*str++))
+			return -1;
+
+		if (!isxdigit(*str++))
+			return -1;
+
+		if (*str == 0)
+			break;
+
+		if (*str++ != ':')
+			return -1;
+	}
+
+	return 0;
+}
+
+int str2ba(const char *str, bdaddr_t *ba)
+{
+	int i;
+	char digit_str[3];
+	long digit;
+
+	if (bachk(str) < 0) {
+		memset(ba, 0, sizeof(*ba));
+		return -1;
+	}
+
+	for (i = 5; i >= 0; i--, str += 3) {
+		digit_str[0] = str[0];
+		digit_str[1] = str[1];
+		digit_str[2] = '\0';
+		if (kstrtol(digit_str, 16, &digit))
+			return -1;
+		if (digit < 0x00 || digit > 0xff)
+			return -1;
+		ba->b[i] = digit;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(str2ba);
+
 /* Bluetooth error codes to Unix errno mapping */
 int bt_to_errno(__u16 code)
 {
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-12-02  4:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-01 21:57 [PATCH] Bluetooth: Expose debugfs entry to force resolvable private address Mike Ryan
2019-12-02  4:34 ` kbuild test robot
  -- strict thread matches above, loose matches on Subject: below --
2019-11-11  5:22 mike
2019-11-19 17:01 ` Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).