TEMP-0000000-B67840.12.ce90e05.patch 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. Subject: Add a limit to the number of ELF notes processed (Suggested by Alexander (...)
  2. ID: TEMP-0000000-B67840
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Tue Dec 16 23:18:40 2014 +0000
  5. Origin: FILE5_21-12-gce90e05
  6. Last-Update: 2015-01-05
  7. - Add a limit to the number of ELF notes processed (Suggested by Alexander
  8. Cherepanov)
  9. - Restructure ELF note printing so that we don't print the same message
  10. multiple times on repeated notes of the same kind.
  11. diff --git a/doc/file.man b/doc/file.man
  12. index dd80d08..1db1660 100644
  13. --- a/doc/file.man
  14. +++ b/doc/file.man
  15. @@ -297,6 +297,7 @@ Set various parameter limits.
  16. .It Sy "Name" Ta Sy "Default" Ta Sy "Explanation"
  17. .It Li indir Ta 15 Ta recursion limit for indirect magic
  18. .It Li name Ta 30 Ta use count limit for name/use magic
  19. +.It Li elf_notes Ta 256 Ta max ELF notes processed
  20. .It Li elf_phnum Ta 128 Ta max ELF program sections processed
  21. .It Li elf_shnum Ta 32768 Ta max ELF sections processed
  22. .El
  23. diff --git a/doc/libmagic.man b/doc/libmagic.man
  24. index d45e3c8..cd9b57c 100644
  25. --- a/doc/libmagic.man
  26. +++ b/doc/libmagic.man
  27. @@ -262,6 +262,7 @@ library.
  28. .It Sy "Parameter" Ta Sy "Type" Ta Sy "Default"
  29. .It Li MAGIC_PARAM_INDIR_MAX Ta size_t Ta 15
  30. .It Li MAGIC_PARAM_NAME_MAX Ta size_t Ta 30
  31. +.It Li MAGIC_PARAM_ELF_NOTES_MAX Ta size_t Ta 256
  32. .It Li MAGIC_PARAM_ELF_PHNUM_MAX Ta size_t Ta 128
  33. .It Li MAGIC_PARAM_ELF_SHNUM_MAX Ta size_t Ta 32768
  34. .El
  35. @@ -281,8 +282,12 @@ The
  36. parameter controls the maximum number of calls for name/use.
  37. .Pp
  38. The
  39. +.Dv MAGIC_PARAM_NOTES_MAX
  40. +parameter controls how many ELF notes will be processed.
  41. +.Pp
  42. +The
  43. .Dv MAGIC_PARAM_PHNUM_MAX
  44. -parameter controls how many elf program sections will be processed.
  45. +parameter controls how many ELF program sections will be processed.
  46. .Pp
  47. The
  48. .Dv MAGIC_PARAM_SHNUM_MAX
  49. diff --git a/src/elfclass.h b/src/elfclass.h
  50. index e144d11..5360b0b 100644
  51. --- a/src/elfclass.h
  52. +++ b/src/elfclass.h
  53. @@ -32,17 +32,18 @@
  54. swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA];
  55. type = elf_getu16(swap, elfhdr.e_type);
  56. + notecount = ms->elf_notes_max;
  57. switch (type) {
  58. #ifdef ELFCORE
  59. case ET_CORE:
  60. phnum = elf_getu16(swap, elfhdr.e_phnum);
  61. if (phnum > ms->elf_phnum_max)
  62. - return toomany(ms, "program", phnum);
  63. + return toomany(ms, "program headers", phnum);
  64. flags |= FLAGS_IS_CORE;
  65. if (dophn_core(ms, clazz, swap, fd,
  66. (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  67. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  68. - fsize, &flags) == -1)
  69. + fsize, &flags, &notecount) == -1)
  70. return -1;
  71. break;
  72. #endif
  73. @@ -57,22 +58,25 @@
  74. if (dophn_exec(ms, clazz, swap, fd,
  75. (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
  76. (size_t)elf_getu16(swap, elfhdr.e_phentsize),
  77. - fsize, &flags, shnum) == -1)
  78. + fsize, shnum, &flags, &notecount) == -1)
  79. return -1;
  80. /*FALLTHROUGH*/
  81. case ET_REL:
  82. shnum = elf_getu16(swap, elfhdr.e_shnum);
  83. if (shnum > ms->elf_shnum_max)
  84. - return toomany(ms, "section", shnum);
  85. + return toomany(ms, "section headers", shnum);
  86. if (doshn(ms, clazz, swap, fd,
  87. (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
  88. (size_t)elf_getu16(swap, elfhdr.e_shentsize),
  89. - fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
  90. - (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
  91. + fsize, elf_getu16(swap, elfhdr.e_machine),
  92. + (int)elf_getu16(swap, elfhdr.e_shstrndx),
  93. + &flags, &notecount) == -1)
  94. return -1;
  95. break;
  96. default:
  97. break;
  98. }
  99. + if (notecount == 0)
  100. + return toomany(ms, "notes", ms->elf_notes_max);
  101. return 1;
  102. diff --git a/src/file.c b/src/file.c
  103. index 5ce08aa..f3d98aa 100644
  104. --- a/src/file.c
  105. +++ b/src/file.c
  106. @@ -128,6 +128,7 @@ private struct {
  107. { "name", MAGIC_PARAM_NAME_MAX, 0 },
  108. { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
  109. { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
  110. + { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
  111. };
  112. private char *progname; /* used throughout */
  113. diff --git a/src/file.h b/src/file.h
  114. index 67331e0..68e22a4 100644
  115. --- a/src/file.h
  116. +++ b/src/file.h
  117. @@ -384,10 +384,12 @@ struct magic_set {
  118. uint16_t name_max;
  119. uint16_t elf_shnum_max;
  120. uint16_t elf_phnum_max;
  121. + uint16_t elf_notes_max;
  122. #define FILE_INDIR_MAX 15
  123. #define FILE_NAME_MAX 30
  124. #define FILE_ELF_SHNUM_MAX 32768
  125. #define FILE_ELF_PHNUM_MAX 128
  126. +#define FILE_ELF_NOTES_MAX 256
  127. };
  128. /* Type for Unicode characters */
  129. diff --git a/src/file_opts.h b/src/file_opts.h
  130. index fc57dc3..9da9796 100644
  131. --- a/src/file_opts.h
  132. +++ b/src/file_opts.h
  133. @@ -46,6 +46,7 @@ OPT('p', "preserve-date", 0, " preserve access times on files\n")
  134. OPT('P', "parameter", 0, " set file engine parameter limits\n"
  135. " indir 15 recursion limit for indirection\n"
  136. " name 30 use limit for name/use magic\n"
  137. + " elf_notes 256 max ELF notes processed\n"
  138. " elf_phnum 128 max ELF prog sections processed\n"
  139. " elf_shnum 32768 max ELF sections processed\n")
  140. OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n")
  141. diff --git a/src/magic.c b/src/magic.c
  142. index 3aa3474..e97c78f 100644
  143. --- a/src/magic.c
  144. +++ b/src/magic.c
  145. @@ -237,6 +237,7 @@ magic_open(int flags)
  146. ms->name_max = FILE_NAME_MAX;
  147. ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
  148. ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
  149. + ms->elf_notes_max = FILE_ELF_NOTES_MAX;
  150. return ms;
  151. free:
  152. free(ms);
  153. @@ -532,6 +533,9 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
  154. case MAGIC_PARAM_ELF_SHNUM_MAX:
  155. ms->elf_shnum_max = *(const size_t *)val;
  156. return 0;
  157. + case MAGIC_PARAM_ELF_NOTES_MAX:
  158. + ms->elf_notes_max = *(const size_t *)val;
  159. + return 0;
  160. default:
  161. errno = EINVAL;
  162. return -1;
  163. @@ -554,6 +558,9 @@ magic_getparam(struct magic_set *ms, int param, void *val)
  164. case MAGIC_PARAM_ELF_SHNUM_MAX:
  165. *(size_t *)val = ms->elf_shnum_max;
  166. return 0;
  167. + case MAGIC_PARAM_ELF_NOTES_MAX:
  168. + *(size_t *)val = ms->elf_notes_max;
  169. + return 0;
  170. default:
  171. errno = EINVAL;
  172. return -1;
  173. diff --git a/src/magic.h b/src/magic.h
  174. index 4aec3c5..ee2e7e8 100644
  175. --- a/src/magic.h
  176. +++ b/src/magic.h
  177. @@ -103,6 +103,7 @@ int magic_errno(magic_t);
  178. #define MAGIC_PARAM_NAME_MAX 1
  179. #define MAGIC_PARAM_ELF_PHNUM_MAX 2
  180. #define MAGIC_PARAM_ELF_SHNUM_MAX 3
  181. +#define MAGIC_PARAM_ELF_NOTES_MAX 4
  182. int magic_setparam(magic_t, int, const void *);
  183. int magic_getparam(magic_t, int, void *);
  184. diff --git a/src/readelf.c b/src/readelf.c
  185. index 544c22b..e1cf692 100644
  186. --- a/src/readelf.c
  187. +++ b/src/readelf.c
  188. @@ -43,14 +43,14 @@ FILE_RCSID("@(#)$File: readelf.c,v 1.90 2011/08/23 08:01:12 christos Exp $")
  189. #ifdef ELFCORE
  190. private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
  191. - off_t, int *);
  192. + off_t, int *, uint16_t *);
  193. #endif
  194. private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
  195. - off_t, int *, int);
  196. + off_t, int, int *, uint16_t *);
  197. private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
  198. - off_t, int *, int, int);
  199. + off_t, int, int, int *, uint16_t *);
  200. private size_t donote(struct magic_set *, void *, size_t, size_t, int,
  201. - int, size_t, int *);
  202. + int, size_t, int *, uint16_t *);
  203. #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
  204. @@ -67,7 +67,7 @@ private uint64_t getu64(int, uint64_t);
  205. private int
  206. toomany(struct magic_set *ms, const char *name, uint16_t num)
  207. {
  208. - if (file_printf(ms, ", too many %s header sections (%u)", name, num
  209. + if (file_printf(ms, ", too many %s (%u)", name, num
  210. ) == -1)
  211. return -1;
  212. return 0;
  213. @@ -301,15 +301,19 @@ private const char os_style_names[][8] = {
  214. "NetBSD",
  215. };
  216. -#define FLAGS_DID_CORE 0x01
  217. -#define FLAGS_DID_NOTE 0x02
  218. -#define FLAGS_DID_BUILD_ID 0x04
  219. -#define FLAGS_DID_CORE_STYLE 0x08
  220. -#define FLAGS_IS_CORE 0x10
  221. +#define FLAGS_DID_CORE 0x001
  222. +#define FLAGS_DID_OS_NOTE 0x002
  223. +#define FLAGS_DID_BUILD_ID 0x004
  224. +#define FLAGS_DID_CORE_STYLE 0x008
  225. +#define FLAGS_DID_NETBSD_PAX 0x010
  226. +#define FLAGS_DID_NETBSD_MARCH 0x020
  227. +#define FLAGS_DID_NETBSD_CMODEL 0x040
  228. +#define FLAGS_DID_NETBSD_UNKNOWN 0x080
  229. +#define FLAGS_IS_CORE 0x100
  230. private int
  231. dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
  232. - int num, size_t size, off_t fsize, int *flags)
  233. + int num, size_t size, off_t fsize, int *flags, uint16_t *notecount)
  234. {
  235. Elf32_Phdr ph32;
  236. Elf64_Phdr ph64;
  237. @@ -355,7 +359,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
  238. if (offset >= (size_t)bufsize)
  239. break;
  240. offset = donote(ms, nbuf, offset, (size_t)bufsize,
  241. - clazz, swap, 4, flags);
  242. + clazz, swap, 4, flags, notecount);
  243. if (offset == 0)
  244. break;
  245. @@ -485,127 +489,126 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
  246. }
  247. }
  248. -private size_t
  249. -donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  250. - int clazz, int swap, size_t align, int *flags)
  251. +private int
  252. +do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
  253. + int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
  254. + size_t noff, size_t doff, int *flags)
  255. {
  256. - Elf32_Nhdr nh32;
  257. - Elf64_Nhdr nh64;
  258. - size_t noff, doff;
  259. -#ifdef ELFCORE
  260. - int os_style = -1;
  261. -#endif
  262. - uint32_t namesz, descsz;
  263. - unsigned char *nbuf = CAST(unsigned char *, vbuf);
  264. -
  265. - if (xnh_sizeof + offset > size) {
  266. - /*
  267. - * We're out of note headers.
  268. - */
  269. - return xnh_sizeof + offset;
  270. - }
  271. -
  272. - (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
  273. - offset += xnh_sizeof;
  274. -
  275. - namesz = xnh_namesz;
  276. - descsz = xnh_descsz;
  277. - if ((namesz == 0) && (descsz == 0)) {
  278. - /*
  279. - * We're out of note headers.
  280. - */
  281. - return (offset >= size) ? offset : size;
  282. - }
  283. -
  284. - if (namesz & 0x80000000) {
  285. - (void)file_printf(ms, ", bad note name size 0x%lx",
  286. - (unsigned long)namesz);
  287. - return 0;
  288. - }
  289. -
  290. - if (descsz & 0x80000000) {
  291. - (void)file_printf(ms, ", bad note description size 0x%lx",
  292. - (unsigned long)descsz);
  293. - return 0;
  294. - }
  295. -
  296. -
  297. - noff = offset;
  298. - doff = ELF_ALIGN(offset + namesz);
  299. -
  300. - if (offset + namesz > size) {
  301. - /*
  302. - * We're past the end of the buffer.
  303. - */
  304. - return doff;
  305. + if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
  306. + type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
  307. + uint32_t desc[5], i;
  308. + *flags |= FLAGS_DID_BUILD_ID;
  309. + if (file_printf(ms, ", BuildID[%s]=0x", descsz == 16 ? "md5/uuid" :
  310. + "sha1") == -1)
  311. + return 1;
  312. + (void)memcpy(desc, &nbuf[doff], descsz);
  313. + for (i = 0; i < descsz >> 2; i++)
  314. + if (file_printf(ms, "%.8x", desc[i]) == -1)
  315. + return 1;
  316. + return 1;
  317. }
  318. + return 0;
  319. +}
  320. - offset = ELF_ALIGN(doff + descsz);
  321. - if (doff + descsz > size) {
  322. - /*
  323. - * We're past the end of the buffer.
  324. - */
  325. - return (offset >= size) ? offset : size;
  326. +private int
  327. +do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
  328. + int swap, uint32_t namesz, uint32_t descsz,
  329. + size_t noff, size_t doff, int *flags)
  330. +{
  331. + if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
  332. + type == NT_GNU_VERSION && descsz == 2) {
  333. + *flags |= FLAGS_DID_OS_NOTE;
  334. + file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
  335. + return 1;
  336. }
  337. - if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) ==
  338. - (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
  339. - goto core;
  340. -
  341. if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
  342. - xnh_type == NT_GNU_VERSION && descsz == 16) {
  343. + type == NT_GNU_VERSION && descsz == 16) {
  344. uint32_t desc[4];
  345. (void)memcpy(desc, &nbuf[doff], sizeof(desc));
  346. + *flags |= FLAGS_DID_OS_NOTE;
  347. if (file_printf(ms, ", for GNU/") == -1)
  348. - return size;
  349. + return 1;
  350. switch (elf_getu32(swap, desc[0])) {
  351. case GNU_OS_LINUX:
  352. if (file_printf(ms, "Linux") == -1)
  353. - return size;
  354. + return 1;
  355. break;
  356. case GNU_OS_HURD:
  357. if (file_printf(ms, "Hurd") == -1)
  358. - return size;
  359. + return 1;
  360. break;
  361. case GNU_OS_SOLARIS:
  362. if (file_printf(ms, "Solaris") == -1)
  363. - return size;
  364. + return 1;
  365. break;
  366. case GNU_OS_KFREEBSD:
  367. if (file_printf(ms, "kFreeBSD") == -1)
  368. - return size;
  369. + return 1;
  370. break;
  371. case GNU_OS_KNETBSD:
  372. if (file_printf(ms, "kNetBSD") == -1)
  373. - return size;
  374. + return 1;
  375. break;
  376. default:
  377. if (file_printf(ms, "<unknown>") == -1)
  378. - return size;
  379. + return 1;
  380. }
  381. if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
  382. elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
  383. - return size;
  384. - *flags |= FLAGS_DID_NOTE;
  385. - return size;
  386. + return 1;
  387. + return 1;
  388. }
  389. - if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
  390. - xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
  391. - uint32_t desc[5], i;
  392. - if (file_printf(ms, ", BuildID[%s]=0x", descsz == 16 ? "md5/uuid" :
  393. - "sha1") == -1)
  394. - return size;
  395. - (void)memcpy(desc, &nbuf[doff], descsz);
  396. - for (i = 0; i < descsz >> 2; i++)
  397. - if (file_printf(ms, "%.8x", desc[i]) == -1)
  398. - return size;
  399. - *flags |= FLAGS_DID_BUILD_ID;
  400. + if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
  401. + if (type == NT_NETBSD_VERSION && descsz == 4) {
  402. + *flags |= FLAGS_DID_OS_NOTE;
  403. + do_note_netbsd_version(ms, swap, &nbuf[doff]);
  404. + return 1;
  405. + }
  406. + }
  407. +
  408. + if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
  409. + if (type == NT_FREEBSD_VERSION && descsz == 4) {
  410. + *flags |= FLAGS_DID_OS_NOTE;
  411. + do_note_freebsd_version(ms, swap, &nbuf[doff]);
  412. + return 1;
  413. + }
  414. }
  415. + if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
  416. + type == NT_OPENBSD_VERSION && descsz == 4) {
  417. + *flags |= FLAGS_DID_OS_NOTE;
  418. + if (file_printf(ms, ", for OpenBSD") == -1)
  419. + return 1;
  420. + /* Content of note is always 0 */
  421. + return 1;
  422. + }
  423. +
  424. + if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
  425. + type == NT_DRAGONFLY_VERSION && descsz == 4) {
  426. + uint32_t desc;
  427. + *flags |= FLAGS_DID_OS_NOTE;
  428. + if (file_printf(ms, ", for DragonFly") == -1)
  429. + return 1;
  430. + (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
  431. + desc = elf_getu32(swap, desc);
  432. + if (file_printf(ms, " %d.%d.%d", desc / 100000,
  433. + desc / 10000 % 10, desc % 10000) == -1)
  434. + return 1;
  435. + return 1;
  436. + }
  437. + return 0;
  438. +}
  439. +
  440. +private int
  441. +do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
  442. + int swap, uint32_t namesz, uint32_t descsz,
  443. + size_t noff, size_t doff, int *flags)
  444. +{
  445. if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
  446. - xnh_type == NT_NETBSD_PAX && descsz == 4) {
  447. + type == NT_NETBSD_PAX && descsz == 4) {
  448. static const char *pax[] = {
  449. "+mprotect",
  450. "-mprotect",
  451. @@ -618,80 +621,32 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  452. size_t i;
  453. int did = 0;
  454. + *flags |= FLAGS_DID_NETBSD_PAX;
  455. (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
  456. desc = elf_getu32(swap, desc);
  457. if (desc && file_printf(ms, ", PaX: ") == -1)
  458. - return size;
  459. + return 1;
  460. for (i = 0; i < __arraycount(pax); i++) {
  461. if (((1 << i) & desc) == 0)
  462. continue;
  463. if (file_printf(ms, "%s%s", did++ ? "," : "",
  464. pax[i]) == -1)
  465. - return size;
  466. - }
  467. - }
  468. -
  469. - if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
  470. - switch (xnh_type) {
  471. - case NT_NETBSD_VERSION:
  472. - if (descsz == 4) {
  473. - do_note_netbsd_version(ms, swap, &nbuf[doff]);
  474. - *flags |= FLAGS_DID_NOTE;
  475. - return size;
  476. - }
  477. - break;
  478. - case NT_NETBSD_MARCH:
  479. - if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
  480. - (const char *)&nbuf[doff]) == -1)
  481. - return size;
  482. - break;
  483. - case NT_NETBSD_CMODEL:
  484. - if (file_printf(ms, ", compiler model: %.*s",
  485. - (int)descsz, (const char *)&nbuf[doff]) == -1)
  486. - return size;
  487. - break;
  488. - default:
  489. - if (file_printf(ms, ", note=%u", xnh_type) == -1)
  490. - return size;
  491. - break;
  492. + return 1;
  493. }
  494. - return size;
  495. - }
  496. -
  497. - if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
  498. - if (xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
  499. - do_note_freebsd_version(ms, swap, &nbuf[doff]);
  500. - *flags |= FLAGS_DID_NOTE;
  501. - return size;
  502. - }
  503. - }
  504. -
  505. - if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
  506. - xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
  507. - if (file_printf(ms, ", for OpenBSD") == -1)
  508. - return size;
  509. - /* Content of note is always 0 */
  510. - *flags |= FLAGS_DID_NOTE;
  511. - return size;
  512. - }
  513. -
  514. - if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
  515. - xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
  516. - uint32_t desc;
  517. - if (file_printf(ms, ", for DragonFly") == -1)
  518. - return size;
  519. - (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
  520. - desc = elf_getu32(swap, desc);
  521. - if (file_printf(ms, " %d.%d.%d", desc / 100000,
  522. - desc / 10000 % 10, desc % 10000) == -1)
  523. - return size;
  524. - *flags |= FLAGS_DID_NOTE;
  525. - return size;
  526. + return 1;
  527. }
  528. + return 0;
  529. +}
  530. -core:
  531. +private int
  532. +do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
  533. + int swap, uint32_t namesz, uint32_t descsz,
  534. + size_t noff, size_t doff, int *flags, size_t size, int clazz)
  535. +{
  536. +#ifdef ELFCORE
  537. + int os_style = -1;
  538. /*
  539. * Sigh. The 2.0.36 kernel in Debian 2.1, at
  540. * least, doesn't correctly implement name
  541. @@ -720,20 +675,17 @@ core:
  542. os_style = OS_STYLE_NETBSD;
  543. }
  544. -#ifdef ELFCORE
  545. - if ((*flags & FLAGS_DID_CORE) != 0)
  546. - return size;
  547. -
  548. if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
  549. if (file_printf(ms, ", %s-style", os_style_names[os_style])
  550. == -1)
  551. - return size;
  552. + return 1;
  553. *flags |= FLAGS_DID_CORE_STYLE;
  554. }
  555. switch (os_style) {
  556. case OS_STYLE_NETBSD:
  557. - if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
  558. + if (type == NT_NETBSD_CORE_PROCINFO) {
  559. + char sbuf[512];
  560. uint32_t signo;
  561. /*
  562. * Extract the program name. It is at
  563. @@ -752,15 +704,14 @@ core:
  564. sizeof(signo));
  565. if (file_printf(ms, " (signal %u)",
  566. elf_getu32(swap, signo)) == -1)
  567. - return size;
  568. + return 1;
  569. *flags |= FLAGS_DID_CORE;
  570. - return size;
  571. + return 1;
  572. }
  573. break;
  574. default:
  575. - if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
  576. -/*###709 [cc] warning: declaration of 'i' shadows previous non-variable%%%*/
  577. + if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
  578. size_t i, j;
  579. unsigned char c;
  580. /*
  581. @@ -828,7 +779,7 @@ core:
  582. * Try next offsets, in case this match is
  583. * in the middle of a string.
  584. */
  585. - for (k = i + 1 ; k < NOFFSETS ; k++) {
  586. + for (k = i + 1 ; k < NOFFSETS; k++) {
  587. size_t no;
  588. int adjust = 1;
  589. if (prpsoffsets(k) >= prpsoffsets(i))
  590. @@ -853,9 +804,9 @@ core:
  591. cp--;
  592. if (file_printf(ms, ", from '%.*s'",
  593. (int)(cp - cname), cname) == -1)
  594. - return size;
  595. + return 1;
  596. *flags |= FLAGS_DID_CORE;
  597. - return size;
  598. + return 1;
  599. tryanother:
  600. ;
  601. @@ -864,6 +815,124 @@ core:
  602. break;
  603. }
  604. #endif
  605. + return 0;
  606. +}
  607. +
  608. +private size_t
  609. +donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
  610. + int clazz, int swap, size_t align, int *flags, uint16_t *notecount)
  611. +{
  612. + Elf32_Nhdr nh32;
  613. + Elf64_Nhdr nh64;
  614. + size_t noff, doff;
  615. + uint32_t namesz, descsz;
  616. + unsigned char *nbuf = CAST(unsigned char *, vbuf);
  617. +
  618. + if (*notecount == 0)
  619. + return 0;
  620. + --*notecount;
  621. +
  622. + if (xnh_sizeof + offset > size) {
  623. + /*
  624. + * We're out of note headers.
  625. + */
  626. + return xnh_sizeof + offset;
  627. + }
  628. +
  629. + (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
  630. + offset += xnh_sizeof;
  631. +
  632. + namesz = xnh_namesz;
  633. + descsz = xnh_descsz;
  634. + if ((namesz == 0) && (descsz == 0)) {
  635. + /*
  636. + * We're out of note headers.
  637. + */
  638. + return (offset >= size) ? offset : size;
  639. + }
  640. +
  641. + if (namesz & 0x80000000) {
  642. + (void)file_printf(ms, ", bad note name size 0x%lx",
  643. + (unsigned long)namesz);
  644. + return 0;
  645. + }
  646. +
  647. + if (descsz & 0x80000000) {
  648. + (void)file_printf(ms, ", bad note description size 0x%lx",
  649. + (unsigned long)descsz);
  650. + return 0;
  651. + }
  652. +
  653. + noff = offset;
  654. + doff = ELF_ALIGN(offset + namesz);
  655. +
  656. + if (offset + namesz > size) {
  657. + /*
  658. + * We're past the end of the buffer.
  659. + */
  660. + return doff;
  661. + }
  662. +
  663. + offset = ELF_ALIGN(doff + descsz);
  664. + if (doff + descsz > size) {
  665. + /*
  666. + * We're past the end of the buffer.
  667. + */
  668. + return (offset >= size) ? offset : size;
  669. + }
  670. +
  671. + if ((*flags & FLAGS_DID_OS_NOTE) == 0) {
  672. + if (do_os_note(ms, nbuf, xnh_type, swap,
  673. + namesz, descsz, noff, doff, flags))
  674. + return size;
  675. + }
  676. +
  677. + if ((*flags & FLAGS_DID_BUILD_ID) == 0) {
  678. + if (do_bid_note(ms, nbuf, xnh_type, swap,
  679. + namesz, descsz, noff, doff, flags))
  680. + return size;
  681. + }
  682. +
  683. + if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
  684. + if (do_pax_note(ms, nbuf, xnh_type, swap,
  685. + namesz, descsz, noff, doff, flags))
  686. + return size;
  687. + }
  688. +
  689. + if ((*flags & FLAGS_DID_CORE) == 0) {
  690. + if (do_core_note(ms, nbuf, xnh_type, swap,
  691. + namesz, descsz, noff, doff, flags, size, clazz))
  692. + return size;
  693. + }
  694. +
  695. + if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
  696. + switch (xnh_type) {
  697. + case NT_NETBSD_VERSION:
  698. + return size;
  699. + case NT_NETBSD_MARCH:
  700. + if (*flags & FLAGS_DID_NETBSD_MARCH)
  701. + return size;
  702. + if (file_printf(ms, ", compiled for: %.*s", (int)descsz,
  703. + (const char *)&nbuf[doff]) == -1)
  704. + return size;
  705. + break;
  706. + case NT_NETBSD_CMODEL:
  707. + if (*flags & FLAGS_DID_NETBSD_CMODEL)
  708. + return size;
  709. + if (file_printf(ms, ", compiler model: %.*s",
  710. + (int)descsz, (const char *)&nbuf[doff]) == -1)
  711. + return size;
  712. + break;
  713. + default:
  714. + if (*flags & FLAGS_DID_NETBSD_UNKNOWN)
  715. + return size;
  716. + if (file_printf(ms, ", note=%u", xnh_type) == -1)
  717. + return size;
  718. + break;
  719. + }
  720. + return size;
  721. + }
  722. +
  723. return offset;
  724. }
  725. @@ -919,7 +988,8 @@ static const cap_desc_t cap_desc_386[] = {
  726. private int
  727. doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
  728. - size_t size, off_t fsize, int *flags, int mach, int strtab)
  729. + size_t size, off_t fsize, int mach, int strtab, int *flags,
  730. + uint16_t *notecount)
  731. {
  732. Elf32_Shdr sh32;
  733. Elf64_Shdr sh64;
  734. @@ -991,7 +1061,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
  735. if (noff >= (off_t)xsh_size)
  736. break;
  737. noff = donote(ms, nbuf, (size_t)noff,
  738. - xsh_size, clazz, swap, 4, flags);
  739. + xsh_size, clazz, swap, 4, flags, notecount);
  740. if (noff == 0)
  741. break;
  742. }
  743. @@ -1117,7 +1187,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
  744. */
  745. private int
  746. dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
  747. - int num, size_t size, off_t fsize, int *flags, int sh_num)
  748. + int num, size_t size, off_t fsize, int sh_num, int *flags,
  749. + uint16_t *notecount)
  750. {
  751. Elf32_Phdr ph32;
  752. Elf64_Phdr ph64;
  753. @@ -1186,7 +1257,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
  754. break;
  755. offset = donote(ms, nbuf, offset,
  756. (size_t)bufsize, clazz, swap, align,
  757. - flags);
  758. + flags, notecount);
  759. if (offset == 0)
  760. break;
  761. }
  762. @@ -1217,7 +1288,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
  763. int flags = 0;
  764. Elf32_Ehdr elf32hdr;
  765. Elf64_Ehdr elf64hdr;
  766. - uint16_t type, phnum, shnum;
  767. + uint16_t type, phnum, shnum, notecount;
  768. if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
  769. return 0;