Messages in this thread Patch in this message | | | Date | Sat, 14 Jul 2012 03:27:50 +0100 | From | Aaron Jones <> | Subject | [PATCH] New capability CAP_RND_ADD for solely allowing addition of entropy |
| |
I was interested in modifying haveged to drop privileges after opening /dev/random but discovered this was not possible because it uses the ioctl RNDADDENTROPY which requires CAP_SYS_ADMIN.
Retaining CAP_SYS_ADMIN after dropping GID/UID would defeat the point of doing so, so this program must always run with UID 0 and/or CAP_SYS_ADMIN, which is undesirable.
I attach a patch to add a new capability CAP_RND_ADD, which allows the use of ioctls RNDADDENTROPY and RNDADDTOENTCNT. It further modifies drivers/char/random.c to also check for this capability before returning -EPERM.
==================
--- a/drivers/char/random.c 2012-07-14 02:52:10.781202854 +0100 +++ b/drivers/char/random.c 2012-07-14 02:52:55.369201089 +0100 @@ -1154,14 +1154,14 @@ return -EFAULT; return 0; case RNDADDTOENTCNT: - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_RND_ADD)) return -EPERM; if (get_user(ent_count, p)) return -EFAULT; credit_entropy_bits(&input_pool, ent_count); return 0; case RNDADDENTROPY: - if (!capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_RND_ADD)) return -EPERM; if (get_user(ent_count, p++)) return -EFAULT; --- a/include/linux/capability.h 2012-07-14 03:15:52.378624902 +0100 +++ b/include/linux/capability.h 2012-07-14 03:16:47.508624928 +0100 @@ -364,7 +364,18 @@
#define CAP_EPOLLWAKEUP 36
-#define CAP_LAST_CAP CAP_EPOLLWAKEUP +/* Allow adding of random entropy and updating entropy estimate, + but not clearing the entropy pool (see drivers/char/random.c) + Introduced so that software like haveged can drop gid/uid + on startup and drop all capabilities except this one. + Otherwise it would require CAP_SYS_ADMIN, which would + defeat the point of dropping gid/uid. */ + +#define CAP_RND_ADD 37 + + + +#define CAP_LAST_CAP CAP_RND_ADD
#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
| |