The open source OpenXR runtime

os/ble: Fix memory leak if we fail to find a device

+92 -72
+1
doc/changes/misc_fixes/mr.264.md
··· 1 + Fix leak in `os/os_ble_dbus.c` code when failing to find any device.
+91 -72
src/xrt/auxiliary/os/os_ble_dbus.c
··· 24 24 25 25 /* 26 26 * 27 + * Structs. 28 + * 29 + */ 30 + 31 + struct ble_notify 32 + { 33 + struct os_ble_device base; 34 + DBusConnection *conn; 35 + DBusError err; 36 + int fd; 37 + }; 38 + 39 + 40 + /* 41 + * 27 42 * Send helpers. 28 43 * 29 44 */ ··· 622 637 return 0; 623 638 } 624 639 640 + static int 641 + init_ble_notify(const char *dev_uuid, 642 + const char *char_uuid, 643 + struct ble_notify *bledev) 644 + { 645 + DBusMessage *msg; 646 + 647 + dbus_error_init(&bledev->err); 648 + bledev->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &bledev->err); 649 + if (dbus_error_is_set(&bledev->err)) { 650 + fprintf(stderr, "DBUS Connection Error: %s\n", 651 + bledev->err.message); 652 + dbus_error_free(&bledev->err); 653 + } 654 + if (bledev->conn == NULL) { 655 + return -1; 656 + } 657 + 658 + char dbus_address[256]; // should be long enough 659 + XRT_MAYBE_UNUSED ssize_t written = 660 + get_path_to_notify_char(bledev->conn, dev_uuid, char_uuid, 661 + dbus_address, sizeof(dbus_address)); 662 + if (written == 0) { 663 + return -1; 664 + } else if (written < 0) { 665 + return -1; 666 + } 667 + 668 + msg = dbus_message_new_method_call( 669 + "org.bluez", // target for the method call 670 + dbus_address, // object to call on 671 + "org.bluez.GattCharacteristic1", // interface to call on 672 + "AcquireNotify"); // method name 673 + if (msg == NULL) { 674 + fprintf(stderr, "Message Null after construction\n"); 675 + return -1; 676 + } 677 + 678 + // AcquireNotify has a argument of Array of Dicts. 679 + add_empty_dict_sv(msg); 680 + 681 + // Send the message, consumes our message and returns what we received. 682 + if (send_message(bledev->conn, &bledev->err, &msg) != 0) { 683 + return -1; 684 + } 685 + 686 + DBusMessageIter args; 687 + char *response = NULL; 688 + dbus_message_iter_init(msg, &args); 689 + while (true) { 690 + int type = dbus_message_iter_get_arg_type(&args); 691 + if (type == DBUS_TYPE_INVALID) { 692 + break; 693 + } else if (type == DBUS_TYPE_STRING) { 694 + dbus_message_iter_get_basic(&args, &response); 695 + printf("DBus call returned message: %s\n", response); 696 + } else if (type == DBUS_TYPE_UNIX_FD) { 697 + dbus_message_iter_get_basic(&args, &bledev->fd); 698 + } 699 + dbus_message_iter_next(&args); 700 + } 701 + 702 + // free reply 703 + dbus_message_unref(msg); 704 + 705 + // We didn't get a fd. 706 + if (bledev->fd == -1) { 707 + return -1; 708 + } 709 + 710 + return 0; 711 + } 712 + 625 713 626 714 /* 627 715 * ··· 629 717 * 630 718 */ 631 719 632 - struct ble_notify 633 - { 634 - struct os_ble_device base; 635 - DBusConnection *conn; 636 - DBusError err; 637 - int fd; 638 - }; 639 - 640 720 static int 641 721 os_ble_notify_read(struct os_ble_device *bdev, 642 722 uint8_t *data, ··· 684 764 } 685 765 686 766 if (dev->conn != NULL) { 767 + dbus_error_free(&dev->err); 687 768 dbus_connection_unref(dev->conn); 688 769 dev->conn = NULL; 689 770 } ··· 696 777 const char *char_uuid, 697 778 struct os_ble_device **out_ble) 698 779 { 699 - DBusMessage *msg; 700 - 701 780 struct ble_notify *bledev = U_TYPED_CALLOC(struct ble_notify); 702 781 bledev->base.read = os_ble_notify_read; 703 782 bledev->base.destroy = os_ble_notify_destroy; 704 783 bledev->fd = -1; 705 784 706 - dbus_error_init(&bledev->err); 707 - bledev->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &bledev->err); 708 - if (dbus_error_is_set(&bledev->err)) { 709 - fprintf(stderr, "DBUS Connection Error: %s\n", 710 - bledev->err.message); 711 - dbus_error_free(&bledev->err); 712 - } 713 - if (bledev->conn == NULL) { 714 - os_ble_notify_destroy(&bledev->base); 715 - return -1; 716 - } 717 - 718 - char dbus_address[256]; // should be long enough 719 - XRT_MAYBE_UNUSED ssize_t written = 720 - get_path_to_notify_char(bledev->conn, dev_uuid, char_uuid, 721 - dbus_address, sizeof(dbus_address)); 722 - if (written == 0) { 723 - return 0; 724 - } else if (written < 0) { 725 - return -1; 726 - } 727 - 728 - msg = dbus_message_new_method_call( 729 - "org.bluez", // target for the method call 730 - dbus_address, // object to call on 731 - "org.bluez.GattCharacteristic1", // interface to call on 732 - "AcquireNotify"); // method name 733 - if (msg == NULL) { 734 - fprintf(stderr, "Message Null after construction\n"); 735 - os_ble_notify_destroy(&bledev->base); 736 - return -1; 737 - } 738 - 739 - // AcquireNotify has a argument of Array of Dicts. 740 - add_empty_dict_sv(msg); 741 - 742 - // Send the message, consumes our message and returns what we received. 743 - if (send_message(bledev->conn, &bledev->err, &msg) != 0) { 744 - return -1; 745 - } 746 - 747 - DBusMessageIter args; 748 - char *response = NULL; 749 - dbus_message_iter_init(msg, &args); 750 - while (true) { 751 - int type = dbus_message_iter_get_arg_type(&args); 752 - if (type == DBUS_TYPE_INVALID) { 753 - break; 754 - } else if (type == DBUS_TYPE_STRING) { 755 - dbus_message_iter_get_basic(&args, &response); 756 - printf("DBus call returned message: %s\n", response); 757 - } else if (type == DBUS_TYPE_UNIX_FD) { 758 - dbus_message_iter_get_basic(&args, &bledev->fd); 759 - } 760 - dbus_message_iter_next(&args); 761 - } 762 - 763 - // free reply 764 - dbus_message_unref(msg); 765 - 766 - // We didn't get a fd. 767 - if (bledev->fd == -1) { 785 + int ret = init_ble_notify(dev_uuid, char_uuid, bledev); 786 + if (ret <= 0) { 768 787 os_ble_notify_destroy(&bledev->base); 769 788 return -1; 770 789 }