Page MenuHomeFreeBSD

D45567.id142410.diff
No OneTemporary

D45567.id142410.diff

diff --git a/usr.bin/wall/ttymsg.h b/usr.bin/wall/ttymsg.h
--- a/usr.bin/wall/ttymsg.h
+++ b/usr.bin/wall/ttymsg.h
@@ -1,4 +1,4 @@
#define TTYMSG_IOV_MAX 32
-const char *ttymsg(struct iovec *, int, const char *, int);
+const char *ttymsg(struct iovec *, int, int, const char *, int);
diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c
--- a/usr.bin/wall/ttymsg.c
+++ b/usr.bin/wall/ttymsg.c
@@ -30,10 +30,13 @@
*/
-
+#include <sys/procdesc.h>
#include <sys/types.h>
#include <sys/uio.h>
+
+#include <capsicum_helpers.h>
#include <dirent.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
@@ -53,15 +56,15 @@
* ignored (exclusive-use, lack of permission, etc.).
*/
const char *
-ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout)
+ttymsg(struct iovec *iov, int iovcnt, int dfd, const char *line, int tmout)
{
struct iovec localiov[TTYMSG_IOV_MAX];
ssize_t left, wret;
- int cnt, fd;
char device[MAXNAMLEN] = _PATH_DEV;
static char errbuf[1024];
char *p;
- int forked;
+ int fd, pd, cnt, forked;
+ cap_rights_t rights;
forked = 0;
if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0])))
@@ -82,7 +85,8 @@
* open will fail on slip lines or exclusive-use lines
* if not running as root; not an error.
*/
- if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
+ fd = openat(dfd, p, O_RDWR|O_NONBLOCK);
+ if (fd < 0){
if (errno == EBUSY || errno == EACCES)
return (NULL);
(void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device,
@@ -90,6 +94,10 @@
return (errbuf);
}
+ cap_rights_init(&rights, CAP_WRITE, CAP_FSTAT, CAP_FCNTL, CAP_FSTATAT);
+ if (caph_rights_limit(fd, &rights) == -1)
+ err(1, "unable to limit capability rights");
+
for (cnt = 0, left = 0; cnt < iovcnt; ++cnt)
left += iov[cnt].iov_len;
@@ -117,12 +125,11 @@
}
if (errno == EWOULDBLOCK) {
int cpid;
-
if (forked) {
(void) close(fd);
_exit(1);
}
- cpid = fork();
+ cpid = pdfork(&pd, 0);
if (cpid < 0) {
(void) snprintf(errbuf, sizeof(errbuf),
"fork: %s", strerror(errno));
@@ -155,9 +162,9 @@
"%s: %s", device, strerror(errno));
return (errbuf);
}
-
(void) close(fd);
- if (forked)
+ if (forked){
_exit(0);
+ }
return (NULL);
}
diff --git a/usr.bin/wall/wall.c b/usr.bin/wall/wall.c
--- a/usr.bin/wall/wall.c
+++ b/usr.bin/wall/wall.c
@@ -36,9 +36,12 @@
#include <sys/param.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <sys/uio.h>
+#include <capsicum_helpers.h>
#include <ctype.h>
+#include <dirent.h>
#include <err.h>
#include <grp.h>
#include <locale.h>
@@ -68,13 +71,21 @@
static char *mbuf;
static int
-ttystat(char *line)
+ttystat(char *line, int dfd)
{
struct stat sb;
char ttybuf[MAXPATHLEN];
+ int fd;
+ char *p;
+ char device[MAXNAMLEN] = _PATH_DEV;
+ strlcat(device, line, sizeof(device));
+ p = device + sizeof(_PATH_DEV) - 1;
+ if (strncmp(p, "pts/", 4) == 0)
+ p += 4;
(void)snprintf(ttybuf, sizeof(ttybuf), "%s%s", _PATH_DEV, line);
- if (stat(ttybuf, &sb) == 0) {
+ fd = openat(dfd, p, O_RDONLY);
+ if (fstat(fd, &sb) == 0) {
return (0);
} else
return (-1);
@@ -92,9 +103,20 @@
char **np;
const char *p;
struct passwd *pw;
+ int devfd;
(void)setlocale(LC_CTYPE, "");
+ /*
+ * Cache NLS data, for strerror, for err(3), before entering capability
+ * mode.
+ */
+ caph_cache_catpages();
+ caph_cache_tzdata();
+ setutxent();
+ devfd = open("/dev/pts/", O_RDONLY|O_NONBLOCK,0);
+ if (devfd < 0)
+ err(1, "open(/dev/pts)");
while ((ch = getopt(argc, argv, "g:n")) != -1)
switch (ch) {
case 'n':
@@ -134,7 +156,7 @@
while ((utmp = getutxent()) != NULL) {
if (utmp->ut_type != USER_PROCESS)
continue;
- if (ttystat(utmp->ut_line) != 0)
+ if (ttystat(utmp->ut_line, devfd) != 0)
continue;
if (grouplist) {
ingroup = 0;
@@ -158,9 +180,10 @@
if (ingroup == 0)
continue;
}
- if ((p = ttymsg(&iov, 1, utmp->ut_line, 60*5)) != NULL)
+ if ((p = ttymsg(&iov, 1, devfd, utmp->ut_line, 60*5)) != NULL)
warnx("%s", p);
}
+ (void)close(devfd);
exit(0);
}
@@ -187,12 +210,29 @@
const char *tty;
const char *whom;
gid_t egid;
+ cap_rights_t rights;
(void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP);
if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+")))
err(1, "can't open temporary file");
(void)unlink(tmpname);
+ cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ,
+ CAP_SEEK, CAP_WRITE);
+ if (caph_rights_limit(fd, &rights) == -1)
+ err(1, "unable to limit capability rights");
+ if (fname) {
+ egid = getegid();
+ setegid(getgid());
+ if (freopen(fname, "r", stdin) == NULL)
+ err(1, "can't read %s", fname);
+ if (setegid(egid) != 0)
+ err(1, "setegid failed");
+ }
+
+ if (caph_enter() < 0)
+ err(1, "unable to enter capability mode");
+
if (!nobanner) {
tty = ttyname(STDERR_FILENO);
if (tty == NULL)
@@ -223,14 +263,6 @@
}
(void)fwprintf(fp, L"%79s\r\n", " ");
- if (fname) {
- egid = getegid();
- setegid(getgid());
- if (freopen(fname, "r", stdin) == NULL)
- err(1, "can't read %s", fname);
- if (setegid(egid) != 0)
- err(1, "setegid failed");
- }
cnt = 0;
while (fgetws(lbuf, sizeof(lbuf)/sizeof(wchar_t), stdin)) {
for (p = lbuf; (ch = *p) != L'\0'; ++p, ++cnt) {

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 20, 3:46 PM (1 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27098533
Default Alt Text
D45567.id142410.diff (5 KB)

Event Timeline