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:
parent
cb8b7bf86a
commit
a59532c835
|
@ -407,7 +407,7 @@ iso_init(fw_handle_t handle, int type,
|
||||||
if (handle->iso.packets == NULL)
|
if (handle->iso.packets == NULL)
|
||||||
return -1;
|
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) {
|
if (handle->iso.fd < 0) {
|
||||||
free(handle->iso.packets);
|
free(handle->iso.packets);
|
||||||
handle->iso.packets = NULL;
|
handle->iso.packets = NULL;
|
||||||
|
@ -557,7 +557,7 @@ int fw_read_cycle_timer(fw_handle_t handle,
|
||||||
int err;
|
int err;
|
||||||
struct fw_cdev_get_cycle_timer ctr = { 0 };
|
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) {
|
if (!err) {
|
||||||
*cycle_timer = ctr.cycle_timer;
|
*cycle_timer = ctr.cycle_timer;
|
||||||
*local_time = ctr.local_time;
|
*local_time = ctr.local_time;
|
||||||
|
|
49
src/fw.c
49
src/fw.c
|
@ -125,17 +125,19 @@ scan_devices(fw_handle_t handle)
|
||||||
char filename[32];
|
char filename[32];
|
||||||
struct fw_cdev_get_info get_info;
|
struct fw_cdev_get_info get_info;
|
||||||
struct fw_cdev_event_bus_reset reset;
|
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;
|
struct port *ports;
|
||||||
|
|
||||||
ports = handle->ports;
|
ports = handle->ports;
|
||||||
memset(ports, 0, sizeof handle->ports);
|
memset(ports, 0, sizeof handle->ports);
|
||||||
|
for (i = 0; i < MAX_PORTS; i++)
|
||||||
|
ports[i].card = -1;
|
||||||
|
|
||||||
dir = opendir(FW_DEVICE_DIR);
|
dir = opendir(FW_DEVICE_DIR);
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
i = 0;
|
for (i = 0; i < MAX_PORTS; ) {
|
||||||
while (1) {
|
|
||||||
de = readdir(dir);
|
de = readdir(dir);
|
||||||
if (de == NULL)
|
if (de == NULL)
|
||||||
break;
|
break;
|
||||||
|
@ -161,7 +163,10 @@ scan_devices(fw_handle_t handle)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
continue;
|
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;
|
fname_str_sz = sizeof(ports[i].device_file) - 1;
|
||||||
strncpy(ports[i].device_file, filename, fname_str_sz);
|
strncpy(ports[i].device_file, filename, fname_str_sz);
|
||||||
ports[i].device_file[fname_str_sz] = '\0';
|
ports[i].device_file[fname_str_sz] = '\0';
|
||||||
|
@ -626,20 +631,27 @@ int fw_set_port(fw_handle_t handle, int port)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->generation = reset.generation;
|
if (handle->iso.filename == NULL) {
|
||||||
if (reset.node_id == reset.local_node_id) {
|
|
||||||
memcpy(&handle->reset, &reset, sizeof handle->reset);
|
memcpy(&handle->reset, &reset, sizeof handle->reset);
|
||||||
handle->local_fd = fd;
|
handle->iso.filename = handle->devices[i].filename;
|
||||||
fname_str_sz = sizeof(handle->local_filename) -1;
|
handle->ioctl_fd = fd;
|
||||||
strncpy(handle->local_filename, filename, fname_str_sz);
|
|
||||||
handle->local_filename[fname_str_sz] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (reset.node_id == reset.local_node_id)
|
||||||
|
handle->local_device = &handle->devices[i];
|
||||||
|
|
||||||
|
handle->generation = reset.generation;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,7 +668,7 @@ int fw_reset_bus_new(fw_handle_t handle, int type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioctl(handle->local_fd,
|
return ioctl(handle->ioctl_fd,
|
||||||
FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate);
|
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.length = length;
|
||||||
request.closure = ptr_to_u64(&allocation->closure);
|
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) {
|
if (retval < 0) {
|
||||||
free(allocation);
|
free(allocation);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -863,7 +875,7 @@ fw_arm_unregister(fw_handle_t handle, nodeaddr_t start)
|
||||||
request.handle = allocation->handle;
|
request.handle = allocation->handle;
|
||||||
free(allocation);
|
free(allocation);
|
||||||
|
|
||||||
return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
return ioctl(handle->ioctl_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1251,7 +1263,7 @@ fw_start_fcp_listen(fw_handle_t handle)
|
||||||
request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND;
|
request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND;
|
||||||
request.length = CSR_FCP_END - CSR_FCP_COMMAND;
|
request.length = CSR_FCP_END - CSR_FCP_COMMAND;
|
||||||
request.closure = ptr_to_u64(closure);
|
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;
|
return -1;
|
||||||
|
|
||||||
handle->fcp_allocation_handle = request.handle;
|
handle->fcp_allocation_handle = request.handle;
|
||||||
|
@ -1266,7 +1278,7 @@ fw_stop_fcp_listen(fw_handle_t handle)
|
||||||
|
|
||||||
request.handle = handle->fcp_allocation_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
|
int
|
||||||
|
@ -1284,13 +1296,18 @@ fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
||||||
struct fw_cdev_get_info get_info;
|
struct fw_cdev_get_info get_info;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (handle->local_device == NULL) {
|
||||||
|
errno = EPERM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&get_info, 0, sizeof(get_info));
|
memset(&get_info, 0, sizeof(get_info));
|
||||||
get_info.version = FW_CDEV_VERSION;
|
get_info.version = FW_CDEV_VERSION;
|
||||||
get_info.rom = ptr_to_u64(buffer);
|
get_info.rom = ptr_to_u64(buffer);
|
||||||
get_info.rom_length = buffersize;
|
get_info.rom_length = buffersize;
|
||||||
get_info.bus_reset = 0;
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
6
src/fw.h
6
src/fw.h
|
@ -101,6 +101,7 @@ struct fw_handle {
|
||||||
__u32 fcp_allocation_handle;
|
__u32 fcp_allocation_handle;
|
||||||
struct allocation *allocations;
|
struct allocation *allocations;
|
||||||
|
|
||||||
|
int ioctl_fd;
|
||||||
int epoll_fd;
|
int epoll_fd;
|
||||||
int inotify_fd;
|
int inotify_fd;
|
||||||
int inotify_watch;
|
int inotify_watch;
|
||||||
|
@ -110,13 +111,12 @@ struct fw_handle {
|
||||||
struct epoll_closure inotify_closure;
|
struct epoll_closure inotify_closure;
|
||||||
|
|
||||||
struct device devices[MAX_DEVICES];
|
struct device devices[MAX_DEVICES];
|
||||||
|
struct device *local_device;
|
||||||
int nodes[MAX_DEVICES];
|
int nodes[MAX_DEVICES];
|
||||||
int local_fd;
|
|
||||||
char local_filename[FILENAME_SIZE];
|
|
||||||
|
|
||||||
struct fw_cdev_event_bus_reset reset;
|
struct fw_cdev_event_bus_reset reset;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
char *filename;
|
||||||
struct epoll_closure closure;
|
struct epoll_closure closure;
|
||||||
int fd;
|
int fd;
|
||||||
int type;
|
int type;
|
||||||
|
|
Reference in New Issue