summaryrefslogtreecommitdiffstats
path: root/contrib/file/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/file/src')
-rw-r--r--contrib/file/src/apprentice.c192
-rw-r--r--contrib/file/src/cdf.c344
-rw-r--r--contrib/file/src/cdf.h6
-rw-r--r--contrib/file/src/cdf_time.c4
-rw-r--r--contrib/file/src/compress.c17
-rw-r--r--contrib/file/src/der.c42
-rw-r--r--contrib/file/src/file.h16
-rw-r--r--contrib/file/src/fsmagic.c19
-rw-r--r--contrib/file/src/funcs.c10
-rw-r--r--contrib/file/src/is_tar.c37
-rw-r--r--contrib/file/src/magic.c17
-rw-r--r--contrib/file/src/magic.h.in30
-rw-r--r--contrib/file/src/print.c4
-rw-r--r--contrib/file/src/readcdf.c10
-rw-r--r--contrib/file/src/readelf.c121
-rw-r--r--contrib/file/src/readelf.h34
-rw-r--r--contrib/file/src/softmagic.c31
-rw-r--r--contrib/file/src/vasprintf.c4
18 files changed, 629 insertions, 309 deletions
diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c
index f2622c0..a7b4dd8 100644
--- a/contrib/file/src/apprentice.c
+++ b/contrib/file/src/apprentice.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.255 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.262 2017/08/28 13:39:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -549,8 +549,10 @@ apprentice_unmap(struct magic_map *map)
break;
case MAP_TYPE_MALLOC:
for (i = 0; i < MAGIC_SETS; i++) {
- if ((char *)map->magic[i] >= (char *)map->p &&
- (char *)map->magic[i] <= (char *)map->p + map->len)
+ void *b = map->magic[i];
+ void *p = map->p;
+ if (CAST(char *, b) >= CAST(char *, p) &&
+ CAST(char *, b) <= CAST(char *, p) + map->len)
continue;
free(map->magic[i]);
}
@@ -610,8 +612,7 @@ buffer_apprentice(struct magic_set *ms, struct magic **bufs,
if (nbufs == 0)
return -1;
- if (ms->mlist[0] != NULL)
- file_reset(ms);
+ (void)file_reset(ms, 0);
init_file_tables();
@@ -654,8 +655,7 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
int file_err, errs = -1;
size_t i;
- if (ms->mlist[0] != NULL)
- file_reset(ms);
+ (void)file_reset(ms, 0);
if ((fn = magic_getpath(fn, action)) == NULL)
return -1;
@@ -777,6 +777,59 @@ nonmagic(const char *str)
return rv == 0 ? 1 : rv; /* Return at least 1 */
}
+
+private size_t
+typesize(int type)
+{
+ switch (type) {
+ case FILE_BYTE:
+ return 1;
+
+ case FILE_SHORT:
+ case FILE_LESHORT:
+ case FILE_BESHORT:
+ return 2;
+
+ case FILE_LONG:
+ case FILE_LELONG:
+ case FILE_BELONG:
+ case FILE_MELONG:
+ return 4;
+
+ case FILE_DATE:
+ case FILE_LEDATE:
+ case FILE_BEDATE:
+ case FILE_MEDATE:
+ case FILE_LDATE:
+ case FILE_LELDATE:
+ case FILE_BELDATE:
+ case FILE_MELDATE:
+ case FILE_FLOAT:
+ case FILE_BEFLOAT:
+ case FILE_LEFLOAT:
+ return 4;
+
+ case FILE_QUAD:
+ case FILE_BEQUAD:
+ case FILE_LEQUAD:
+ case FILE_QDATE:
+ case FILE_LEQDATE:
+ case FILE_BEQDATE:
+ case FILE_QLDATE:
+ case FILE_LEQLDATE:
+ case FILE_BEQLDATE:
+ case FILE_QWDATE:
+ case FILE_LEQWDATE:
+ case FILE_BEQWDATE:
+ case FILE_DOUBLE:
+ case FILE_BEDOUBLE:
+ case FILE_LEDOUBLE:
+ return 8;
+ default:
+ return (size_t)~0;
+ }
+}
+
/*
* Get weight of this magic entry, for sorting purposes.
*/
@@ -784,7 +837,7 @@ private size_t
apprentice_magic_strength(const struct magic *m)
{
#define MULT 10
- size_t v, val = 2 * MULT; /* baseline strength */
+ size_t ts, v, val = 2 * MULT; /* baseline strength */
switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */
@@ -793,41 +846,13 @@ apprentice_magic_strength(const struct magic *m)
return 0;
case FILE_BYTE:
- val += 1 * MULT;
- break;
-
case FILE_SHORT:
case FILE_LESHORT:
case FILE_BESHORT:
- val += 2 * MULT;
- break;
-
case FILE_LONG:
case FILE_LELONG:
case FILE_BELONG:
case FILE_MELONG:
- val += 4 * MULT;
- break;
-
- case FILE_PSTRING:
- case FILE_STRING:
- val += m->vallen * MULT;
- break;
-
- case FILE_BESTRING16:
- case FILE_LESTRING16:
- val += m->vallen * MULT / 2;
- break;
-
- case FILE_SEARCH:
- val += m->vallen * MAX(MULT / m->vallen, 1);
- break;
-
- case FILE_REGEX:
- v = nonmagic(m->value.s);
- val += v * MAX(MULT / v, 1);
- break;
-
case FILE_DATE:
case FILE_LEDATE:
case FILE_BEDATE:
@@ -839,9 +864,6 @@ apprentice_magic_strength(const struct magic *m)
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
- val += 4 * MULT;
- break;
-
case FILE_QUAD:
case FILE_BEQUAD:
case FILE_LEQUAD:
@@ -857,7 +879,29 @@ apprentice_magic_strength(const struct magic *m)
case FILE_DOUBLE:
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
- val += 8 * MULT;
+ ts = typesize(m->type);
+ if (ts == (size_t)~0)
+ abort();
+ val += ts * MULT;
+ break;
+
+ case FILE_PSTRING:
+ case FILE_STRING:
+ val += m->vallen * MULT;
+ break;
+
+ case FILE_BESTRING16:
+ case FILE_LESTRING16:
+ val += m->vallen * MULT / 2;
+ break;
+
+ case FILE_SEARCH:
+ val += m->vallen * MAX(MULT / m->vallen, 1);
+ break;
+
+ case FILE_REGEX:
+ v = nonmagic(m->value.s);
+ val += v * MAX(MULT / v, 1);
break;
case FILE_INDIRECT:
@@ -1314,6 +1358,8 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
goto out;
}
while ((d = readdir(dir)) != NULL) {
+ if (d->d_name[0] == '.')
+ continue;
if (asprintf(&mfn, "%s/%s", fn, d->d_name) < 0) {
file_oomem(ms,
strlen(fn) + strlen(d->d_name) + 2);
@@ -2291,7 +2337,7 @@ parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line)
return parse_extra(ms, me, line,
CAST(off_t, offsetof(struct magic, ext)),
- sizeof(m->ext), "EXTENSION", ",!+-/", 0);
+ sizeof(m->ext), "EXTENSION", ",!+-/@", 0);
}
/*
@@ -2352,6 +2398,8 @@ check_format_type(const char *ptr, int type, const char **estr)
ptr++;
if (*ptr == '.')
ptr++;
+ if (*ptr == '#')
+ ptr++;
#define CHECKLEN() do { \
for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
len = len * 10 + (*ptr - '0'); \
@@ -2617,9 +2665,46 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
default:
if (m->reln != 'x') {
char *ep;
+ uint64_t ull;
errno = 0;
- m->value.q = file_signextend(ms, m,
- (uint64_t)strtoull(*p, &ep, 0));
+ ull = (uint64_t)strtoull(*p, &ep, 0);
+ m->value.q = file_signextend(ms, m, ull);
+ if (*p == ep) {
+ file_magwarn(ms, "Unparseable number `%s'", *p);
+ } else {
+ size_t ts = typesize(m->type);
+ uint64_t x;
+ const char *q;
+
+ if (ts == (size_t)~0) {
+ file_magwarn(ms, "Expected numeric type got `%s'",
+ type_tbl[m->type].name);
+ }
+ for (q = *p; isspace((unsigned char)*q); q++)
+ continue;
+ if (*q == '-')
+ ull = -(int64_t)ull;
+ switch (ts) {
+ case 1:
+ x = ull & ~0xffULL;
+ break;
+ case 2:
+ x = ull & ~0xffffULL;
+ break;
+ case 4:
+ x = ull & ~0xffffffffULL;
+ break;
+ case 8:
+ x = 0;
+ break;
+ default:
+ abort();
+ }
+ if (x) {
+ file_magwarn(ms, "Overflow for numeric type `%s' value %#" PRIx64,
+ type_tbl[m->type].name, ull);
+ }
+ }
if (errno == 0) {
*p = ep;
eatsize(p);
@@ -3271,22 +3356,35 @@ file_pstring_get_length(const struct magic *m, const char *ss)
{
size_t len = 0;
const unsigned char *s = (const unsigned char *)ss;
+ unsigned int s3, s2, s1, s0;
switch (m->str_flags & PSTRING_LEN) {
case PSTRING_1_LE:
len = *s;
break;
case PSTRING_2_LE:
- len = (s[1] << 8) | s[0];
+ s0 = s[0];
+ s1 = s[1];
+ len = (s1 << 8) | s0;
break;
case PSTRING_2_BE:
- len = (s[0] << 8) | s[1];
+ s0 = s[0];
+ s1 = s[1];
+ len = (s0 << 8) | s1;
break;
case PSTRING_4_LE:
- len = (s[3] << 24) | (s[2] << 16) | (s[1] << 8) | s[0];
+ s0 = s[0];
+ s1 = s[1];
+ s2 = s[2];
+ s3 = s[3];
+ len = (s3 << 24) | (s2 << 16) | (s1 << 8) | s0;
break;
case PSTRING_4_BE:
- len = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+ s0 = s[0];
+ s1 = s[1];
+ s2 = s[2];
+ s3 = s[3];
+ len = (s0 << 24) | (s1 << 16) | (s2 << 8) | s3;
break;
default:
abort(); /* Impossible */
diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c
index d38e793..accfb32 100644
--- a/contrib/file/src/cdf.c
+++ b/contrib/file/src/cdf.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.85 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.106 2017/04/30 17:05:02 christos Exp $")
#endif
#include <assert.h>
@@ -80,6 +80,34 @@ static union {
CDF_TOLE8(CAST(uint64_t, x))))
#define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
+#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
+#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
+#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
+
+
+static void *
+cdf_malloc(const char *file __attribute__((__unused__)),
+ size_t line __attribute__((__unused__)), size_t n)
+{
+ DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ return malloc(n);
+}
+
+static void *
+cdf_realloc(const char *file __attribute__((__unused__)),
+ size_t line __attribute__((__unused__)), void *p, size_t n)
+{
+ DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ return realloc(p, n);
+}
+
+static void *
+cdf_calloc(const char *file __attribute__((__unused__)),
+ size_t line __attribute__((__unused__)), size_t n, size_t u)
+{
+ DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u));
+ return calloc(n, u);
+}
/*
* swap a short
@@ -340,18 +368,18 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
cdf_unpack_header(h, buf);
cdf_swap_header(h);
if (h->h_magic != CDF_MAGIC) {
- DPRINTF(("Bad magic 0x%" INT64_T_FORMAT "x != 0x%"
+ DPRINTF(("Bad magic %#" INT64_T_FORMAT "x != %#"
INT64_T_FORMAT "x\n",
(unsigned long long)h->h_magic,
(unsigned long long)CDF_MAGIC));
goto out;
}
if (h->h_sec_size_p2 > 20) {
- DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2));
+ DPRINTF(("Bad sector size %hu\n", h->h_sec_size_p2));
goto out;
}
if (h->h_short_sec_size_p2 > 20) {
- DPRINTF(("Bad short sector size 0x%u\n",
+ DPRINTF(("Bad short sector size %hu\n",
h->h_short_sec_size_p2));
goto out;
}
@@ -408,7 +436,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
if (h->h_master_sat[i] == CDF_SECID_FREE)
break;
-#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss))
+#define CDF_SEC_LIMIT (UINT32_MAX / (8 * ss))
if ((nsatpersec > 0 &&
h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) ||
i > CDF_SEC_LIMIT) {
@@ -421,7 +449,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i;
DPRINTF(("sat_len = %" SIZE_T_FORMAT "u ss = %" SIZE_T_FORMAT "u\n",
sat->sat_len, ss));
- if ((sat->sat_tab = CAST(cdf_secid_t *, calloc(sat->sat_len, ss)))
+ if ((sat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(sat->sat_len, ss)))
== NULL)
return -1;
@@ -435,7 +463,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
}
}
- if ((msa = CAST(cdf_secid_t *, calloc(1, ss))) == NULL)
+ if ((msa = CAST(cdf_secid_t *, CDF_CALLOC(1, ss))) == NULL)
goto out1;
mid = h->h_secid_first_sector_in_master_sat;
@@ -527,13 +555,16 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
ssize_t nr;
scn->sst_tab = NULL;
scn->sst_len = cdf_count_chain(sat, sid, ss);
- scn->sst_dirlen = len;
+ scn->sst_dirlen = MAX(h->h_min_size_standard_stream, len);
scn->sst_ss = ss;
+ if (sid == CDF_SECID_END_OF_CHAIN || len == 0)
+ return cdf_zero_stream(scn);
+
if (scn->sst_len == (size_t)-1)
goto out;
- scn->sst_tab = calloc(scn->sst_len, ss);
+ scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
if (scn->sst_tab == NULL)
return cdf_zero_stream(scn);
@@ -579,7 +610,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
if (scn->sst_len == (size_t)-1)
goto out;
- scn->sst_tab = calloc(scn->sst_len, ss);
+ scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
if (scn->sst_tab == NULL)
return cdf_zero_stream(scn);
@@ -637,11 +668,11 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
dir->dir_len = ns * nd;
dir->dir_tab = CAST(cdf_directory_t *,
- calloc(dir->dir_len, sizeof(dir->dir_tab[0])));
+ CDF_CALLOC(dir->dir_len, sizeof(dir->dir_tab[0])));
if (dir->dir_tab == NULL)
return -1;
- if ((buf = CAST(char *, malloc(ss))) == NULL) {
+ if ((buf = CAST(char *, CDF_MALLOC(ss))) == NULL) {
free(dir->dir_tab);
return -1;
}
@@ -687,7 +718,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
if (ssat->sat_len == (size_t)-1)
goto out;
- ssat->sat_tab = CAST(cdf_secid_t *, calloc(ssat->sat_len, ss));
+ ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss));
if (ssat->sat_tab == NULL)
goto out1;
@@ -808,13 +839,107 @@ cdf_find_stream(const cdf_dir_t *dir, const char *name, int type)
== 0)
break;
if (i > 0)
- return i;
+ return CAST(int, i);
DPRINTF(("Cannot find type %d `%s'\n", type, name));
errno = ESRCH;
return 0;
}
+#define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
+#define CDF_PROP_LIMIT (UINT32_MAX / (8 * sizeof(cdf_property_info_t)))
+
+static const void *
+cdf_offset(const void *p, size_t l)
+{
+ return CAST(const void *, CAST(const uint8_t *, p) + l);
+}
+
+static const uint8_t *
+cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
+ const uint8_t *p, const uint8_t *e, size_t i)
+{
+ size_t tail = (i << 1) + 1;
+ size_t ofs;
+ const uint8_t *q;
+
+ if (p >= e) {
+ DPRINTF(("Past end %p < %p\n", e, p));
+ return NULL;
+ }
+ if (cdf_check_stream_offset(sst, h, p, (tail + 1) * sizeof(uint32_t),
+ __LINE__) == -1)
+ return NULL;
+ ofs = CDF_GETUINT32(p, tail);
+ q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
+ ofs - 2 * sizeof(uint32_t)));
+
+ if (q < p) {
+ DPRINTF(("Wrapped around %p < %p\n", q, p));
+ return NULL;
+ }
+
+ if (q >= e) {
+ DPRINTF(("Ran off the end %p >= %p\n", q, e));
+ return NULL;
+ }
+ return q;
+}
+
+static cdf_property_info_t *
+cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr)
+{
+ cdf_property_info_t *inp;
+ size_t newcount = *maxcount + incr;
+
+ if (newcount > CDF_PROP_LIMIT) {
+ DPRINTF(("exceeded property limit %zu > %zu\n",
+ newcount, CDF_PROP_LIMIT));
+ goto out;
+ }
+ inp = CAST(cdf_property_info_t *,
+ CDF_REALLOC(*info, newcount * sizeof(*inp)));
+ if (inp == NULL)
+ goto out;
+
+ *info = inp;
+ *maxcount = newcount;
+ return inp;
+out:
+ free(*info);
+ *maxcount = 0;
+ *info = NULL;
+ return NULL;
+}
+
+static int
+cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e,
+ size_t len)
+{
+ if (inp->pi_type & CDF_VECTOR)
+ return 0;
+
+ if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len)
+ return 0;
+
+ (void)memcpy(&inp->pi_val, p, len);
+
+ switch (len) {
+ case 2:
+ inp->pi_u16 = CDF_TOLE2(inp->pi_u16);
+ break;
+ case 4:
+ inp->pi_u32 = CDF_TOLE4(inp->pi_u32);
+ break;
+ case 8:
+ inp->pi_u64 = CDF_TOLE8(inp->pi_u64);
+ break;
+ default:
+ abort();
+ }
+ return 1;
+}
+
int
cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
uint32_t offs, cdf_property_info_t **info, size_t *count, size_t *maxcount)
@@ -822,92 +947,69 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
const cdf_section_header_t *shp;
cdf_section_header_t sh;
const uint8_t *p, *q, *e;
- int16_t s16;
- int32_t s32;
- uint32_t u32;
- int64_t s64;
- uint64_t u64;
- cdf_timestamp_t tp;
- size_t i, o, o4, nelements, j;
+ size_t i, o4, nelements, j, slen, left;
cdf_property_info_t *inp;
if (offs > UINT32_MAX / 4) {
errno = EFTYPE;
goto out;
}
- shp = CAST(const cdf_section_header_t *, (const void *)
- ((const char *)sst->sst_tab + offs));
+ shp = CAST(const cdf_section_header_t *,
+ cdf_offset(sst->sst_tab, offs));
if (cdf_check_stream_offset(sst, h, shp, sizeof(*shp), __LINE__) == -1)
goto out;
sh.sh_len = CDF_TOLE4(shp->sh_len);
-#define CDF_SHLEN_LIMIT (UINT32_MAX / 8)
if (sh.sh_len > CDF_SHLEN_LIMIT) {
errno = EFTYPE;
goto out;
}
- sh.sh_properties = CDF_TOLE4(shp->sh_properties);
-#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp)))
- if (sh.sh_properties > CDF_PROP_LIMIT)
+
+ if (cdf_check_stream_offset(sst, h, shp, sh.sh_len, __LINE__) == -1)
goto out;
+
+ sh.sh_properties = CDF_TOLE4(shp->sh_properties);
DPRINTF(("section len: %u properties %u\n", sh.sh_len,
sh.sh_properties));
- if (*maxcount) {
- if (*maxcount > CDF_PROP_LIMIT)
- goto out;
- *maxcount += sh.sh_properties;
- inp = CAST(cdf_property_info_t *,
- realloc(*info, *maxcount * sizeof(*inp)));
- } else {
- *maxcount = sh.sh_properties;
- inp = CAST(cdf_property_info_t *,
- malloc(*maxcount * sizeof(*inp)));
- }
+ if (sh.sh_properties > CDF_PROP_LIMIT)
+ goto out;
+ inp = cdf_grow_info(info, maxcount, sh.sh_properties);
if (inp == NULL)
- goto out1;
- *info = inp;
+ goto out;
inp += *count;
*count += sh.sh_properties;
- p = CAST(const uint8_t *, (const void *)
- ((const char *)(const void *)sst->sst_tab +
- offs + sizeof(sh)));
- e = CAST(const uint8_t *, (const void *)
- (((const char *)(const void *)shp) + sh.sh_len));
- if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
+ p = CAST(const uint8_t *, cdf_offset(sst->sst_tab, offs + sizeof(sh)));
+ e = CAST(const uint8_t *, cdf_offset(shp, sh.sh_len));
+ if (p >= e || cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
goto out;
+
for (i = 0; i < sh.sh_properties; i++) {
- size_t tail = (i << 1) + 1;
- size_t ofs;
- if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t),
- __LINE__) == -1)
- goto out;
- ofs = CDF_GETUINT32(p, tail);
- q = (const uint8_t *)(const void *)
- ((const char *)(const void *)p + ofs
- - 2 * sizeof(uint32_t));
- if (q < p) {
- DPRINTF(("Wrapped around %p < %p\n", q, p));
+ if ((q = cdf_get_property_info_pos(sst, h, p, e, i)) == NULL)
goto out;
- }
- if (q > e) {
- DPRINTF(("Ran of the end %p > %p\n", q, e));
+ inp[i].pi_id = CDF_GETUINT32(p, i << 1);
+ left = CAST(size_t, e - q);
+ if (left < sizeof(uint32_t)) {
+ DPRINTF(("short info (no type)_\n"));
goto out;
}
- inp[i].pi_id = CDF_GETUINT32(p, i << 1);
inp[i].pi_type = CDF_GETUINT32(q, 0);
- DPRINTF(("%" SIZE_T_FORMAT "u) id=%x type=%x offs=0x%tx,0x%x\n",
+ DPRINTF(("%" SIZE_T_FORMAT "u) id=%#x type=%#x offs=%#tx,%#x\n",
i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
if (inp[i].pi_type & CDF_VECTOR) {
+ if (left < sizeof(uint32_t) * 2) {
+ DPRINTF(("missing CDF_VECTOR length\n"));
+ goto out;
+ }
nelements = CDF_GETUINT32(q, 1);
if (nelements == 0) {
DPRINTF(("CDF_VECTOR with nelements == 0\n"));
goto out;
}
- o = 2;
+ slen = 2;
} else {
nelements = 1;
- o = 1;
+ slen = 1;
}
- o4 = o * sizeof(uint32_t);
+ o4 = slen * sizeof(uint32_t);
if (inp[i].pi_type & (CDF_ARRAY|CDF_BYREF|CDF_RESERVED))
goto unknown;
switch (inp[i].pi_type & CDF_TYPEMASK) {
@@ -915,109 +1017,83 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
case CDF_EMPTY:
break;
case CDF_SIGNED16:
- if (inp[i].pi_type & CDF_VECTOR)
+ if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int16_t)))
goto unknown;
- (void)memcpy(&s16, &q[o4], sizeof(s16));
- inp[i].pi_s16 = CDF_TOLE2(s16);
break;
case CDF_SIGNED32:
- if (inp[i].pi_type & CDF_VECTOR)
- goto unknown;
- (void)memcpy(&s32, &q[o4], sizeof(s32));
- inp[i].pi_s32 = CDF_TOLE4((uint32_t)s32);
- break;
case CDF_BOOL:
case CDF_UNSIGNED32:
- if (inp[i].pi_type & CDF_VECTOR)
+ case CDF_FLOAT:
+ if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int32_t)))
goto unknown;
- (void)memcpy(&u32, &q[o4], sizeof(u32));
- inp[i].pi_u32 = CDF_TOLE4(u32);
break;
case CDF_SIGNED64:
- if (inp[i].pi_type & CDF_VECTOR)
- goto unknown;
- (void)memcpy(&s64, &q[o4], sizeof(s64));
- inp[i].pi_s64 = CDF_TOLE8((uint64_t)s64);
- break;
case CDF_UNSIGNED64:
- if (inp[i].pi_type & CDF_VECTOR)
- goto unknown;
- (void)memcpy(&u64, &q[o4], sizeof(u64));
- inp[i].pi_u64 = CDF_TOLE8((uint64_t)u64);
- break;
- case CDF_FLOAT:
- if (inp[i].pi_type & CDF_VECTOR)
- goto unknown;
- (void)memcpy(&u32, &q[o4], sizeof(u32));
- u32 = CDF_TOLE4(u32);
- memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f));
- break;
case CDF_DOUBLE:
- if (inp[i].pi_type & CDF_VECTOR)
+ case CDF_FILETIME:
+ if (!cdf_copy_info(&inp[i], &q[o4], e, sizeof(int64_t)))
goto unknown;
- (void)memcpy(&u64, &q[o4], sizeof(u64));
- u64 = CDF_TOLE8((uint64_t)u64);
- memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d));
break;
case CDF_LENGTH32_STRING:
case CDF_LENGTH32_WSTRING:
if (nelements > 1) {
size_t nelem = inp - *info;
- if (*maxcount > CDF_PROP_LIMIT
- || nelements > CDF_PROP_LIMIT)
- goto out;
- *maxcount += nelements;
- inp = CAST(cdf_property_info_t *,
- realloc(*info, *maxcount * sizeof(*inp)));
+ inp = cdf_grow_info(info, maxcount, nelements);
if (inp == NULL)
- goto out1;
- *info = inp;
- inp = *info + nelem;
+ goto out;
+ inp += nelem;
}
DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n",
nelements));
for (j = 0; j < nelements && i < sh.sh_properties;
j++, i++)
{
- uint32_t l = CDF_GETUINT32(q, o);
+ uint32_t l;
+
+ if (o4 + sizeof(uint32_t) > left)
+ goto out;
+
+ l = CDF_GETUINT32(q, slen);
+ o4 += sizeof(uint32_t);
+ if (o4 + l > left)
+ goto out;
+
inp[i].pi_str.s_len = l;
- inp[i].pi_str.s_buf = (const char *)
- (const void *)(&q[o4 + sizeof(l)]);
- DPRINTF(("l = %d, r = %" SIZE_T_FORMAT
- "u, s = %s\n", l,
- CDF_ROUND(l, sizeof(l)),
+ inp[i].pi_str.s_buf = CAST(const char *,
+ CAST(const void *, &q[o4]));
+
+ DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT
+ "u), t=%zu s=%s\n", o4, l,
+ CDF_ROUND(l, sizeof(l)), left,
inp[i].pi_str.s_buf));
+
if (l & 1)
l++;
- o += l >> 1;
- if (q + o >= e)
- goto out;
- o4 = o * sizeof(uint32_t);
+
+ slen += l >> 1;
+ o4 = slen * sizeof(uint32_t);
}
i--;
break;
- case CDF_FILETIME:
- if (inp[i].pi_type & CDF_VECTOR)
- goto unknown;
- (void)memcpy(&tp, &q[o4], sizeof(tp));
- inp[i].pi_tp = CDF_TOLE8((uint64_t)tp);
- break;
case CDF_CLIPBOARD:
if (inp[i].pi_type & CDF_VECTOR)
goto unknown;
break;
default:
unknown:
- DPRINTF(("Don't know how to deal with %x\n",
+ memset(&inp[i].pi_val, 0, sizeof(inp[i].pi_val));
+ DPRINTF(("Don't know how to deal with %#x\n",
inp[i].pi_type));
break;
}
}
return 0;
out:
- errno = EFTYPE;
-out1:
free(*info);
+ *info = NULL;
+ *count = 0;
+ *maxcount = 0;
+ errno = EFTYPE;
return -1;
}
@@ -1065,7 +1141,7 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst,
{
size_t ss = cdf_check_stream(sst, h);
const char *b = CAST(const char *, sst->sst_tab);
- const char *eb = b + ss * sst->sst_len;
+ const char *nb, *eb = b + ss * sst->sst_len;
size_t nr, i, j, k;
cdf_catalog_entry_t *ce;
uint16_t reclen;
@@ -1084,7 +1160,7 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst,
return -1;
nr--;
*cat = CAST(cdf_catalog_t *,
- malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce)));
+ CDF_MALLOC(sizeof(cdf_catalog_t) + nr * sizeof(*ce)));
if (*cat == NULL)
return -1;
ce = (*cat)->cat_e;
@@ -1110,7 +1186,9 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst,
cep->ce_namlen = rlen;
np = CAST(const uint16_t *, CAST(const void *, (b + 16)));
- if (RCAST(const char *, np + cep->ce_namlen) > eb) {
+ nb = CAST(const char *, CAST(const void *,
+ (np + cep->ce_namlen)));
+ if (nb > eb) {
cep->ce_namlen = 0;
break;
}
@@ -1169,7 +1247,7 @@ cdf_print_property_name(char *buf, size_t bufsiz, uint32_t p)
for (i = 0; i < __arraycount(vn); i++)
if (vn[i].v == p)
return snprintf(buf, bufsiz, "%s", vn[i].n);
- return snprintf(buf, bufsiz, "0x%x", p);
+ return snprintf(buf, bufsiz, "%#x", p);
}
int
@@ -1228,7 +1306,7 @@ cdf_dump_header(const cdf_header_t *h)
h->h_ ## b, 1 << h->h_ ## b)
DUMP("%d", revision);
DUMP("%d", version);
- DUMP("0x%x", byte_order);
+ DUMP("%#x", byte_order);
DUMP2("%d", sec_size_p2);
DUMP2("%d", short_sec_size_p2);
DUMP("%d", num_sectors_in_sat);
@@ -1322,7 +1400,7 @@ cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h,
d->d_color ? "black" : "red");
(void)fprintf(stderr, "Left child: %d\n", d->d_left_child);
(void)fprintf(stderr, "Right child: %d\n", d->d_right_child);
- (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags);
+ (void)fprintf(stderr, "Flags: %#x\n", d->d_flags);
cdf_timestamp_to_timespec(&ts, d->d_created);
(void)fprintf(stderr, "Created %s", cdf_ctime(&ts.tv_sec, buf));
cdf_timestamp_to_timespec(&ts, d->d_modified);
@@ -1415,7 +1493,7 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count)
(void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32);
break;
default:
- DPRINTF(("Don't know how to deal with %x\n",
+ DPRINTF(("Don't know how to deal with %#x\n",
info[i].pi_type));
break;
}
@@ -1434,7 +1512,7 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
(void)&h;
if (cdf_unpack_summary_info(sst, h, &ssi, &info, &count) == -1)
return;
- (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
+ (void)fprintf(stderr, "Endian: %#x\n", ssi.si_byte_order);
(void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
ssi.si_os_version >> 8);
(void)fprintf(stderr, "Os %d\n", ssi.si_os);
diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h
index 0b345ab..f2df830 100644
--- a/contrib/file/src/cdf.h
+++ b/contrib/file/src/cdf.h
@@ -127,9 +127,9 @@ typedef struct {
typedef struct {
void *sst_tab;
- size_t sst_len;
- size_t sst_dirlen;
- size_t sst_ss;
+ size_t sst_len; /* Number of sectors */
+ size_t sst_dirlen; /* Directory sector size */
+ size_t sst_ss; /* Sector size */
} cdf_stream_t;
typedef struct {
diff --git a/contrib/file/src/cdf_time.c b/contrib/file/src/cdf_time.c
index 1e572de..2bdcd2a 100644
--- a/contrib/file/src/cdf_time.c
+++ b/contrib/file/src/cdf_time.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: cdf_time.c,v 1.15 2014/05/14 23:15:42 christos Exp $")
+FILE_RCSID("@(#)$File: cdf_time.c,v 1.16 2017/03/29 15:57:48 christos Exp $")
#endif
#include <time.h>
@@ -171,7 +171,7 @@ cdf_ctime(const time_t *sec, char *buf)
char *ptr = ctime_r(sec, buf);
if (ptr != NULL)
return buf;
- (void)snprintf(buf, 26, "*Bad* 0x%16.16" INT64_T_FORMAT "x\n",
+ (void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
(long long)*sec);
return buf;
}
diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c
index 95f0955..2f789cd 100644
--- a/contrib/file/src/compress.c
+++ b/contrib/file/src/compress.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.100 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.105 2017/05/25 00:13:03 christos Exp $")
#endif
#include "magic.h"
@@ -62,7 +62,7 @@ typedef void (*sig_t)(int);
#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
-#if defined(HAVE_ZLIB_H)
+#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
#define BUILTIN_DECOMPRESS
#include <zlib.h>
#endif
@@ -83,6 +83,7 @@ int tty = -1;
/*
* The following python code is not really used because ZLIBSUPPORT is only
* defined if we have a built-in zlib, and the built-in zlib handles that.
+ * That is not true for android where we have zlib.h and not -lz.
*/
static const char zlibcode[] =
"import sys, zlib; sys.stdout.write(zlib.decompress(sys.stdin.read()))";
@@ -93,7 +94,7 @@ static int
zlibcmp(const unsigned char *buf)
{
unsigned short x = 1;
- unsigned char *s = (unsigned char *)&x;
+ unsigned char *s = CAST(unsigned char *, CAST(void *, &x));
if ((buf[0] & 0xf) != 8 || (buf[0] & 0x80) != 0)
return 0;
@@ -497,7 +498,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
z.next_in = CCAST(Bytef *, old);
z.avail_in = CAST(uint32_t, *n);
z.next_out = *newch;
- z.avail_out = bytes_max;
+ z.avail_out = CAST(unsigned int, bytes_max);
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
@@ -632,7 +633,7 @@ filter_error(unsigned char *ubuf, ssize_t n)
while (isspace((unsigned char)*p))
p++;
n = strlen(p);
- memmove(ubuf, p, n + 1);
+ memmove(ubuf, p, CAST(size_t, n + 1));
}
DPRINTF("Filter error after[[[%s]]]\n", (char *)ubuf);
if (islower(*ubuf))
@@ -688,7 +689,7 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
}
for (i = 0; i < __arraycount(fdp); i++)
- copydesc(i, fdp[i]);
+ copydesc(CAST(int, i), fdp[i]);
(void)execvp(compr[method].argv[0],
(char *const *)(intptr_t)compr[method].argv);
@@ -748,9 +749,9 @@ err:
rv = makeerror(newch, n, "Wait failed, %s", strerror(errno));
DPRINTF("Child wait return %#x\n", status);
} else if (!WIFEXITED(status)) {
- DPRINTF("Child not exited (0x%x)\n", status);
+ DPRINTF("Child not exited (%#x)\n", status);
} else if (WEXITSTATUS(status) != 0) {
- DPRINTF("Child exited (0x%d)\n", WEXITSTATUS(status));
+ DPRINTF("Child exited (%#x)\n", WEXITSTATUS(status));
}
closefd(fdp[STDIN_FILENO], 0);
diff --git a/contrib/file/src/der.c b/contrib/file/src/der.c
index 8ae638f..4e22caf 100644
--- a/contrib/file/src/der.c
+++ b/contrib/file/src/der.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.10 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.12 2017/02/10 18:14:01 christos Exp $")
#endif
#endif
@@ -159,31 +159,49 @@ gettag(const uint8_t *c, size_t *p, size_t l)
return tag;
}
+/*
+ * Read the length of a DER tag from the input.
+ *
+ * `c` is the input, `p` is an output parameter that specifies how much of the
+ * input we consumed, and `l` is the maximum input length.
+ *
+ * Returns the length, or DER_BAD if the end of the input is reached or the
+ * length exceeds the remaining input.
+ */
static uint32_t
getlength(const uint8_t *c, size_t *p, size_t l)
{
uint8_t digits, i;
size_t len;
+ int is_onebyte_result;
if (*p >= l)
return DER_BAD;
- digits = c[(*p)++];
+ /*
+ * Digits can either be 0b0 followed by the result, or 0b1
+ * followed by the number of digits of the result. In either case,
+ * we verify that we can read so many bytes from the input.
+ */
+ is_onebyte_result = (c[*p] & 0x80) == 0;
+ digits = c[(*p)++] & 0x7f;
+ if (*p + digits >= l)
+ return DER_BAD;
- if ((digits & 0x80) == 0)
+ if (is_onebyte_result)
return digits;
- digits &= 0x7f;
+ /*
+ * Decode len. We've already verified that we're allowed to read
+ * `digits` bytes.
+ */
len = 0;
-
- if (*p + digits >= l)
- return DER_BAD;
-
for (i = 0; i < digits; i++)
len = (len << 8) | c[(*p)++];
+
if (*p + len >= l)
return DER_BAD;
- return len;
+ return CAST(uint32_t, len);
}
static const char *
@@ -242,12 +260,12 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
#endif
if (m->cont_level != 0) {
if (offs + tlen > nbytes)
- return DER_BAD;
- ms->c.li[m->cont_level - 1].off = offs + tlen;
+ return -1;
+ ms->c.li[m->cont_level - 1].off = CAST(int, offs + tlen);
DPRINTF(("cont_level[%u] = %u\n", m->cont_level - 1,
ms->c.li[m->cont_level - 1].off));
}
- return offs;
+ return CAST(int32_t, offs);
}
int
diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h
index 180efd3..eb9c054 100644
--- a/contrib/file/src/file.h
+++ b/contrib/file/src/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.180 2016/07/20 11:27:08 christos Exp $
+ * @(#)$File: file.h,v 1.183 2017/08/28 13:39:18 christos Exp $
*/
#ifndef __file_h__
@@ -36,6 +36,10 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#ifdef HAVE_STDINT_H
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
#ifdef WIN32
#ifdef _WIN64
@@ -50,16 +54,12 @@
#define INT64_T_FORMAT "ll"
#define INTMAX_T_FORMAT "j"
#endif
+#include <stdint.h>
+#endif
#include <stdio.h> /* Include that here, to make sure __P gets defined */
#include <errno.h>
#include <fcntl.h> /* For open and flags */
-#ifdef HAVE_STDINT_H
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-#include <stdint.h>
-#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
@@ -447,7 +447,7 @@ protected size_t file_printedlen(const struct magic_set *);
protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
-protected int file_reset(struct magic_set *);
+protected int file_reset(struct magic_set *, int);
protected int file_tryelf(struct magic_set *, int, const unsigned char *,
size_t);
protected int file_trycdf(struct magic_set *, int, const unsigned char *,
diff --git a/contrib/file/src/fsmagic.c b/contrib/file/src/fsmagic.c
index 27f982a..c0a437a 100644
--- a/contrib/file/src/fsmagic.c
+++ b/contrib/file/src/fsmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.76 2015/04/09 20:01:41 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -104,14 +104,13 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
{
int ret, did = 0;
int mime = ms->flags & MAGIC_MIME;
+ int silent = ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION);
#ifdef S_IFLNK
char buf[BUFSIZ+4];
ssize_t nch;
struct stat tstatbuf;
#endif
- if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))
- return 0;
if (fn == NULL)
return 0;
@@ -168,7 +167,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
}
ret = 1;
- if (!mime) {
+ if (!mime && !silent) {
#ifdef S_ISUID
if (sb->st_mode & S_ISUID)
if (file_printf(ms, "%ssetuid", COMMA) == -1)
@@ -191,6 +190,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "directory") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%sdirectory", COMMA) == -1)
return -1;
break;
@@ -208,6 +208,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "chardevice") == -1)
return -1;
+ } else if (silent) {
} else {
#ifdef HAVE_STRUCT_STAT_ST_RDEV
# ifdef dv_unit
@@ -242,6 +243,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "blockdevice") == -1)
return -1;
+ } else if (silent) {
} else {
#ifdef HAVE_STRUCT_STAT_ST_RDEV
# ifdef dv_unit
@@ -270,6 +272,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "fifo") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
return -1;
break;
@@ -279,6 +282,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "door") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%sdoor", COMMA) == -1)
return -1;
break;
@@ -294,6 +298,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "symlink") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms,
"%sunreadable symlink `%s' (%s)", COMMA, fn,
strerror(errno)) == -1)
@@ -323,6 +328,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (handle_mime(ms, mime,
"x-path-too-long") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms,
"%spath too long: `%s'", COMMA,
fn) == -1)
@@ -352,6 +358,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "symlink") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%ssymbolic link to %s",
COMMA, buf) == -1)
return -1;
@@ -364,6 +371,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "socket") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%ssocket", COMMA) == -1)
return -1;
break;
@@ -386,6 +394,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "x-empty") == -1)
return -1;
+ } else if (silent) {
} else if (file_printf(ms, "%sempty", COMMA) == -1)
return -1;
break;
@@ -399,7 +408,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
/*NOTREACHED*/
}
- if (!mime && did && ret == 0) {
+ if (!silent && !mime && did && ret == 0) {
if (file_printf(ms, " ") == -1)
return -1;
}
diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c
index c8918a4..d7a18f4 100644
--- a/contrib/file/src/funcs.c
+++ b/contrib/file/src/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.90 2016/10/19 20:51:17 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.93 2017/08/28 13:39:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -76,7 +76,7 @@ file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
ms->o.buf = buf;
return 0;
out:
- file_error(ms, errno, "vasprintf failed");
+ fprintf(stderr, "vasprintf failed (%s)", strerror(errno));
return -1;
}
@@ -328,9 +328,9 @@ simple:
#endif
protected int
-file_reset(struct magic_set *ms)
+file_reset(struct magic_set *ms, int checkloaded)
{
- if (ms->mlist[0] == NULL) {
+ if (checkloaded && ms->mlist[0] == NULL) {
file_error(ms, 0, "no magic files loaded");
return -1;
}
@@ -509,6 +509,8 @@ file_regexec(file_regex_t *rx, const char *str, size_t nmatch,
regmatch_t* pmatch, int eflags)
{
assert(rx->rc == 0);
+ /* XXX: force initialization because glibc does not always do this */
+ memset(pmatch, 0, nmatch * sizeof(*pmatch));
return regexec(&rx->rx, str, nmatch, pmatch, eflags);
}
diff --git a/contrib/file/src/is_tar.c b/contrib/file/src/is_tar.c
index a3e5dbf..1953a7f 100644
--- a/contrib/file/src/is_tar.c
+++ b/contrib/file/src/is_tar.c
@@ -40,7 +40,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: is_tar.c,v 1.38 2015/04/09 20:01:41 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.39 2017/03/17 20:45:01 christos Exp $")
#endif
#include "magic.h"
@@ -51,7 +51,7 @@ FILE_RCSID("@(#)$File: is_tar.c,v 1.38 2015/04/09 20:01:41 christos Exp $")
#define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
private int is_tar(const unsigned char *, size_t);
-private int from_oct(int, const char *); /* Decode octal number */
+private int from_oct(const char *, size_t); /* Decode octal number */
static const char tartype[][32] = {
"tar archive",
@@ -93,31 +93,35 @@ private int
is_tar(const unsigned char *buf, size_t nbytes)
{
const union record *header = (const union record *)(const void *)buf;
- int i;
- int sum, recsum;
- const unsigned char *p;
+ size_t i;
+ int sum, recsum;
+ const unsigned char *p, *ep;
- if (nbytes < sizeof(union record))
+ if (nbytes < sizeof(*header))
return 0;
- recsum = from_oct(8, header->header.chksum);
+ recsum = from_oct(header->header.chksum, sizeof(header->header.chksum));
sum = 0;
p = header->charptr;
- for (i = sizeof(union record); --i >= 0;)
+ ep = header->charptr + sizeof(*header);
+ while (p < ep)
sum += *p++;
/* Adjust checksum to count the "chksum" field as blanks. */
- for (i = sizeof(header->header.chksum); --i >= 0;)
+ for (i = 0; i < sizeof(header->header.chksum); i++)
sum -= header->header.chksum[i];
- sum += ' ' * sizeof header->header.chksum;
+ sum += ' ' * sizeof(header->header.chksum);
if (sum != recsum)
return 0; /* Not a tar archive */
- if (strcmp(header->header.magic, GNUTMAGIC) == 0)
+ if (strncmp(header->header.magic, GNUTMAGIC,
+ sizeof(header->header.magic)) == 0)
return 3; /* GNU Unix Standard tar archive */
- if (strcmp(header->header.magic, TMAGIC) == 0)
+
+ if (strncmp(header->header.magic, TMAGIC,
+ sizeof(header->header.magic)) == 0)
return 2; /* Unix Standard tar archive */
return 1; /* Old fashioned tar archive */
@@ -130,19 +134,22 @@ is_tar(const unsigned char *buf, size_t nbytes)
* Result is -1 if the field is invalid (all blank, or non-octal).
*/
private int
-from_oct(int digs, const char *where)
+from_oct(const char *where, size_t digs)
{
int value;
+ if (digs == 0)
+ return -1;
+
while (isspace((unsigned char)*where)) { /* Skip spaces */
where++;
- if (--digs <= 0)
+ if (digs-- == 0)
return -1; /* All blank field */
}
value = 0;
while (digs > 0 && isodigit(*where)) { /* Scan til non-octal */
value = (value << 3) | (*where++ - '0');
- --digs;
+ digs--;
}
if (digs > 0 && *where && !isspace((unsigned char)*where))
diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c
index b61ad29..1448a69 100644
--- a/contrib/file/src/magic.c
+++ b/contrib/file/src/magic.c
@@ -33,7 +33,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: magic.c,v 1.100 2016/07/18 11:43:05 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -167,7 +167,7 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
{
if (fdwReason == DLL_PROCESS_ATTACH)
_w32_dll_instance = hinstDLL;
- return TRUE;
+ return 1;
}
#endif
@@ -409,7 +409,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
int ispipe = 0;
off_t pos = (off_t)-1;
- if (file_reset(ms) == -1)
+ if (file_reset(ms, 1) == -1)
goto out;
/*
@@ -538,7 +538,7 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
{
if (ms == NULL)
return NULL;
- if (file_reset(ms) == -1)
+ if (file_reset(ms, 1) == -1)
return NULL;
/*
* The main work is done here!
@@ -568,6 +568,15 @@ magic_errno(struct magic_set *ms)
}
public int
+magic_getflags(struct magic_set *ms)
+{
+ if (ms == NULL)
+ return -1;
+
+ return ms->flags;
+}
+
+public int
magic_setflags(struct magic_set *ms, int flags)
{
if (ms == NULL)
diff --git a/contrib/file/src/magic.h.in b/contrib/file/src/magic.h.in
index 3d6954a..1134bdc 100644
--- a/contrib/file/src/magic.h.in
+++ b/contrib/file/src/magic.h.in
@@ -73,6 +73,35 @@
0 \
)
+#define MAGIC_SNPRINTB "\177\020\
+b\0debug\0\
+b\1symlink\0\
+b\2compress\0\
+b\3devices\0\
+b\4mime_type\0\
+b\5continue\0\
+b\6check\0\
+b\7preserve_atime\0\
+b\10raw\0\
+b\11error\0\
+b\12mime_encoding\0\
+b\13apple\0\
+b\14no_check_compress\0\
+b\15no_check_tar\0\
+b\16no_check_soft\0\
+b\17no_check_sapptype\0\
+b\20no_check_elf\0\
+b\21no_check_text\0\
+b\22no_check_cdf\0\
+b\23no_check_reserved0\0\
+b\24no_check_tokens\0\
+b\25no_check_encoding\0\
+b\26no_check_reserved1\0\
+b\27no_check_reserved2\0\
+b\30extension\0\
+b\31transp_compression\0\
+"
+
/* Defined for backwards compatibility (renamed) */
#define MAGIC_NO_CHECK_ASCII MAGIC_NO_CHECK_TEXT
@@ -97,6 +126,7 @@ const char *magic_descriptor(magic_t, int);
const char *magic_buffer(magic_t, const void *, size_t);
const char *magic_error(magic_t);
+int magic_getflags(magic_t);
int magic_setflags(magic_t, int);
int magic_version(void);
diff --git a/contrib/file/src/print.c b/contrib/file/src/print.c
index a0221b1..0b91863 100644
--- a/contrib/file/src/print.c
+++ b/contrib/file/src/print.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.81 2016/01/19 15:09:03 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.82 2017/02/10 18:14:01 christos Exp $")
#endif /* lint */
#include <string.h>
@@ -238,7 +238,7 @@ file_fmttime(uint64_t v, int flags, char *buf)
if (flags & FILE_T_WINDOWS) {
struct timespec ts;
- cdf_timestamp_to_timespec(&ts, v);
+ cdf_timestamp_to_timespec(&ts, CAST(cdf_timestamp_t, v));
t = ts.tv_sec;
} else {
// XXX: perhaps detect and print something if overflow
diff --git a/contrib/file/src/readcdf.c b/contrib/file/src/readcdf.c
index 20e631d..80c8d26 100644
--- a/contrib/file/src/readcdf.c
+++ b/contrib/file/src/readcdf.c
@@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.63 2016/10/18 22:25:42 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.65 2017/04/08 20:58:03 christos Exp $")
#endif
#include <assert.h>
@@ -152,7 +152,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
struct timespec ts;
char buf[64];
const char *str = NULL;
- const char *s;
+ const char *s, *e;
int len;
if (!NOTMIME(ms) && root_storage)
@@ -199,7 +199,9 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
if (info[i].pi_type == CDF_LENGTH32_WSTRING)
k++;
s = info[i].pi_str.s_buf;
- for (j = 0; j < sizeof(vbuf) && len--; s += k) {
+ e = info[i].pi_str.s_buf + len;
+ for (j = 0; s < e && j < sizeof(vbuf)
+ && len--; s += k) {
if (*s == '\0')
break;
if (isprint((unsigned char)*s))
@@ -603,7 +605,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
if ((i = cdf_read_user_stream(&info, &h, &sat, &ssat, &sst, &dir,
"FileHeader", &scn)) != -1) {
#define HWP5_SIGNATURE "HWP Document File"
- if (scn.sst_dirlen >= sizeof(HWP5_SIGNATURE) - 1
+ if (scn.sst_len * scn.sst_ss >= sizeof(HWP5_SIGNATURE) - 1
&& memcmp(scn.sst_tab, HWP5_SIGNATURE,
sizeof(HWP5_SIGNATURE) - 1) == 0) {
if (NOTMIME(ms)) {
diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c
index 90dae39..33766b7 100644
--- a/contrib/file/src/readelf.c
+++ b/contrib/file/src/readelf.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.128 2016/10/04 21:43:10 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.138 2017/08/27 07:55:02 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@@ -310,16 +310,18 @@ private const char os_style_names[][8] = {
"NetBSD",
};
-#define FLAGS_DID_CORE 0x001
-#define FLAGS_DID_OS_NOTE 0x002
-#define FLAGS_DID_BUILD_ID 0x004
-#define FLAGS_DID_CORE_STYLE 0x008
-#define FLAGS_DID_NETBSD_PAX 0x010
-#define FLAGS_DID_NETBSD_MARCH 0x020
-#define FLAGS_DID_NETBSD_CMODEL 0x040
-#define FLAGS_DID_NETBSD_UNKNOWN 0x080
-#define FLAGS_IS_CORE 0x100
-#define FLAGS_DID_AUXV 0x200
+#define FLAGS_CORE_STYLE 0x003
+
+#define FLAGS_DID_CORE 0x004
+#define FLAGS_DID_OS_NOTE 0x008
+#define FLAGS_DID_BUILD_ID 0x010
+#define FLAGS_DID_CORE_STYLE 0x020
+#define FLAGS_DID_NETBSD_PAX 0x040
+#define FLAGS_DID_NETBSD_MARCH 0x080
+#define FLAGS_DID_NETBSD_CMODEL 0x100
+#define FLAGS_DID_NETBSD_UNKNOWN 0x200
+#define FLAGS_IS_CORE 0x400
+#define FLAGS_DID_AUXV 0x800
private int
dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
@@ -709,32 +711,30 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
== -1)
return 1;
*flags |= FLAGS_DID_CORE_STYLE;
+ *flags |= os_style;
}
switch (os_style) {
case OS_STYLE_NETBSD:
if (type == NT_NETBSD_CORE_PROCINFO) {
char sbuf[512];
- uint32_t signo;
- /*
- * Extract the program name. It is at
- * offset 0x7c, and is up to 32-bytes,
- * including the terminating NUL.
- */
- if (file_printf(ms, ", from '%.31s'",
+ struct NetBSD_elfcore_procinfo pi;
+ memset(&pi, 0, sizeof(pi));
+ memcpy(&pi, nbuf + doff, descsz);
+
+ if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
+ "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
file_printable(sbuf, sizeof(sbuf),
- (const char *)&nbuf[doff + 0x7c])) == -1)
- return 1;
-
- /*
- * Extract the signal number. It is at
- * offset 0x08.
- */
- (void)memcpy(&signo, &nbuf[doff + 0x08],
- sizeof(signo));
- if (file_printf(ms, " (signal %u)",
- elf_getu32(swap, signo)) == -1)
+ CAST(char *, pi.cpi_name)),
+ elf_getu32(swap, pi.cpi_pid),
+ elf_getu32(swap, pi.cpi_euid),
+ elf_getu32(swap, pi.cpi_egid),
+ elf_getu32(swap, pi.cpi_nlwps),
+ elf_getu32(swap, pi.cpi_siglwp),
+ elf_getu32(swap, pi.cpi_signo),
+ elf_getu32(swap, pi.cpi_sigcode)) == -1)
return 1;
+
*flags |= FLAGS_DID_CORE;
return 1;
}
@@ -890,7 +890,7 @@ get_string_on_virtaddr(struct magic_set *ms,
offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num,
fsize, virtaddr);
- if ((buflen = pread(fd, buf, buflen, offset)) <= 0) {
+ if ((buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
file_badread(ms);
return 0;
}
@@ -924,8 +924,28 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int is_string;
size_t nval;
- if (type != NT_AUXV || (*flags & FLAGS_IS_CORE) == 0)
+ if ((*flags & (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE)) !=
+ (FLAGS_IS_CORE|FLAGS_DID_CORE_STYLE))
+ return 0;
+
+ switch (*flags & FLAGS_CORE_STYLE) {
+ case OS_STYLE_SVR4:
+ if (type != NT_AUXV)
+ return 0;
+ break;
+#ifdef notyet
+ case OS_STYLE_NETBSD:
+ if (type != NT_NETBSD_CORE_AUXV)
+ return 0;
+ break;
+ case OS_STYLE_FREEBSD:
+ if (type != NT_FREEBSD_PROCSTAT_AUXV)
+ return 0;
+ break;
+#endif
+ default:
return 0;
+ }
*flags |= FLAGS_DID_AUXV;
@@ -1031,13 +1051,13 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
}
if (namesz & 0x80000000) {
- (void)file_printf(ms, ", bad note name size 0x%lx",
+ (void)file_printf(ms, ", bad note name size %#lx",
(unsigned long)namesz);
return 0;
}
if (descsz & 0x80000000) {
- (void)file_printf(ms, ", bad note description size 0x%lx",
+ (void)file_printf(ms, ", bad note description size %#lx",
(unsigned long)descsz);
return 0;
}
@@ -1185,12 +1205,12 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
{
Elf32_Shdr sh32;
Elf64_Shdr sh64;
- int stripped = 1;
+ int stripped = 1, has_debug_info = 0;
size_t nbadcap = 0;
void *nbuf;
off_t noff, coff, name_off;
- uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
- uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
+ uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilities */
+ uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilities */
char name[50];
ssize_t namesize;
@@ -1203,8 +1223,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
/* Read offset of name section to be able to read section names later */
if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab)))
< (ssize_t)xsh_sizeof) {
- file_badread(ms);
- return -1;
+ if (file_printf(ms, ", missing section headers") == -1)
+ return -1;
+ return 0;
}
name_off = xsh_offset;
@@ -1215,8 +1236,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
return -1;
}
name[namesize] = '\0';
- if (strcmp(name, ".debug_info") == 0)
+ if (strcmp(name, ".debug_info") == 0) {
+ has_debug_info = 1;
stripped = 0;
+ }
if (pread(fd, xsh_addr, xsh_sizeof, off) < (ssize_t)xsh_sizeof) {
file_badread(ms);
@@ -1247,9 +1270,9 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
if ((uintmax_t)(xsh_size + xsh_offset) >
(uintmax_t)fsize) {
if (file_printf(ms,
- ", note offset/size 0x%" INTMAX_T_FORMAT
- "x+0x%" INTMAX_T_FORMAT "x exceeds"
- " file size 0x%" INTMAX_T_FORMAT "x",
+ ", note offset/size %#" INTMAX_T_FORMAT
+ "x+%#" INTMAX_T_FORMAT "x exceeds"
+ " file size %#" INTMAX_T_FORMAT "x",
(uintmax_t)xsh_offset, (uintmax_t)xsh_size,
(uintmax_t)fsize) == -1)
return -1;
@@ -1353,7 +1376,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
default:
if (file_printf(ms,
", with unknown capability "
- "0x%" INT64_T_FORMAT "x = 0x%"
+ "%#" INT64_T_FORMAT "x = %#"
INT64_T_FORMAT "x",
(unsigned long long)xcap_tag,
(unsigned long long)xcap_val) == -1)
@@ -1370,6 +1393,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
}
}
+ if (has_debug_info) {
+ if (file_printf(ms, ", with debug_info") == -1)
+ return -1;
+ }
if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
return -1;
if (cap_hw1) {
@@ -1403,13 +1430,13 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
}
if (cap_hw1)
if (file_printf(ms,
- " unknown hardware capability 0x%"
+ " unknown hardware capability %#"
INT64_T_FORMAT "x",
(unsigned long long)cap_hw1) == -1)
return -1;
} else {
if (file_printf(ms,
- " hardware capability 0x%" INT64_T_FORMAT "x",
+ " hardware capability %#" INT64_T_FORMAT "x",
(unsigned long long)cap_hw1) == -1)
return -1;
}
@@ -1425,7 +1452,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
cap_sf1 &= ~SF1_SUNW_MASK;
if (cap_sf1)
if (file_printf(ms,
- ", with unknown software capability 0x%"
+ ", with unknown software capability %#"
INT64_T_FORMAT "x",
(unsigned long long)cap_sf1) == -1)
return -1;
@@ -1479,7 +1506,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
if (((align = xph_align) & 0x80000000UL) != 0 ||
align < 4) {
if (file_printf(ms,
- ", invalid note alignment 0x%lx",
+ ", invalid note alignment %#lx",
(unsigned long)align) == -1)
return -1;
align = 4;
diff --git a/contrib/file/src/readelf.h b/contrib/file/src/readelf.h
index f443b29..ef880b9 100644
--- a/contrib/file/src/readelf.h
+++ b/contrib/file/src/readelf.h
@@ -141,7 +141,7 @@ typedef struct {
#define SHT_SYMTAB 2
#define SHT_NOTE 7
#define SHT_DYNSYM 11
-#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilites */
+#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilities */
/* elf type */
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
@@ -230,6 +230,33 @@ typedef struct {
} Elf64_Shdr;
#define NT_NETBSD_CORE_PROCINFO 1
+#define NT_NETBSD_CORE_AUXV 2
+
+struct NetBSD_elfcore_procinfo {
+ /* Version 1 fields start here. */
+ uint32_t cpi_version; /* our version */
+ uint32_t cpi_cpisize; /* sizeof(this struct) */
+ uint32_t cpi_signo; /* killing signal */
+ uint32_t cpi_sigcode; /* signal code */
+ uint32_t cpi_sigpend[4]; /* pending signals */
+ uint32_t cpi_sigmask[4]; /* blocked signals */
+ uint32_t cpi_sigignore[4]; /* ignored signals */
+ uint32_t cpi_sigcatch[4]; /* caught signals */
+ int32_t cpi_pid; /* process ID */
+ int32_t cpi_ppid; /* parent process ID */
+ int32_t cpi_pgrp; /* process group ID */
+ int32_t cpi_sid; /* session ID */
+ uint32_t cpi_ruid; /* real user ID */
+ uint32_t cpi_euid; /* effective user ID */
+ uint32_t cpi_svuid; /* saved user ID */
+ uint32_t cpi_rgid; /* real group ID */
+ uint32_t cpi_egid; /* effective group ID */
+ uint32_t cpi_svgid; /* saved group ID */
+ uint32_t cpi_nlwps; /* number of LWPs */
+ int8_t cpi_name[32]; /* copy of p->p_comm */
+ /* Add version 2 fields below here. */
+ int32_t cpi_siglwp; /* LWP target of killing signal */
+};
/* Note header in a PT_NOTE section */
typedef struct elf_note {
@@ -328,6 +355,11 @@ typedef struct {
*/
#define NT_NETBSD_CMODEL 6
+/*
+ * FreeBSD specific notes
+ */
+#define NT_FREEBSD_PROCSTAT_AUXV 16
+
#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
#define ELFSIZE ARCH_ELFSIZE
#endif
diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c
index 0e9d433..b9e9753 100644
--- a/contrib/file/src/softmagic.c
+++ b/contrib/file/src/softmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.238 2016/10/24 18:02:17 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.249 2017/06/19 18:30:25 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -192,6 +192,7 @@ flush:
while (magindex < nmagic - 1 &&
magic[magindex + 1].cont_level != 0)
magindex++;
+ cont_level = 0;
continue; /* Skip to next top-level test*/
}
@@ -370,6 +371,7 @@ flush:
case -1:
case 0:
flush = 1;
+ cont_level--;
break;
default:
break;
@@ -1017,9 +1019,8 @@ private int
mconvert(struct magic_set *ms, struct magic *m, int flip)
{
union VALUETYPE *p = &ms->ms_value;
- uint8_t type;
- switch (type = cvt_flip(m->type, flip)) {
+ switch (cvt_flip(m->type, flip)) {
case FILE_BYTE:
if (cvt_8(p, m) == -1)
goto out;
@@ -1184,7 +1185,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
case FILE_DER:
case FILE_SEARCH:
if (offset > nbytes)
- offset = nbytes;
+ offset = CAST(uint32_t, nbytes);
ms->search.s = RCAST(const char *, s) + offset;
ms->search.s_len = nbytes - offset;
ms->search.offset = offset;
@@ -1198,7 +1199,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
const char *end;
size_t lines, linecnt, bytecnt;
- if (s == NULL) {
+ if (s == NULL || nbytes < offset) {
ms->search.s_len = 0;
ms->search.s = NULL;
return 0;
@@ -1260,7 +1261,8 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
if (*dst == '\0') {
if (type == FILE_BESTRING16 ?
*(src - 1) != '\0' :
- *(src + 1) != '\0')
+ ((src + 1 < esrc) &&
+ *(src + 1) != '\0'))
*dst = ' ';
}
}
@@ -1365,7 +1367,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
- fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%"
+ fprintf(stderr, "mget(type=%d, flag=%#x, offset=%u, o=%"
SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
"u, il=%hu, nc=%hu)\n",
m->type, m->flag, offset, o, nbytes,
@@ -1632,6 +1634,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
*/
const unsigned char *a = (const unsigned char *)s1;
const unsigned char *b = (const unsigned char *)s2;
+ const unsigned char *eb = b + len;
uint64_t v;
/*
@@ -1646,6 +1649,10 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
}
else { /* combine the others */
while (len-- > 0) {
+ if (b >= eb) {
+ v = 1;
+ break;
+ }
if ((flags & STRING_IGNORE_LOWERCASE) &&
islower(*a)) {
if ((v = tolower(*b++) - *a++) != '\0')
@@ -1661,7 +1668,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
a++;
if (isspace(*b++)) {
if (!isspace(*a))
- while (isspace(*b))
+ while (b < eb && isspace(*b))
b++;
}
else {
@@ -1672,7 +1679,7 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
else if ((flags & STRING_COMPACT_OPTIONAL_WHITESPACE) &&
isspace(*a)) {
a++;
- while (isspace(*b))
+ while (b < eb && isspace(*b))
b++;
}
else {
@@ -1843,13 +1850,13 @@ magiccheck(struct magic_set *ms, struct magic *m)
for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
if (slen + idx > ms->search.s_len)
- break;
+ return 0;
v = file_strncmp(m->value.s, ms->search.s + idx, slen,
m->str_flags);
if (v == 0) { /* found match */
ms->search.offset += idx;
- ms->search.rm_len = m->str_range - idx;
+ ms->search.rm_len = ms->search.s_len - idx;
break;
}
}
@@ -1887,7 +1894,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
copy[--slen] = '\0';
search = copy;
} else {
- search = ms->search.s;
+ search = CCAST(char *, "");
copy = NULL;
}
rc = file_regexec(&rx, (const char *)search,
diff --git a/contrib/file/src/vasprintf.c b/contrib/file/src/vasprintf.c
index 7a18bed..ad1d316 100644
--- a/contrib/file/src/vasprintf.c
+++ b/contrib/file/src/vasprintf.c
@@ -88,7 +88,7 @@ type: d i o u x X f e g E G c s p n
The function needs to allocate memory to store the full text before to
-actually writting it. i.e if you want to fnprintf() 1000 characters, the
+actually writing it. i.e if you want to fnprintf() 1000 characters, the
functions will allocate 1000 bytes.
This behaviour can be modified: you have to customise the code to flush the
internal buffer (writing to screen or file) when it reach a given size. Then
@@ -108,7 +108,7 @@ you use strange formats.
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: vasprintf.c,v 1.13 2014/12/04 15:56:46 christos Exp $")
+FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $")
#endif /* lint */
#include <assert.h>
OpenPOWER on IntegriCloud