poll(2) implementation for capabilities.
When calling poll(2) on a capability, unwrap first and then poll the underlying object. Approved by: re (kib), mentor (rwatson) Sponsored by: Google Inc
This commit is contained in:
parent
6291312c14
commit
d6f7248983
@ -1279,11 +1279,17 @@ pollrescan(struct thread *td)
|
||||
if (si != NULL)
|
||||
continue;
|
||||
fp = fdp->fd_ofiles[fd->fd];
|
||||
#ifdef CAPABILITIES
|
||||
if ((fp == NULL)
|
||||
|| (cap_funwrap(fp, CAP_POLL_EVENT, &fp) != 0)) {
|
||||
#else
|
||||
if (fp == NULL) {
|
||||
#endif
|
||||
fd->revents = POLLNVAL;
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: backend also returns POLLHUP and
|
||||
* POLLERR if appropriate.
|
||||
@ -1344,7 +1350,12 @@ pollscan(td, fds, nfd)
|
||||
fds->revents = 0;
|
||||
} else {
|
||||
fp = fdp->fd_ofiles[fds->fd];
|
||||
#ifdef CAPABILITIES
|
||||
if ((fp == NULL)
|
||||
|| (cap_funwrap(fp, CAP_POLL_EVENT, &fp) != 0)) {
|
||||
#else
|
||||
if (fp == NULL) {
|
||||
#endif
|
||||
fds->revents = POLLNVAL;
|
||||
n++;
|
||||
} else {
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -68,6 +69,7 @@ __FBSDID("$FreeBSD$");
|
||||
else if (errno != ENOTCAPABLE) \
|
||||
SYSCALL_FAIL(syscall, "errno != ENOTCAPABLE"); \
|
||||
} \
|
||||
errno = 0; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@ -87,6 +89,7 @@ __FBSDID("$FreeBSD$");
|
||||
} else if (errno != ENOTCAPABLE) \
|
||||
SYSCALL_FAIL(syscall, "errno != ENOTCAPABLE"); \
|
||||
} \
|
||||
errno = 0; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@ -104,6 +107,7 @@ try_file_ops(int fd, cap_rights_t rights)
|
||||
void *p;
|
||||
char ch;
|
||||
int ret, is_nfs;
|
||||
struct pollfd pollfd;
|
||||
int success = PASSED;
|
||||
|
||||
REQUIRE(fstatfs(fd, &sf));
|
||||
@ -114,6 +118,10 @@ try_file_ops(int fd, cap_rights_t rights)
|
||||
REQUIRE(fd_capcap = cap_new(fd_cap, rights));
|
||||
CHECK(fd_capcap != fd_cap);
|
||||
|
||||
pollfd.fd = fd_cap;
|
||||
pollfd.events = POLLIN | POLLERR | POLLHUP;
|
||||
pollfd.revents = 0;
|
||||
|
||||
ssize = read(fd_cap, &ch, sizeof(ch));
|
||||
CHECK_RESULT(read, CAP_READ | CAP_SEEK, ssize >= 0);
|
||||
|
||||
@ -189,7 +197,13 @@ try_file_ops(int fd, cap_rights_t rights)
|
||||
ret = futimes(fd_cap, NULL);
|
||||
CHECK_RESULT(futimes, CAP_FUTIMES, ret == 0);
|
||||
|
||||
/* XXX select / poll / kqueue */
|
||||
ret = poll(&pollfd, 1, 0);
|
||||
if (rights & CAP_POLL_EVENT)
|
||||
CHECK((pollfd.revents & POLLNVAL) == 0);
|
||||
else
|
||||
CHECK((pollfd.revents & POLLNVAL) != 0);
|
||||
|
||||
/* XXX: select, kqueue */
|
||||
|
||||
close (fd_cap);
|
||||
return (success);
|
||||
@ -210,7 +224,7 @@ test_capabilities(void)
|
||||
int fd;
|
||||
int success = PASSED;
|
||||
|
||||
fd = open("/tmp/cap_test", O_RDWR | O_CREAT, 0644);
|
||||
fd = open("/tmp/cap_test_capabilities", O_RDWR | O_CREAT, 0644);
|
||||
if (fd < 0)
|
||||
err(-1, "open");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user