Page MenuHomeFreeBSD

D7734.1775693620.diff
No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None

D7734.1775693620.diff

Index: contrib/file/src/file.h
===================================================================
--- contrib/file/src/file.h
+++ contrib/file/src/file.h
@@ -33,6 +33,17 @@
#ifndef __file_h__
#define __file_h__
+#if defined(__FreeBSD__)
+#include <sys/param.h>
+#if __FreeBSD_version >= 1100014
+#include <sys/capsicum.h>
+#define HAVE_CAPSICUM
+#elif __FreeBSD_version >= 1000000
+#include <sys/capability.h>
+#define HAVE_CAPSICUM
+#endif
+#endif
+
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -439,7 +450,8 @@
protected void file_ms_free(struct magic_set *);
protected int file_buffer(struct magic_set *, int, const char *, const void *,
size_t);
-protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
+protected int file_fsmagic(struct magic_set *, const char *, struct stat *,
+ int);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_vprintf(struct magic_set *, const char *, va_list)
__attribute__((__format__(__printf__, 2, 0)));
Index: contrib/file/src/file.c
===================================================================
--- contrib/file/src/file.c
+++ contrib/file/src/file.c
@@ -87,6 +87,12 @@
nobuffer = 0, /* Do not buffer stdout */
nulsep = 0; /* Append '\0' to the separator */
+#ifdef HAVE_CAPSICUM
+ private int *ifds = NULL;
+ private int fcnt = 0;
+ private char **fnames = NULL;
+#endif
+
private const char *separator = ":"; /* Default field separator */
private const struct option long_options[] = {
#define OPT_HELP 1
@@ -148,8 +154,8 @@
#endif
private void help(void);
-private int unwrap(struct magic_set *, const char *);
-private int process(struct magic_set *ms, const char *, int);
+private int unwrap(struct magic_set * __unused, const char *, size_t *);
+private int process(struct magic_set *ms, const char *, int, int);
private struct magic_set *load(const char *, int);
private void setparam(const char *);
private void applyparam(magic_t);
@@ -162,12 +168,15 @@
main(int argc, char *argv[])
{
int c;
- size_t i;
+ size_t i, wid = 0;
int action = 0, didsomefiles = 0, errflg = 0;
int flags = 0, e = 0;
struct magic_set *magic = NULL;
int longindex;
const char *magicfile = NULL; /* where the magic is */
+#ifdef HAVE_CAPSICUM
+ cap_rights_t rights_ro;
+#endif
/* makes islower etc work for other langs */
#ifdef HAVE_SETLOCALE
@@ -238,11 +247,15 @@
case 'f':
if(action)
usage();
+#ifdef HAVE_CAPSICUM
+ e |= unwrap(NULL, optarg, &wid);
+#else
if (magic == NULL)
if ((magic = load(magicfile, flags)) == NULL)
return 1;
applyparam(magic);
- e |= unwrap(magic, optarg);
+ e |= unwrap(magic, optarg, &wid);
+#endif
++didsomefiles;
break;
case 'F':
@@ -365,10 +378,24 @@
if (optind == argc) {
if (!didsomefiles)
usage();
+#ifdef HAVE_CAPSICUM
+ if (cap_enter() < 0 && errno != ENOSYS) {
+ (void)fprintf(stderr, "%s: Error: failed to enter "
+ "sandbox\n", progname);
+ return 1;
+ }
+
+ /* Process file descriptions we opened earlier in unwrap_open */
+ for (c = 0; c < fcnt; c++) {
+ e |= process(magic, fnames[c], wid, ifds[c]);
+ if(nobuffer)
+ (void)fflush(stdout);
+ }
+#endif
}
else {
- size_t j, wid, nw;
- for (wid = 0, j = (size_t)optind; j < (size_t)argc; j++) {
+ size_t j, nw;
+ for (j = (size_t)optind; j < (size_t)argc; j++) {
nw = file_mbswidth(argv[j]);
if (nw > wid)
wid = nw;
@@ -380,11 +407,76 @@
if (bflag == 2) {
bflag = optind >= argc - 1;
}
- for (; optind < argc; optind++)
- e |= process(magic, argv[optind], wid);
+
+#ifdef HAVE_CAPSICUM
+ cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK);
+
+ ifds = realloc(ifds, sizeof(int) * (fcnt + argc));
+ if (ifds == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory: %s\n",
+ progname, strerror(errno));
+ return 1;
+ }
+
+ for (c = optind; c < argc; c++) {
+ if (strcmp(argv[c], "-") == 0) {
+ ifds[c + fcnt] = STDIN_FILENO;
+ continue;
+ }
+ if ((ifds[c + fcnt] = open(argv[c],
+ O_RDONLY | O_BINARY)) == -1)
+ (void)fprintf(stderr, "%s: cannot open `%s': "
+ "%s\n", progname, argv[c], strerror(errno));
+ if (cap_rights_limit(ifds[c + fcnt], &rights_ro) < 0 &&
+ errno != ENOSYS) {
+ (void)fprintf(stderr, "%s: cap_rights_limit() "
+ "failed, could not restrict capabilities\n",
+ progname);
+ return 1;
+ }
+ }
+
+ if (cap_enter() < 0 && errno != ENOSYS) {
+ (void)fprintf(stderr, "%s: Error: failed to enter "
+ "sandbox\n", progname);
+ return 1;
+ }
+
+ /* Process file descriptions we opened earlier in unwrap_open */
+ for (c = 0; c < fcnt; c++) {
+ e |= process(magic, fnames[c], wid, ifds[c]);
+ if(nobuffer)
+ (void)fflush(stdout);
+ }
+
+ /* Process files listed on the command line */
+ for (; optind < argc; optind++) {
+ e |= process(magic, argv[optind], wid,
+ ifds[optind + fcnt]);
+ if(nobuffer)
+ (void)fflush(stdout);
+ }
+#else
+ for (; optind < argc; optind++) {
+ e |= process(magic, argv[optind], wid, -1);
+ if(nobuffer)
+ (void)fflush(stdout);
+ }
+#endif
}
out:
+#ifdef HAVE_CAPSICUM
+ if (ifds != NULL)
+ free(ifds);
+ if (fnames != NULL) {
+ for (c = 0; c < fcnt; c++)
+ if (fnames[c] != NULL)
+ free(fnames[c]);
+ free(fnames);
+ }
+#endif
+
if (magic)
magic_close(magic);
return e;
@@ -448,18 +540,22 @@
* unwrap -- read a file of filenames, do each one.
*/
private int
-unwrap(struct magic_set *ms, const char *fn)
+unwrap(struct magic_set *ms __unused, const char *fn, size_t *wid)
{
FILE *f;
ssize_t len;
char *line = NULL;
- size_t llen = 0;
- int wid = 0, cwid;
+ size_t llen = 0, cwid, linecnt = 0;
int e = 0;
+#ifdef HAVE_CAPSICUM
+ cap_rights_t rights_ro;
+
+ cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK);
+#endif
if (strcmp("-", fn) == 0) {
f = stdin;
- wid = 1;
+ *wid = 1;
} else {
if ((f = fopen(fn, "r")) == NULL) {
(void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",
@@ -471,19 +567,54 @@
if (line[len - 1] == '\n')
line[len - 1] = '\0';
cwid = file_mbswidth(line);
- if (cwid > wid)
- wid = cwid;
+ if (cwid > *wid)
+ *wid = cwid;
+ linecnt++;
}
rewind(f);
}
+#ifdef HAVE_CAPSICUM
+ ifds = realloc(ifds, sizeof(int) * (fcnt + linecnt));
+ fnames = realloc(fnames, sizeof(char *) * (fcnt + linecnt));
+ if (ifds == NULL || fnames == NULL) {
+ (void)fprintf(stderr, "%s: failed to allocate memory: %s\n",
+ progname, strerror(errno));
+ exit(1);
+ }
+#endif
+
while ((len = getline(&line, &llen, f)) > 0) {
if (line[len - 1] == '\n')
line[len - 1] = '\0';
- e |= process(ms, line, wid);
+#ifdef HAVE_CAPSICUM
+ if (strcmp(line, "-") == 0) {
+ ifds[fcnt] = STDIN_FILENO;
+ } else if ((ifds[fcnt] = open(line, O_RDONLY)) == -1) {
+ (void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",
+ progname, line, strerror(errno));
+ e = 1;
+ break;
+ }
+ if ((fnames[fcnt] = strdup(line)) == NULL) {
+ (void)fprintf(stderr, "%s: failed to allocate memory: "
+ "%s\n", progname, strerror(errno));
+ exit(1);
+ }
+ if (cap_rights_limit(ifds[fcnt], &rights_ro) < 0 &&
+ errno != ENOSYS) {
+ (void)fprintf(stderr, "%s: cap_rights_limit() "
+ "failed, could not restrict capabilities\n",
+ progname);
+ exit(1);
+ }
+ fcnt++;
+#else
+ e |= process(ms, line, wid, -1);
if(nobuffer)
(void)fflush(stdout);
+#endif
}
free(line);
@@ -495,13 +626,14 @@
* Called for each input file on the command line (or in a list of files)
*/
private int
-process(struct magic_set *ms, const char *inname, int wid)
+process(struct magic_set *ms, const char *inname, int wid, int ifd)
{
const char *type, c = nulsep > 1 ? '\0' : '\n';
- int std_in = strcmp(inname, "-") == 0;
+ if (ifd == -1 && strcmp(inname, "-") == 0)
+ ifd = STDIN_FILENO;
if (wid > 0 && !bflag) {
- (void)printf("%s", std_in ? "/dev/stdin" : inname);
+ (void)printf("%s", ifd == STDIN_FILENO ? "/dev/stdin" : inname);
if (nulsep)
(void)putc('\0', stdout);
if (nulsep < 2) {
@@ -512,7 +644,10 @@
}
}
- type = magic_file(ms, std_in ? NULL : inname);
+ type = magic_file(ms, ifd == STDIN_FILENO ? NULL : inname, ifd);
+
+ if (ifd > 0)
+ close(ifd);
if (type == NULL) {
(void)printf("ERROR: %s%c", magic_error(ms), c);
Index: contrib/file/src/fsmagic.c
===================================================================
--- contrib/file/src/fsmagic.c
+++ contrib/file/src/fsmagic.c
@@ -100,7 +100,7 @@
}
protected int
-file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
+file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, int fd)
{
int ret, did = 0;
int mime = ms->flags & MAGIC_MIME;
@@ -120,13 +120,16 @@
* Fstat is cheaper but fails for files you don't have read perms on.
* On 4.2BSD and similar systems, use lstat() to identify symlinks.
*/
+#ifdef HAVE_CAPSICUM /* XXX: TODO: capsicumization breaks symlink check */
+ ret = fstat(fd, sb);
+#else
#ifdef S_IFLNK
if ((ms->flags & MAGIC_SYMLINK) == 0)
ret = lstat(fn, sb);
else
#endif
ret = stat(fn, sb); /* don't merge into if; see "ret =" above */
-
+#endif /* ifndef HAVE_CAPSICUM */
#ifdef WIN32
{
HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
@@ -344,7 +347,7 @@
if ((ms->flags & MAGIC_SYMLINK) != 0) {
const char *p;
ms->flags &= MAGIC_SYMLINK;
- p = magic_file(ms, buf);
+ p = magic_file(ms, buf, -1);
ms->flags |= MAGIC_SYMLINK;
if (p == NULL)
return -1;
Index: contrib/file/src/magic.h.in
===================================================================
--- contrib/file/src/magic.h.in
+++ contrib/file/src/magic.h.in
@@ -92,7 +92,7 @@
void magic_close(magic_t);
const char *magic_getpath(const char *, int);
-const char *magic_file(magic_t, const char *);
+const char *magic_file(magic_t, const char *, int);
const char *magic_descriptor(magic_t, int);
const char *magic_buffer(magic_t, const void *, size_t);
Index: contrib/file/src/magic.c
===================================================================
--- contrib/file/src/magic.c
+++ contrib/file/src/magic.c
@@ -392,11 +392,11 @@
* find type of named file
*/
public const char *
-magic_file(struct magic_set *ms, const char *inname)
+magic_file(struct magic_set *ms, const char *inname, int fd)
{
if (ms == NULL)
return NULL;
- return file_or_fd(ms, inname, STDIN_FILENO);
+ return file_or_fd(ms, inname, fd);
}
private const char *
@@ -420,7 +420,7 @@
if ((buf = CAST(unsigned char *, malloc(ms->bytes_max + SLOP))) == NULL)
return NULL;
- switch (file_fsmagic(ms, inname, &sb)) {
+ switch (file_fsmagic(ms, inname, &sb, fd)) {
case -1: /* error */
goto done;
case 0: /* nothing found */
@@ -441,6 +441,24 @@
ispipe = 1;
else
pos = lseek(fd, (off_t)0, SEEK_CUR);
+#ifdef HAVE_CAPSICUM
+ } else if (fd > 0 && fd != STDIN_FILENO) {
+ int flags = O_RDONLY|O_BINARY;
+ int okstat = fstat(fd, &sb) == 0;
+
+ if (okstat && S_ISFIFO(sb.st_mode)) {
+#ifdef O_NONBLOCK
+ flags |= O_NONBLOCK;
+#endif
+ ispipe = 1;
+ }
+#ifdef O_NONBLOCK
+ if ((flags = fcntl(fd, F_GETFL)) != -1) {
+ flags &= ~O_NONBLOCK;
+ (void)fcntl(fd, F_SETFL, flags);
+ }
+#endif
+#endif /* ifdef HAVE_CAPSICUM */
} else {
int flags = O_RDONLY|O_BINARY;
int okstat = stat(inname, &sb) == 0;

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 9, 12:13 AM (16 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28305151
Default Alt Text
D7734.1775693620.diff (11 KB)

Event Timeline