2019-07-05 09:15:21

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: [PATCH BlueZ] mesh: Check address range passed to ImportRemoteNode

From: Michał 'Khorne' Lowas-Rzechonek <[email protected]>

This patch disallows importing device key for:
- non-unicast addresses
- unicast addresses overlapping with local node address range
---
doc/mesh-api.txt | 8 ++++++++
mesh/keyring.c | 9 +++++++++
mesh/manager.c | 13 +++++++++++++
3 files changed, 30 insertions(+)

diff --git a/doc/mesh-api.txt b/doc/mesh-api.txt
index f2ba164a9..4fa2f9690 100644
--- a/doc/mesh-api.txt
+++ b/doc/mesh-api.txt
@@ -609,9 +609,13 @@ Methods:

This call affects the local bluetooth-meshd key database only.

+ It is an error to call this with address range overlapping
+ with local element addresses.
+
PossibleErrors:
org.bluez.mesh.Error.Failed
org.bluez.mesh.Error.InvalidArguments
+ org.bluez.mesh.Error.NotAuthorized

void DeleteRemoteNode(uint16 primary, uint8 count)

@@ -626,8 +630,12 @@ Methods:

This call affects the local bluetooth-meshd key database only.

+ It is an error to call this with address range overlapping
+ with local element addresses.
+
PossibleErrors:
org.bluez.mesh.Error.InvalidArguments
+ org.bluez.mesh.Error.NotAuthorized

Properties:
dict Features [read-only]
diff --git a/mesh/keyring.c b/mesh/keyring.c
index 4c6d2986d..be17fb8a5 100644
--- a/mesh/keyring.c
+++ b/mesh/keyring.c
@@ -131,6 +131,9 @@ bool keyring_put_remote_dev_key(struct mesh_node *node, uint16_t unicast,
if (!node)
return false;

+ if (!IS_UNICAST(unicast) || !IS_UNICAST(unicast + count - 1))
+ return false;
+
node_path = node_path_get(node);

if (strlen(node_path) + strlen(dev_key_dir) + 1 + 4 >= PATH_MAX)
@@ -221,6 +224,9 @@ bool keyring_get_remote_dev_key(struct mesh_node *node, uint16_t unicast,
if (!node)
return false;

+ if (!IS_UNICAST(unicast))
+ return false;
+
node_path = node_path_get(node);
snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path, dev_key_dir,
unicast);
@@ -283,6 +289,9 @@ bool keyring_del_remote_dev_key(struct mesh_node *node, uint16_t unicast,
if (!node)
return false;

+ if (!IS_UNICAST(unicast) || !IS_UNICAST(unicast + count - 1))
+ return false;
+
node_path = node_path_get(node);
for (i = 0; i < count; i++) {
snprintf(key_file, PATH_MAX, "%s%s/%4.4x", node_path,
diff --git a/mesh/manager.c b/mesh/manager.c
index ca3562512..d3c4b2e21 100644
--- a/mesh/manager.c
+++ b/mesh/manager.c
@@ -31,6 +31,7 @@
#include "mesh/node.h"
#include "mesh/keyring.h"
#include "mesh/manager.h"
+#include "mesh/net.h"

static struct l_dbus_message *add_node_call(struct l_dbus *dbus,
struct l_dbus_message *msg,
@@ -60,6 +61,7 @@ static struct l_dbus_message *import_node_call(struct l_dbus *dbus,
void *user_data)
{
struct mesh_node *node = user_data;
+ struct mesh_net *net = node_get_net(node);
struct l_dbus_message_iter iter_key;
uint16_t primary;
uint8_t num_ele;
@@ -75,6 +77,11 @@ static struct l_dbus_message *import_node_call(struct l_dbus *dbus,
return dbus_error(msg, MESH_ERROR_INVALID_ARGS,
"Bad device key");

+ if (mesh_net_is_local_address(net, primary) ||
+ mesh_net_is_local_address(net, primary + num_ele - 1))
+ return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED,
+ "Cannot overwrite local device key");
+
if (!keyring_put_remote_dev_key(node, primary, num_ele, key))
return dbus_error(msg, MESH_ERROR_FAILED, NULL);

@@ -86,12 +93,18 @@ static struct l_dbus_message *delete_node_call(struct l_dbus *dbus,
void *user_data)
{
struct mesh_node *node = user_data;
+ struct mesh_net *net = node_get_net(node);
uint16_t primary;
uint8_t num_ele;

if (!l_dbus_message_get_arguments(msg, "qy", &primary, &num_ele))
return dbus_error(msg, MESH_ERROR_INVALID_ARGS, NULL);

+ if (mesh_net_is_local_address(net, primary) ||
+ mesh_net_is_local_address(net, primary + num_ele - 1))
+ return dbus_error(msg, MESH_ERROR_NOT_AUTHORIZED,
+ "Cannot remove local device key");
+
keyring_del_remote_dev_key(node, primary, num_ele);

return l_dbus_message_new_method_return(msg);
--
2.22.0