Page MenuHomeFreeBSD

D7655.diff
No OneTemporary

D7655.diff

Index: usr.bin/uudecode/uudecode.c
===================================================================
--- usr.bin/uudecode/uudecode.c
+++ usr.bin/uudecode/uudecode.c
@@ -49,12 +49,14 @@
* create the specified file, decoding as you go.
* used with uuencode.
*/
+#include <sys/capsicum.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
+#include <capsicum_helpers.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -69,7 +71,7 @@
static const char *infile, *outfile;
static FILE *infp, *outfp;
-static int base64, cflag, iflag, oflag, pflag, rflag, sflag;
+static int base64, cflag, iflag, oflag, pflag, rflag, sflag, cwdfd;
static void usage(void);
static int decode(void);
@@ -80,8 +82,15 @@
int
main(int argc, char *argv[])
{
- int rval, ch;
+ int rval, ch, fnum, i;
+ int *infds;
+ char **infiles;
+ cap_rights_t rights_ro;
+ fnum = 0;
+ rval = 0;
+ cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_FCNTL);
+
if (strcmp(basename(argv[0]), "b64decode") == 0)
base64 = 1;
@@ -128,22 +137,57 @@
argv += optind;
if (*argv != NULL) {
- rval = 0;
+ infds = calloc(argc, sizeof(int));
+ infiles = calloc(argc, sizeof(char*));
+ if (infds == NULL || infiles == NULL)
+ errc(1, ENOMEM, "malloc() fds");
do {
- infp = fopen(infile = *argv, "r");
- if (infp == NULL) {
+ infds[fnum] = open(*argv, O_RDONLY);
+ if (infds[fnum] == -1) {
warn("%s", *argv);
rval = 1;
continue;
}
- rval |= decode();
- fclose(infp);
+ if (cap_rights_limit(infds[fnum], &rights_ro) < 0 && errno != ENOSYS)
+ err(1, "unable to limit rights on: %s", *argv);
+ if (cap_fcntls_limit(infds[fnum], CAP_FCNTL_GETFL) < 0 && errno != ENOSYS)
+ err(1, "unable to limit fcntls on: %s", *argv);
+ infiles[fnum] = *argv;
+ fnum++;
} while (*++argv);
} else {
- infile = "stdin";
- infp = stdin;
- rval = decode();
+ infds = malloc(sizeof(int));
+ infiles = malloc(sizeof(char*));
+ if (infds == NULL || infiles == NULL)
+ errc(1, ENOMEM, "malloc() fd");
+ infds[fnum] = STDIN_FILENO;
+ infiles[fnum] = strdup("stdin");
+ if (infiles[fnum] == NULL)
+ errc(1, ENOMEM, "malloc()");
+ fnum++;
}
+
+ if ((cwdfd = open(".", O_DIRECTORY)) < 0)
+ err(1, "Failed to open the working directory");
+
+ caph_cache_catpages();
+ if (caph_limit_stdio() == -1)
+ err(1, "unable to limit stdio");
+ if (cap_enter() < 0 && errno != ENOSYS)
+ err(1, "failed to enter security sandbox");
+
+ for (i = 0; i < fnum; i++) {
+ infp = fdopen(infds[i], "r");
+ if (infp == NULL)
+ err(1, "unable to open: %s", infiles[i]);
+ infile = infiles[i];
+ rval |= decode();
+ fclose(infp);
+ }
+
+ free(infds);
+ free(infiles);
+
exit(rval);
}
@@ -259,7 +303,7 @@
outfp = stdout;
else {
flags = O_WRONLY | O_CREAT | O_EXCL;
- if (lstat(outfile, &st) == 0) {
+ if (fstatat(cwdfd, outfile, &st, AT_SYMLINK_NOFOLLOW) == 0) {
if (iflag) {
warnc(EEXIST, "%s: %s", infile, outfile);
return (0);
@@ -268,7 +312,8 @@
case S_IFREG:
case S_IFLNK:
/* avoid symlink attacks */
- if (unlink(outfile) == 0 || errno == ENOENT)
+ if (unlinkat(cwdfd, outfile, 0) == 0 ||
+ errno == ENOENT)
break;
warn("%s: unlink %s", infile, outfile);
return (1);
@@ -285,12 +330,12 @@
return (1);
}
} else if (errno != ENOENT) {
- warn("%s: %s", infile, outfile);
+ warn("%s: stat %s", infile, outfile);
return (1);
}
- if ((fd = open(outfile, flags, mode)) < 0 ||
+ if ((fd = openat(cwdfd, outfile, flags, mode)) < 0 ||
(outfp = fdopen(fd, "w")) == NULL) {
- warn("%s: %s", infile, outfile);
+ warn("%s: open %s", infile, outfile);
return (1);
}
}

File Metadata

Mime Type
text/plain
Expires
Mon, Jun 22, 9:33 PM (9 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34213774
Default Alt Text
D7655.diff (3 KB)

Event Timeline