Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144603699
D7734.1775693620.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D7734.1775693620.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D7734: First pass at capsicumizing file(1)
Attached
Detach File
Event Timeline
Log In to Comment