mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MFp4 @229086:
Make use of Capsicum to protect kdump(1), as it might be used to parse data
from untrusted sources:
- Sandbox kdump(1) using capability mode.
- Limit stdin descriptor (where opened file is moved to) to only
CAP_READ and CAP_FSTAT rights.
- Limit stdout descriptor to only CAP_WRITE, CAP_FSTAT and CAP_IOCTL.
Plus limit allowed ioctls to TIOCGETA only, which is needed for
isatty() to work.
- Limit stderr descriptor to only CAP_WRITE and CAP_FSTAT. In addition
if the -s option is not given, grant CAP_IOCTL right, but allow for
TIOCGWINSZ ioctl only, as we need screen width to dump the data.
- Before entering capability mode call catopen("libc", NL_CAT_LOCALE),
which opens message catalogs and caches data, so that strerror(3)
and strsignal(3) can work in a sandbox.
Sponsored by: The FreeBSD Foundation
Discussed with: rwatson
This commit is contained in:
parent
4b0ae51212
commit
f9b20fc804
1 changed files with 50 additions and 0 deletions
|
|
@ -46,6 +46,7 @@ extern int errno;
|
|||
#include <sys/errno.h>
|
||||
#undef _KERNEL
|
||||
#include <sys/param.h>
|
||||
#include <sys/capability.h>
|
||||
#include <sys/errno.h>
|
||||
#define _KERNEL
|
||||
#include <sys/time.h>
|
||||
|
|
@ -73,10 +74,12 @@ extern int errno;
|
|||
#include <grp.h>
|
||||
#include <inttypes.h>
|
||||
#include <locale.h>
|
||||
#include <nl_types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <vis.h>
|
||||
|
|
@ -105,6 +108,7 @@ void ktrstruct(char *, size_t);
|
|||
void ktrcapfail(struct ktr_cap_fail *);
|
||||
void ktrfault(struct ktr_fault *);
|
||||
void ktrfaultend(struct ktr_faultend *);
|
||||
void limitfd(int fd);
|
||||
void usage(void);
|
||||
void ioctlname(unsigned long, int);
|
||||
|
||||
|
|
@ -230,6 +234,18 @@ main(int argc, char *argv[])
|
|||
errx(1, "%s", strerror(ENOMEM));
|
||||
if (!freopen(tracefile, "r", stdin))
|
||||
err(1, "%s", tracefile);
|
||||
|
||||
/*
|
||||
* Cache NLS data before entering capability mode.
|
||||
* XXXPJD: There should be strerror_init() and strsignal_init() in libc.
|
||||
*/
|
||||
(void)catopen("libc", NL_CAT_LOCALE);
|
||||
if (cap_enter() < 0 && errno != ENOSYS)
|
||||
err(1, "unable to enter capability mode");
|
||||
limitfd(STDIN_FILENO);
|
||||
limitfd(STDOUT_FILENO);
|
||||
limitfd(STDERR_FILENO);
|
||||
|
||||
TAILQ_INIT(&trace_procs);
|
||||
drop_logged = 0;
|
||||
while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
|
||||
|
|
@ -331,6 +347,40 @@ main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
limitfd(int fd)
|
||||
{
|
||||
cap_rights_t rights;
|
||||
unsigned long cmd;
|
||||
|
||||
rights = CAP_FSTAT;
|
||||
cmd = -1;
|
||||
|
||||
switch (fd) {
|
||||
case STDIN_FILENO:
|
||||
rights |= CAP_READ;
|
||||
break;
|
||||
case STDOUT_FILENO:
|
||||
rights |= CAP_IOCTL | CAP_WRITE;
|
||||
cmd = TIOCGETA; /* required by isatty(3) in printf(3) */
|
||||
break;
|
||||
case STDERR_FILENO:
|
||||
rights |= CAP_WRITE;
|
||||
if (!suppressdata) {
|
||||
rights |= CAP_IOCTL;
|
||||
cmd = TIOCGWINSZ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)
|
||||
err(1, "unable to limit rights for descriptor %d", fd);
|
||||
if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
|
||||
err(1, "unable to limit ioctls for descriptor %d", fd);
|
||||
}
|
||||
|
||||
int
|
||||
fread_tail(void *buf, int size, int num)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue