Work without permission to access local node's /dev/fw*

On 10 Jan, David Moore wrote:
> On Sat, 2009-01-10 at 19:28 +0100, Stefan Richter wrote:
>> @@ -161,14 +160,16 @@ scan_devices(fw_handle_t handle)
...
>> +		for (j = 0; j < i; j++)
>> +			if (ports[j].card == get_info.card)
>> +				continue;
>> +
>
> That continue statement doesn't do what you intended I think.

From: Stefan Richter <stefanr@s5r6.in-berlin.de>
Subject: [PATCH] Work without permission to access local node's /dev/fw*

Fix for juju backend:

libraw1394 required write permission to the character device file of
the local node(s) in order to enumerate cards and for a number of
other operations.  This forced users to either run applications like
dvgrab and kino with elevated privileges, or to configure write
permission for all /dev/fw* or at least for local nodes' /dev/fw*.

We now use the first accessible file which was found for each card
for as many tasks as possible, instead of the local node's file.

This allows distributors or admins to implement stricter access
rights (default off, e.g. only on for AV/C and IIDC devices)
without sacrificing functionality of said class of applications.
Access to the local node is now only required by low-level tools
like gscanbus.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: Dan Dennedy <dan@dennedy.org>
This commit is contained in:
Stefan Richter 2009-01-10 21:03:25 +01:00 committed by Dan Dennedy
parent cb8b7bf86a
commit a59532c835
3 changed files with 38 additions and 21 deletions

View File

@ -407,7 +407,7 @@ iso_init(fw_handle_t handle, int type,
if (handle->iso.packets == NULL)
return -1;
handle->iso.fd = open(handle->local_filename, O_RDWR);
handle->iso.fd = open(handle->iso.filename, O_RDWR);
if (handle->iso.fd < 0) {
free(handle->iso.packets);
handle->iso.packets = NULL;
@ -557,7 +557,7 @@ int fw_read_cycle_timer(fw_handle_t handle,
int err;
struct fw_cdev_get_cycle_timer ctr = { 0 };
err = ioctl(handle->local_fd, FW_CDEV_IOC_GET_CYCLE_TIMER, &ctr);
err = ioctl(handle->ioctl_fd, FW_CDEV_IOC_GET_CYCLE_TIMER, &ctr);
if (!err) {
*cycle_timer = ctr.cycle_timer;
*local_time = ctr.local_time;

View File

@ -125,17 +125,19 @@ scan_devices(fw_handle_t handle)
char filename[32];
struct fw_cdev_get_info get_info;
struct fw_cdev_event_bus_reset reset;
int fd, err, i, fname_str_sz;
int fd, err, i, j, fname_str_sz;
struct port *ports;
ports = handle->ports;
memset(ports, 0, sizeof handle->ports);
for (i = 0; i < MAX_PORTS; i++)
ports[i].card = -1;
dir = opendir(FW_DEVICE_DIR);
if (dir == NULL)
return -1;
i = 0;
while (1) {
for (i = 0; i < MAX_PORTS; ) {
de = readdir(dir);
if (de == NULL)
break;
@ -161,7 +163,10 @@ scan_devices(fw_handle_t handle)
if (err < 0)
continue;
if (i < MAX_PORTS && reset.node_id == reset.local_node_id) {
for (j = 0; j < i; j++)
if (ports[j].card == get_info.card)
break;
if (j == i) {
fname_str_sz = sizeof(ports[i].device_file) - 1;
strncpy(ports[i].device_file, filename, fname_str_sz);
ports[i].device_file[fname_str_sz] = '\0';
@ -626,20 +631,27 @@ int fw_set_port(fw_handle_t handle, int port)
return -1;
}
handle->generation = reset.generation;
if (reset.node_id == reset.local_node_id) {
if (handle->iso.filename == NULL) {
memcpy(&handle->reset, &reset, sizeof handle->reset);
handle->local_fd = fd;
fname_str_sz = sizeof(handle->local_filename) -1;
strncpy(handle->local_filename, filename, fname_str_sz);
handle->local_filename[fname_str_sz] = '\0';
handle->iso.filename = handle->devices[i].filename;
handle->ioctl_fd = fd;
}
if (reset.node_id == reset.local_node_id)
handle->local_device = &handle->devices[i];
handle->generation = reset.generation;
i++;
}
closedir(dir);
if (i == 0) {
errno = ENODEV;
return -1;
}
return 0;
}
@ -656,7 +668,7 @@ int fw_reset_bus_new(fw_handle_t handle, int type)
break;
}
return ioctl(handle->local_fd,
return ioctl(handle->ioctl_fd,
FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate);
}
@ -817,7 +829,7 @@ fw_arm_register(fw_handle_t handle, nodeaddr_t start,
request.length = length;
request.closure = ptr_to_u64(&allocation->closure);
retval = ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request);
retval = ioctl(handle->ioctl_fd, FW_CDEV_IOC_ALLOCATE, &request);
if (retval < 0) {
free(allocation);
return -1;
@ -863,7 +875,7 @@ fw_arm_unregister(fw_handle_t handle, nodeaddr_t start)
request.handle = allocation->handle;
free(allocation);
return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request);
return ioctl(handle->ioctl_fd, FW_CDEV_IOC_DEALLOCATE, &request);
}
int
@ -1251,7 +1263,7 @@ fw_start_fcp_listen(fw_handle_t handle)
request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND;
request.length = CSR_FCP_END - CSR_FCP_COMMAND;
request.closure = ptr_to_u64(closure);
if (ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0)
if (ioctl(handle->ioctl_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0)
return -1;
handle->fcp_allocation_handle = request.handle;
@ -1266,7 +1278,7 @@ fw_stop_fcp_listen(fw_handle_t handle)
request.handle = handle->fcp_allocation_handle;
return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request);
return ioctl(handle->ioctl_fd, FW_CDEV_IOC_DEALLOCATE, &request);
}
int
@ -1284,13 +1296,18 @@ fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
struct fw_cdev_get_info get_info;
int err;
if (handle->local_device == NULL) {
errno = EPERM;
return -1;
}
memset(&get_info, 0, sizeof(get_info));
get_info.version = FW_CDEV_VERSION;
get_info.rom = ptr_to_u64(buffer);
get_info.rom_length = buffersize;
get_info.bus_reset = 0;
err = ioctl(handle->local_fd, FW_CDEV_IOC_GET_INFO, &get_info);
err = ioctl(handle->local_device->fd, FW_CDEV_IOC_GET_INFO, &get_info);
if (err)
return err;

View File

@ -101,6 +101,7 @@ struct fw_handle {
__u32 fcp_allocation_handle;
struct allocation *allocations;
int ioctl_fd;
int epoll_fd;
int inotify_fd;
int inotify_watch;
@ -110,13 +111,12 @@ struct fw_handle {
struct epoll_closure inotify_closure;
struct device devices[MAX_DEVICES];
struct device *local_device;
int nodes[MAX_DEVICES];
int local_fd;
char local_filename[FILENAME_SIZE];
struct fw_cdev_event_bus_reset reset;
struct {
char *filename;
struct epoll_closure closure;
int fd;
int type;