summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2009-02-10 15:58:14 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2009-02-10 15:58:14 +0200
commit60cf1091c23bb36f45f56ab94b1904e61498f3c7 (patch)
treed02673a16b8e2941228816c890ccfdb3691cd9c5
parent13f9996bbaeb5865fa1e152a45509aceaad73734 (diff)
Make the unix IPC handling more robust
This patch adds extra checks to strictly only allow messages that can be expected to work with the current code.
-rw-r--r--audio/unix.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/audio/unix.c b/audio/unix.c
index e30a2257..472347b1 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -648,8 +648,6 @@ static void start_discovery(struct audio_device *dev, struct unix_client *client
struct a2dp_data *a2dp;
int err = 0;
- client->type = select_service(dev, client->interface);
-
switch (client->type) {
case TYPE_SINK:
a2dp = &client->d.a2dp;
@@ -691,8 +689,6 @@ static void start_config(struct audio_device *dev, struct unix_client *client)
struct headset_data *hs;
unsigned int id;
- client->type = select_service(dev, client->interface);
-
switch (client->type) {
case TYPE_SINK:
a2dp = &client->d.a2dp;
@@ -758,8 +754,6 @@ static void start_resume(struct audio_device *dev, struct unix_client *client)
struct headset_data *hs;
unsigned int id;
- client->type = select_service(dev, client->interface);
-
switch (client->type) {
case TYPE_SINK:
a2dp = &client->d.a2dp;
@@ -813,8 +807,6 @@ static void start_suspend(struct audio_device *dev, struct unix_client *client)
struct headset_data *hs;
unsigned int id;
- client->type = select_service(dev, client->interface);
-
switch (client->type) {
case TYPE_SINK:
a2dp = &client->d.a2dp;
@@ -870,8 +862,8 @@ static void handle_getcapabilities_req(struct unix_client *client,
str2ba(req->device, &bdaddr);
if (client->interface) {
- g_free(client->interface);
- client->interface = NULL;
+ error("Got GET_CAPABILITIES for an initialized client");
+ goto failed;
}
if (req->transport == BT_CAPABILITIES_TRANSPORT_SCO)
@@ -883,15 +875,19 @@ static void handle_getcapabilities_req(struct unix_client *client,
goto failed;
dev = manager_find_device(&bdaddr, client->interface, TRUE);
+ if (!dev && (req->flags & BT_FLAG_AUTOCONNECT))
+ dev = manager_find_device(&bdaddr, client->interface, FALSE);
+
if (!dev) {
- if (req->flags & BT_FLAG_AUTOCONNECT)
- dev = manager_find_device(&bdaddr, client->interface, FALSE);
- else
- goto failed;
+ error("Unable to find a matching device");
+ goto failed;
}
- if (!dev)
+ client->type = select_service(dev, client->interface);
+ if (client->type == TYPE_NONE) {
+ error("No matching service found");
goto failed;
+ }
start_discovery(dev, client);
@@ -904,7 +900,10 @@ failed:
static int handle_sco_transport(struct unix_client *client,
struct bt_set_configuration_req *req)
{
- client->interface = g_strdup(AUDIO_HEADSET_INTERFACE);
+ if (!client->interface)
+ client->interface = g_strdup(AUDIO_HEADSET_INTERFACE);
+ else if (!g_str_equal(client->interface, AUDIO_HEADSET_INTERFACE))
+ return -EIO;
debug("config sco - device = %s access_mode = %u", req->device,
req->access_mode);
@@ -919,7 +918,10 @@ static int handle_a2dp_transport(struct unix_client *client,
struct sbc_codec_cap sbc_cap;
struct mpeg_codec_cap mpeg_cap;
- client->interface = g_strdup(AUDIO_SINK_INTERFACE);
+ if (!client->interface)
+ client->interface = g_strdup(AUDIO_SINK_INTERFACE);
+ else if (!g_str_equal(client->interface, AUDIO_SINK_INTERFACE))
+ return -EIO;
if (client->caps) {
g_slist_foreach(client->caps, (GFunc) g_free, NULL);
@@ -1003,11 +1005,6 @@ static void handle_setconfiguration_req(struct unix_client *client,
str2ba(req->device, &bdaddr);
- if (client->interface) {
- g_free(client->interface);
- client->interface = NULL;
- }
-
if (req->codec.transport == BT_CAPABILITIES_TRANSPORT_SCO) {
err = handle_sco_transport(client, req);
if (err < 0) {