aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-10 21:03:25 +0100
committerDan Dennedy <dan@dennedy.org>2009-01-10 16:50:28 -0800
commita59532c835c2a0c403059e4dbb8a6eb6e6bce516 (patch)
tree78d9d1c5752ff3a3502ec5e3baa5f1203471de19
parentcb8b7bf86af003ac6eeb167305c70192c4959c7b (diff)
downloadlibraw1394-a59532c835c2a0c403059e4dbb8a6eb6e6bce516.tar.gz
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>
-rw-r--r--src/fw-iso.c4
-rw-r--r--src/fw.c49
-rw-r--r--src/fw.h6
3 files changed, 38 insertions, 21 deletions
diff --git a/src/fw-iso.c b/src/fw-iso.c
index 6a84662..a87259b 100644
--- a/src/fw-iso.c
+++ b/src/fw-iso.c
@@ -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;
diff --git a/src/fw.c b/src/fw.c
index e211b60..dd2a968 100644
--- a/src/fw.c
+++ b/src/fw.c
@@ -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;
diff --git a/src/fw.h b/src/fw.h
index 56b59d9..a5e3772 100644
--- a/src/fw.h
+++ b/src/fw.h
@@ -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;