[sane-devel] USB device locking in the snapscan backend

Julien BLACHE jb at jblache.org
Sun Feb 24 16:12:17 UTC 2008


Hi,

The snapscan backend uses a mutex to lock the USB device it's working
with when sending "atomic" commands.

We're not talking about pthread mutexes here, which is one of the
available implementations, but IPC semaphores.

Let's look at the code:

static int snapscani_mutex_open(snapscan_mutex_t* sem_id, const char* dev)
{
    *sem_id = semget( ftok(dev,0x12), 1, IPC_CREAT | 0660 );
    if (*sem_id != -1)
    {
        semop(*sem_id, &sem_signal, 1);
        return 1;
    }
    return 0;
}

ftok() requires its first argument to be a real, accessible
file. Obviously, when the code was written, USB scanners were driven
through the kernel scanner driver and this was not a problem.

But today, dev is something like "libusb:001:003" which is all but a
real, accessible file.

ftok() returns -1 in this case, but this isn't checked for in this
code, so it happily goes on and semget(0xffffffff, 1, ...).

As it happens, most of the time, that works. Except when another
similarly careless piece of code has already used 0xffffffff as the
IPC key.

In which case, all hell breaks loose.

So, 2 bugs in this code:
 - ftok() return value is not checked (BAD BAD BAD)
 - dev is not a real file

Now, two questions:
 - is that locking really useful in the backend?
 - if yes, how do we fix this?

I've started patching sanei_usb to add a method to return the full
path to the USB device node, except libusb doesn't expose this
information. Second-guessing is obviously not an option :|

And there is the UsbCalls access method that needs to be fixed if it
can be used along with IPC semaphores and I don't know anything about
UsbCalls...

Thoughts ?

JB.

-- 
Julien BLACHE                                   <http://www.jblache.org> 
<jb at jblache.org>                                  GPG KeyID 0xF5D65169



More information about the sane-devel mailing list