Repository: secdev/scapy

Issue:
Cannot Open BluetoothUserSocket After Opening/Closing One Beforehand
I am working on a program that creates a BluetoothUserSocket with a local Bluetooth adapter, does some stuff, closes the socket, then creates a new BluetoothUserSocket with the same adapter. When I do this, I get an error: "IOError: [Errno 16] Device or resource busy". Is there some proper way to close down the socket and free the resource that I'm missing?

The following is some sample code I'm using to test this (based on code from PyBT https://github.com/mikeryan/PyBT/tree/master/PyBT):

``` python
import os
import sys
from fcntl import ioctl
import logging
import time
import socket as s
from scapy.layers.bluetooth import *
from select import select

class HCIConfig(object):
    @staticmethod
    def down(iface):
        #31 => PF_BLUETOOTH
        #0 => HCI_CHANNEL_USER
        # 0x400448ca => HCIDEVDOWN
        sock = s.socket(31, s.SOCK_RAW, 1)
        ioctl(sock.fileno(), 0x400448ca, iface)
        sock.close()
        return True

    @staticmethod
    def up(iface):
        sock = s.socket(31, s.SOCK_RAW, iface)
        # TODO
        # ioctl(sock.fileno(), HCIDEVUP, 0)
        sock.close()
        return False


def get_socket(adapter):
    try:
        return BluetoothUserSocket(adapter)
    except BluetoothSocketError as e:

        log.debug("[!] Creating socket failed: %s\n" % (repr(e)))
        if os.getuid() > 0:
            log.error("[!] Are you definitely root? detected uid: %d\n" % (os.getuid()))
        else:
            log.debug("[+] have root, attempting to take iface down\n")
            HCIConfig.down(adapter)
            try:
                return BluetoothUserSocket(adapter)
            except BluetoothSocketError as e:
                log.error("[!] Failed to create socket: %s" % repr(e))
                log.error("[!] Giving up.\n")
    sys.exit(1)


print "First time getting socket"
sock = get_socket(0)
print "About to flush"
sock.flush()
print "About to close"
sock.close()
print "Sleeping...2 seconds"
time.sleep(2)
print "Second time getting socket"
sock = get_socket(0)
print "About to flush"
sock.flush()
print "About to close"
sock.close()
```

The following is the output from this program:

```
$ sudo python bt.py
First time getting socket
About to flush
About to close
Sleeping...2 seconds
Second time getting socket
Traceback (most recent call last):
  File "bt.py", line 60, in <module>
    sock = get_socket(0)
  File "bt.py", line 42, in get_socket
    HCIConfig.down(adapter)
  File "bt.py", line 19, in down
    ioctl(sock.fileno(), 0x400448ca, iface)
IOError: [Errno 16] Device or resource busy
```



Discussion:
Hi,

Is there anything else using the bluetooth adapter?

Anyway unless I'm wrong (if so, please reopen), the problem exists in your code rather than in Scapy, so I'm closing this issue.

As far as I'm aware, nothing else is using the adapter. I am able to create the socket by supplying the adapter identifier and, using some other code not displayed above, connect to a Bluetooth Low Energy device. I get the error after closing the socket and then attempting to open a new socket with the same adapter. Interestingly enough, after the Python process is dead, I am able to re-launch the script and open the socket.

There is a possibility that my code is missing something, but I'm really not sure what it would be at this point. I can't seem to find any documentation on this. Any suggestions?

Sorry, I was totally wrong. I had no idea how weird the `BluetoothUserSocket` code is ;-) (but as far as I understand, that's for a good reason)!

Can you try the patch from PR #193 and tell me if it fixes this issue? Anyway you are right, this is definitely a bug in Scapy, and more specifically related to the way Scapy closes `BluetoothUserSocket` objects.

Thanks for your time and sorry for the initial misunderstanding.

No problem, it was just as plausible that I screwed up in my code somewhere. 

I just tried your code from PR #193 using the same test code I posted before and a couple other pieces of code I'm working on, same error. Beyond flushing the socket and closing the socket, are there any further steps that need to be done in order to ensure the resource is freed?

Not that I know of, unfortunately…

Seems to me the bug does not exist in Scapy but in the Bluetooth sockets. Please reopen if needed.
Hello,
I'm getting same issue. Is there any update on this? 
Hi All,
I'm running to the same issue, from the previous comment, the commit did not fix the issue.
Could us reopen the issue?
This issue is still not solved. Can I replace BluetoothUserSocket with BluetoothHCISocket? I didn't find much description of their difference.

Resolving patch:
diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py
--- a/scapy/layers/bluetooth.py
+++ b/scapy/layers/bluetooth.py
@@ -1523,6 +1523,7 @@ def __init__(self, adapter_index=0):
         if r != 0:
             raise BluetoothSocketError("Unable to bind")
 
+        self.hci_fd = s
         self.ins = self.outs = socket.fromfd(s, 31, 3, 1)
 
     def send_command(self, cmd):
@@ -1564,6 +1565,7 @@ def close(self):
         if hasattr(self, "ins"):
             if self.ins and (WINDOWS or self.ins.fileno() != -1):
                 close(self.ins.fileno())
+        close(self.hci_fd)
 
 
 conf.BTsocket = BluetoothRFCommSocket


Test patch: