Replace CAP_POLL_EVENT and CAP_POST_EVENT capability rights (which I had

a very hard time to fully understand) with much more intuitive rights:

	CAP_EVENT - when set on descriptor, the descriptor can be monitored
		with syscalls like select(2), poll(2), kevent(2).

	CAP_KQUEUE_EVENT - When set on a kqueue descriptor, the kevent(2)
		syscall can be called on this kqueue to with the eventlist
		argument set to non-NULL value; in other words the given
		kqueue descriptor can be used to monitor other descriptors.
	CAP_KQUEUE_CHANGE - When set on a kqueue descriptor, the kevent(2)
		syscall can be called on this kqueue to with the changelist
		argument set to non-NULL value; in other words it allows to
		modify events monitored with the given kqueue descriptor.

Add alias CAP_KQUEUE, which allows for both CAP_KQUEUE_EVENT and
CAP_KQUEUE_CHANGE.

Add backward compatibility define CAP_POLL_EVENT which is equal to CAP_EVENT.

Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Pawel Jakub Dawidek 2013-11-15 19:55:35 +00:00
parent 2f0e4b9e62
commit ed5848c835
5 changed files with 35 additions and 17 deletions

View File

@ -855,10 +855,17 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
cap_rights_t rights;
int i, n, nerrors, error;
error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp);
cap_rights_init(&rights);
if (nchanges > 0)
cap_rights_set(&rights, CAP_KQUEUE_CHANGE);
if (nevents > 0)
cap_rights_set(&rights, CAP_KQUEUE_EVENT);
error = fget(td, fd, &rights, &fp);
if (error != 0)
return (error);
if ((error = kqueue_acquire(fp, &kq)) != 0)
error = kqueue_acquire(fp, &kq);
if (error != 0)
goto done_norel;
nerrors = 0;
@ -1015,7 +1022,7 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa
if (fops->f_isfd) {
KASSERT(td != NULL, ("td is NULL"));
error = fget(td, kev->ident,
cap_rights_init(&rights, CAP_POLL_EVENT), &fp);
cap_rights_init(&rights, CAP_EVENT), &fp);
if (error)
goto done;
@ -2301,7 +2308,7 @@ kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok)
cap_rights_t rights;
int error;
error = fget(td, fd, cap_rights_init(&rights, CAP_POST_EVENT), &fp);
error = fget(td, fd, cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &fp);
if (error != 0)
return (error);
if ((error = kqueue_acquire(fp, &kq)) != 0)

View File

@ -1195,8 +1195,9 @@ getselfd_cap(struct filedesc *fdp, int fd, struct file **fpp)
{
cap_rights_t rights;
return (fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_POLL_EVENT),
0, fpp, NULL));
cap_rights_init(&rights, CAP_EVENT);
return (fget_unlocked(fdp, fd, &rights, 0, fpp, NULL));
}
/*
@ -1392,7 +1393,7 @@ pollrescan(struct thread *td)
#ifdef CAPABILITIES
if (fp == NULL ||
cap_check(cap_rights(fdp, fd->fd),
cap_rights_init(&rights, CAP_POLL_EVENT)) != 0)
cap_rights_init(&rights, CAP_EVENT)) != 0)
#else
if (fp == NULL)
#endif
@ -1467,7 +1468,7 @@ pollscan(td, fds, nfd)
#ifdef CAPABILITIES
if (fp == NULL ||
cap_check(cap_rights(fdp, fds->fd),
cap_rights_init(&rights, CAP_POLL_EVENT)) != 0)
cap_rights_init(&rights, CAP_EVENT)) != 0)
#else
if (fp == NULL)
#endif

View File

@ -2119,7 +2119,7 @@ getmq(struct thread *td, int fd, struct file **fpp, struct mqfs_node **ppn,
{
cap_rights_t rights;
return _getmq(td, fd, cap_rights_init(&rights, CAP_POLL_EVENT), fget,
return _getmq(td, fd, cap_rights_init(&rights, CAP_EVENT), fget,
fpp, ppn, pmq);
}
@ -2282,7 +2282,7 @@ kern_kmq_notify(struct thread *td, int mqd, struct sigevent *sigev)
}
#ifdef CAPABILITIES
error = cap_check(cap_rights(fdp, mqd),
cap_rights_init(&rights, CAP_POLL_EVENT));
cap_rights_init(&rights, CAP_EVENT));
if (error) {
FILEDESC_SUNLOCK(fdp);
goto out;

View File

@ -226,9 +226,10 @@
#define CAP_SEM_POST CAPRIGHT(1, 0x0000000000000008ULL)
#define CAP_SEM_WAIT CAPRIGHT(1, 0x0000000000000010ULL)
/* kqueue events. */
#define CAP_POLL_EVENT CAPRIGHT(1, 0x0000000000000020ULL)
#define CAP_POST_EVENT CAPRIGHT(1, 0x0000000000000040ULL)
/* Allows select(2) and poll(2) on descriptor. */
#define CAP_EVENT CAPRIGHT(1, 0x0000000000000020ULL)
/* Allows for kevent(2) on kqueue descriptor with eventlist != NULL. */
#define CAP_KQUEUE_EVENT CAPRIGHT(1, 0x0000000000000040ULL)
/* Strange and powerful rights that should not be given lightly. */
/* Allows for ioctl(2). */
@ -263,14 +264,22 @@
/* Allows for acl_set_fd(3) and acl_set_fd_np(3). */
#define CAP_ACL_SET CAPRIGHT(1, 0x0000000000080000ULL)
/* Allows for kevent(2) on kqueue descriptor with changelist != NULL. */
#define CAP_KQUEUE_CHANGE CAPRIGHT(1, 0x0000000000100000ULL)
#define CAP_KQUEUE (CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE)
/* All used bits for index 1. */
#define CAP_ALL1 CAPRIGHT(1, 0x00000000000FFFFFULL)
#define CAP_ALL1 CAPRIGHT(1, 0x00000000001FFFFFULL)
/* Available bits for index 1. */
#define CAP_UNUSED1_21 CAPRIGHT(1, 0x0000000000100000ULL)
#define CAP_UNUSED1_22 CAPRIGHT(1, 0x0000000000200000ULL)
/* ... */
#define CAP_UNUSED1_57 CAPRIGHT(1, 0x0100000000000000ULL)
/* Backward compatibility. */
#define CAP_POLL_EVENT CAP_EVENT
#define CAP_ALL(rights) do { \
(rights)->cr_rights[0] = \
((uint64_t)CAP_RIGHTS_VERSION << 62) | CAP_ALL0; \

View File

@ -203,8 +203,9 @@ static struct cap_desc {
{ CAP_SEM_WAIT, "sw" },
/* Event monitoring and posting. */
{ CAP_POLL_EVENT, "po" },
{ CAP_POST_EVENT, "ev" },
{ CAP_EVENT, "ev" },
{ CAP_KQUEUE_EVENT, "ke" },
{ CAP_KQUEUE_CHANGE, "kc" },
/* Strange and powerful rights that should not be given lightly. */
{ CAP_IOCTL, "io" },