cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

v4l2-jpeg.c (16028B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * V4L2 JPEG header parser helpers.
      4 *
      5 * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>
      6 *
      7 * For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
      8 *
      9 * [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
     10 */
     11
     12#include <asm/unaligned.h>
     13#include <linux/errno.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/types.h>
     17#include <media/v4l2-jpeg.h>
     18
     19MODULE_DESCRIPTION("V4L2 JPEG header parser helpers");
     20MODULE_AUTHOR("Philipp Zabel <kernel@pengutronix.de>");
     21MODULE_LICENSE("GPL");
     22
     23/* Table B.1 - Marker code assignments */
     24#define SOF0	0xffc0	/* start of frame */
     25#define SOF1	0xffc1
     26#define SOF2	0xffc2
     27#define SOF3	0xffc3
     28#define SOF5	0xffc5
     29#define SOF7	0xffc7
     30#define JPG	0xffc8	/* extensions */
     31#define SOF9	0xffc9
     32#define SOF11	0xffcb
     33#define SOF13	0xffcd
     34#define SOF15	0xffcf
     35#define DHT	0xffc4	/* huffman table */
     36#define DAC	0xffcc	/* arithmetic coding conditioning */
     37#define RST0	0xffd0	/* restart */
     38#define RST7	0xffd7
     39#define SOI	0xffd8	/* start of image */
     40#define EOI	0xffd9	/* end of image */
     41#define SOS	0xffda	/* start of stream */
     42#define DQT	0xffdb	/* quantization table */
     43#define DNL	0xffdc	/* number of lines */
     44#define DRI	0xffdd	/* restart interval */
     45#define DHP	0xffde	/* hierarchical progression */
     46#define EXP	0xffdf	/* expand reference */
     47#define APP0	0xffe0	/* application data */
     48#define APP14	0xffee	/* application data for colour encoding */
     49#define APP15	0xffef
     50#define JPG0	0xfff0	/* extensions */
     51#define JPG13	0xfffd
     52#define COM	0xfffe	/* comment */
     53#define TEM	0xff01	/* temporary */
     54
     55/**
     56 * struct jpeg_stream - JPEG byte stream
     57 * @curr: current position in stream
     58 * @end: end position, after last byte
     59 */
     60struct jpeg_stream {
     61	u8 *curr;
     62	u8 *end;
     63};
     64
     65/* returns a value that fits into u8, or negative error */
     66static int jpeg_get_byte(struct jpeg_stream *stream)
     67{
     68	if (stream->curr >= stream->end)
     69		return -EINVAL;
     70
     71	return *stream->curr++;
     72}
     73
     74/* returns a value that fits into u16, or negative error */
     75static int jpeg_get_word_be(struct jpeg_stream *stream)
     76{
     77	u16 word;
     78
     79	if (stream->curr + sizeof(__be16) > stream->end)
     80		return -EINVAL;
     81
     82	word = get_unaligned_be16(stream->curr);
     83	stream->curr += sizeof(__be16);
     84
     85	return word;
     86}
     87
     88static int jpeg_skip(struct jpeg_stream *stream, size_t len)
     89{
     90	if (stream->curr + len > stream->end)
     91		return -EINVAL;
     92
     93	stream->curr += len;
     94
     95	return 0;
     96}
     97
     98static int jpeg_next_marker(struct jpeg_stream *stream)
     99{
    100	int byte;
    101	u16 marker = 0;
    102
    103	while ((byte = jpeg_get_byte(stream)) >= 0) {
    104		marker = (marker << 8) | byte;
    105		/* skip stuffing bytes and REServed markers */
    106		if (marker == TEM || (marker > 0xffbf && marker < 0xffff))
    107			return marker;
    108	}
    109
    110	return byte;
    111}
    112
    113/* this does not advance the current position in the stream */
    114static int jpeg_reference_segment(struct jpeg_stream *stream,
    115				  struct v4l2_jpeg_reference *segment)
    116{
    117	u16 len;
    118
    119	if (stream->curr + sizeof(__be16) > stream->end)
    120		return -EINVAL;
    121
    122	len = get_unaligned_be16(stream->curr);
    123	if (stream->curr + len > stream->end)
    124		return -EINVAL;
    125
    126	segment->start = stream->curr;
    127	segment->length = len;
    128
    129	return 0;
    130}
    131
    132static int v4l2_jpeg_decode_subsampling(u8 nf, u8 h_v)
    133{
    134	if (nf == 1)
    135		return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
    136
    137	/* no chroma subsampling for 4-component images */
    138	if (nf == 4 && h_v != 0x11)
    139		return -EINVAL;
    140
    141	switch (h_v) {
    142	case 0x11:
    143		return V4L2_JPEG_CHROMA_SUBSAMPLING_444;
    144	case 0x21:
    145		return V4L2_JPEG_CHROMA_SUBSAMPLING_422;
    146	case 0x22:
    147		return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
    148	case 0x41:
    149		return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
    150	default:
    151		return -EINVAL;
    152	}
    153}
    154
    155static int jpeg_parse_frame_header(struct jpeg_stream *stream, u16 sof_marker,
    156				   struct v4l2_jpeg_frame_header *frame_header)
    157{
    158	int len = jpeg_get_word_be(stream);
    159
    160	if (len < 0)
    161		return len;
    162	/* Lf = 8 + 3 * Nf, Nf >= 1 */
    163	if (len < 8 + 3)
    164		return -EINVAL;
    165
    166	if (frame_header) {
    167		/* Table B.2 - Frame header parameter sizes and values */
    168		int p, y, x, nf;
    169		int i;
    170
    171		p = jpeg_get_byte(stream);
    172		if (p < 0)
    173			return p;
    174		/*
    175		 * Baseline DCT only supports 8-bit precision.
    176		 * Extended sequential DCT also supports 12-bit precision.
    177		 */
    178		if (p != 8 && (p != 12 || sof_marker != SOF1))
    179			return -EINVAL;
    180
    181		y = jpeg_get_word_be(stream);
    182		if (y < 0)
    183			return y;
    184		if (y == 0)
    185			return -EINVAL;
    186
    187		x = jpeg_get_word_be(stream);
    188		if (x < 0)
    189			return x;
    190		if (x == 0)
    191			return -EINVAL;
    192
    193		nf = jpeg_get_byte(stream);
    194		if (nf < 0)
    195			return nf;
    196		/*
    197		 * The spec allows 1 <= Nf <= 255, but we only support up to 4
    198		 * components.
    199		 */
    200		if (nf < 1 || nf > V4L2_JPEG_MAX_COMPONENTS)
    201			return -EINVAL;
    202		if (len != 8 + 3 * nf)
    203			return -EINVAL;
    204
    205		frame_header->precision = p;
    206		frame_header->height = y;
    207		frame_header->width = x;
    208		frame_header->num_components = nf;
    209
    210		for (i = 0; i < nf; i++) {
    211			struct v4l2_jpeg_frame_component_spec *component;
    212			int c, h_v, tq;
    213
    214			c = jpeg_get_byte(stream);
    215			if (c < 0)
    216				return c;
    217
    218			h_v = jpeg_get_byte(stream);
    219			if (h_v < 0)
    220				return h_v;
    221			if (i == 0) {
    222				int subs;
    223
    224				subs = v4l2_jpeg_decode_subsampling(nf, h_v);
    225				if (subs < 0)
    226					return subs;
    227				frame_header->subsampling = subs;
    228			} else if (h_v != 0x11) {
    229				/* all chroma sampling factors must be 1 */
    230				return -EINVAL;
    231			}
    232
    233			tq = jpeg_get_byte(stream);
    234			if (tq < 0)
    235				return tq;
    236
    237			component = &frame_header->component[i];
    238			component->component_identifier = c;
    239			component->horizontal_sampling_factor =
    240				(h_v >> 4) & 0xf;
    241			component->vertical_sampling_factor = h_v & 0xf;
    242			component->quantization_table_selector = tq;
    243		}
    244	} else {
    245		return jpeg_skip(stream, len - 2);
    246	}
    247
    248	return 0;
    249}
    250
    251static int jpeg_parse_scan_header(struct jpeg_stream *stream,
    252				  struct v4l2_jpeg_scan_header *scan_header)
    253{
    254	size_t skip;
    255	int len = jpeg_get_word_be(stream);
    256
    257	if (len < 0)
    258		return len;
    259	/* Ls = 8 + 3 * Ns, Ns >= 1 */
    260	if (len < 6 + 2)
    261		return -EINVAL;
    262
    263	if (scan_header) {
    264		int ns;
    265		int i;
    266
    267		ns = jpeg_get_byte(stream);
    268		if (ns < 0)
    269			return ns;
    270		if (ns < 1 || ns > 4 || len != 6 + 2 * ns)
    271			return -EINVAL;
    272
    273		scan_header->num_components = ns;
    274
    275		for (i = 0; i < ns; i++) {
    276			struct v4l2_jpeg_scan_component_spec *component;
    277			int cs, td_ta;
    278
    279			cs = jpeg_get_byte(stream);
    280			if (cs < 0)
    281				return cs;
    282
    283			td_ta = jpeg_get_byte(stream);
    284			if (td_ta < 0)
    285				return td_ta;
    286
    287			component = &scan_header->component[i];
    288			component->component_selector = cs;
    289			component->dc_entropy_coding_table_selector =
    290				(td_ta >> 4) & 0xf;
    291			component->ac_entropy_coding_table_selector =
    292				td_ta & 0xf;
    293		}
    294
    295		skip = 3; /* skip Ss, Se, Ah, and Al */
    296	} else {
    297		skip = len - 2;
    298	}
    299
    300	return jpeg_skip(stream, skip);
    301}
    302
    303/* B.2.4.1 Quantization table-specification syntax */
    304static int jpeg_parse_quantization_tables(struct jpeg_stream *stream,
    305					  u8 precision,
    306					  struct v4l2_jpeg_reference *tables)
    307{
    308	int len = jpeg_get_word_be(stream);
    309
    310	if (len < 0)
    311		return len;
    312	/* Lq = 2 + n * 65 (for baseline DCT), n >= 1 */
    313	if (len < 2 + 65)
    314		return -EINVAL;
    315
    316	len -= 2;
    317	while (len >= 65) {
    318		u8 pq, tq, *qk;
    319		int ret;
    320		int pq_tq = jpeg_get_byte(stream);
    321
    322		if (pq_tq < 0)
    323			return pq_tq;
    324
    325		/* quantization table element precision */
    326		pq = (pq_tq >> 4) & 0xf;
    327		/*
    328		 * Only 8-bit Qk values for 8-bit sample precision. Extended
    329		 * sequential DCT with 12-bit sample precision also supports
    330		 * 16-bit Qk values.
    331		 */
    332		if (pq != 0 && (pq != 1 || precision != 12))
    333			return -EINVAL;
    334
    335		/* quantization table destination identifier */
    336		tq = pq_tq & 0xf;
    337		if (tq > 3)
    338			return -EINVAL;
    339
    340		/* quantization table element */
    341		qk = stream->curr;
    342		ret = jpeg_skip(stream, pq ? 128 : 64);
    343		if (ret < 0)
    344			return -EINVAL;
    345
    346		if (tables) {
    347			tables[tq].start = qk;
    348			tables[tq].length = pq ? 128 : 64;
    349		}
    350
    351		len -= pq ? 129 : 65;
    352	}
    353
    354	return 0;
    355}
    356
    357/* B.2.4.2 Huffman table-specification syntax */
    358static int jpeg_parse_huffman_tables(struct jpeg_stream *stream,
    359				     struct v4l2_jpeg_reference *tables)
    360{
    361	int mt;
    362	int len = jpeg_get_word_be(stream);
    363
    364	if (len < 0)
    365		return len;
    366	/* Table B.5 - Huffman table specification parameter sizes and values */
    367	if (len < 2 + 17)
    368		return -EINVAL;
    369
    370	for (len -= 2; len >= 17; len -= 17 + mt) {
    371		u8 tc, th, *table;
    372		int tc_th = jpeg_get_byte(stream);
    373		int i, ret;
    374
    375		if (tc_th < 0)
    376			return tc_th;
    377
    378		/* table class - 0 = DC, 1 = AC */
    379		tc = (tc_th >> 4) & 0xf;
    380		if (tc > 1)
    381			return -EINVAL;
    382
    383		/* huffman table destination identifier */
    384		th = tc_th & 0xf;
    385		/* only two Huffman tables for baseline DCT */
    386		if (th > 1)
    387			return -EINVAL;
    388
    389		/* BITS - number of Huffman codes with length i */
    390		table = stream->curr;
    391		mt = 0;
    392		for (i = 0; i < 16; i++) {
    393			int li;
    394
    395			li = jpeg_get_byte(stream);
    396			if (li < 0)
    397				return li;
    398
    399			mt += li;
    400		}
    401		/* HUFFVAL - values associated with each Huffman code */
    402		ret = jpeg_skip(stream, mt);
    403		if (ret < 0)
    404			return ret;
    405
    406		if (tables) {
    407			tables[(tc << 1) | th].start = table;
    408			tables[(tc << 1) | th].length = stream->curr - table;
    409		}
    410	}
    411
    412	return jpeg_skip(stream, len - 2);
    413}
    414
    415/* B.2.4.4 Restart interval definition syntax */
    416static int jpeg_parse_restart_interval(struct jpeg_stream *stream,
    417				       u16 *restart_interval)
    418{
    419	int len = jpeg_get_word_be(stream);
    420	int ri;
    421
    422	if (len < 0)
    423		return len;
    424	if (len != 4)
    425		return -EINVAL;
    426
    427	ri = jpeg_get_word_be(stream);
    428	if (ri < 0)
    429		return ri;
    430
    431	*restart_interval = ri;
    432
    433	return 0;
    434}
    435
    436static int jpeg_skip_segment(struct jpeg_stream *stream)
    437{
    438	int len = jpeg_get_word_be(stream);
    439
    440	if (len < 0)
    441		return len;
    442	if (len < 2)
    443		return -EINVAL;
    444
    445	return jpeg_skip(stream, len - 2);
    446}
    447
    448/* Rec. ITU-T T.872 (06/2012) 6.5.3 */
    449static int jpeg_parse_app14_data(struct jpeg_stream *stream,
    450				 enum v4l2_jpeg_app14_tf *tf)
    451{
    452	int ret;
    453	int lp;
    454	int skip;
    455
    456	lp = jpeg_get_word_be(stream);
    457	if (lp < 0)
    458		return lp;
    459
    460	/* Check for "Adobe\0" in Ap1..6 */
    461	if (stream->curr + 6 > stream->end ||
    462	    strncmp(stream->curr, "Adobe\0", 6))
    463		return -EINVAL;
    464
    465	/* get to Ap12 */
    466	ret = jpeg_skip(stream, 11);
    467	if (ret < 0)
    468		return ret;
    469
    470	ret = jpeg_get_byte(stream);
    471	if (ret < 0)
    472		return ret;
    473
    474	*tf = ret;
    475
    476	/* skip the rest of the segment, this ensures at least it is complete */
    477	skip = lp - 2 - 11;
    478	return jpeg_skip(stream, skip);
    479}
    480
    481/**
    482 * v4l2_jpeg_parse_header - locate marker segments and optionally parse headers
    483 * @buf: address of the JPEG buffer, should start with a SOI marker
    484 * @len: length of the JPEG buffer
    485 * @out: returns marker segment positions and optionally parsed headers
    486 *
    487 * The out->scan_header pointer must be initialized to NULL or point to a valid
    488 * v4l2_jpeg_scan_header structure. The out->huffman_tables and
    489 * out->quantization_tables pointers must be initialized to NULL or point to a
    490 * valid array of 4 v4l2_jpeg_reference structures each.
    491 *
    492 * Returns 0 or negative error if parsing failed.
    493 */
    494int v4l2_jpeg_parse_header(void *buf, size_t len, struct v4l2_jpeg_header *out)
    495{
    496	struct jpeg_stream stream;
    497	int marker;
    498	int ret = 0;
    499
    500	stream.curr = buf;
    501	stream.end = stream.curr + len;
    502
    503	out->num_dht = 0;
    504	out->num_dqt = 0;
    505
    506	/* the first bytes must be SOI, B.2.1 High-level syntax */
    507	if (jpeg_get_word_be(&stream) != SOI)
    508		return -EINVAL;
    509
    510	/* init value to signal if this marker is not present */
    511	out->app14_tf = V4L2_JPEG_APP14_TF_UNKNOWN;
    512
    513	/* loop through marker segments */
    514	while ((marker = jpeg_next_marker(&stream)) >= 0) {
    515		switch (marker) {
    516		/* baseline DCT, extended sequential DCT */
    517		case SOF0 ... SOF1:
    518			ret = jpeg_reference_segment(&stream, &out->sof);
    519			if (ret < 0)
    520				return ret;
    521			ret = jpeg_parse_frame_header(&stream, marker,
    522						      &out->frame);
    523			break;
    524		/* progressive, lossless */
    525		case SOF2 ... SOF3:
    526		/* differential coding */
    527		case SOF5 ... SOF7:
    528		/* arithmetic coding */
    529		case SOF9 ... SOF11:
    530		case SOF13 ... SOF15:
    531		case DAC:
    532		case TEM:
    533			return -EINVAL;
    534
    535		case DHT:
    536			ret = jpeg_reference_segment(&stream,
    537					&out->dht[out->num_dht++ % 4]);
    538			if (ret < 0)
    539				return ret;
    540			if (!out->huffman_tables) {
    541				ret = jpeg_skip_segment(&stream);
    542				break;
    543			}
    544			ret = jpeg_parse_huffman_tables(&stream,
    545							out->huffman_tables);
    546			break;
    547		case DQT:
    548			ret = jpeg_reference_segment(&stream,
    549					&out->dqt[out->num_dqt++ % 4]);
    550			if (ret < 0)
    551				return ret;
    552			if (!out->quantization_tables) {
    553				ret = jpeg_skip_segment(&stream);
    554				break;
    555			}
    556			ret = jpeg_parse_quantization_tables(&stream,
    557					out->frame.precision,
    558					out->quantization_tables);
    559			break;
    560		case DRI:
    561			ret = jpeg_parse_restart_interval(&stream,
    562							&out->restart_interval);
    563			break;
    564		case APP14:
    565			ret = jpeg_parse_app14_data(&stream,
    566						    &out->app14_tf);
    567			break;
    568		case SOS:
    569			ret = jpeg_reference_segment(&stream, &out->sos);
    570			if (ret < 0)
    571				return ret;
    572			ret = jpeg_parse_scan_header(&stream, out->scan);
    573			/*
    574			 * stop parsing, the scan header marks the beginning of
    575			 * the entropy coded segment
    576			 */
    577			out->ecs_offset = stream.curr - (u8 *)buf;
    578			return ret;
    579
    580		/* markers without parameters */
    581		case RST0 ... RST7: /* restart */
    582		case SOI: /* start of image */
    583		case EOI: /* end of image */
    584			break;
    585
    586		/* skip unknown or unsupported marker segments */
    587		default:
    588			ret = jpeg_skip_segment(&stream);
    589			break;
    590		}
    591		if (ret < 0)
    592			return ret;
    593	}
    594
    595	return marker;
    596}
    597EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_header);
    598
    599/**
    600 * v4l2_jpeg_parse_frame_header - parse frame header
    601 * @buf: address of the frame header, after the SOF0 marker
    602 * @len: length of the frame header
    603 * @frame_header: returns the parsed frame header
    604 *
    605 * Returns 0 or negative error if parsing failed.
    606 */
    607int v4l2_jpeg_parse_frame_header(void *buf, size_t len,
    608				 struct v4l2_jpeg_frame_header *frame_header)
    609{
    610	struct jpeg_stream stream;
    611
    612	stream.curr = buf;
    613	stream.end = stream.curr + len;
    614	return jpeg_parse_frame_header(&stream, SOF0, frame_header);
    615}
    616EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_frame_header);
    617
    618/**
    619 * v4l2_jpeg_parse_scan_header - parse scan header
    620 * @buf: address of the scan header, after the SOS marker
    621 * @len: length of the scan header
    622 * @scan_header: returns the parsed scan header
    623 *
    624 * Returns 0 or negative error if parsing failed.
    625 */
    626int v4l2_jpeg_parse_scan_header(void *buf, size_t len,
    627				struct v4l2_jpeg_scan_header *scan_header)
    628{
    629	struct jpeg_stream stream;
    630
    631	stream.curr = buf;
    632	stream.end = stream.curr + len;
    633	return jpeg_parse_scan_header(&stream, scan_header);
    634}
    635EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_scan_header);
    636
    637/**
    638 * v4l2_jpeg_parse_quantization_tables - parse quantization tables segment
    639 * @buf: address of the quantization table segment, after the DQT marker
    640 * @len: length of the quantization table segment
    641 * @precision: sample precision (P) in bits per component
    642 * @q_tables: returns four references into the buffer for the
    643 *            four possible quantization table destinations
    644 *
    645 * Returns 0 or negative error if parsing failed.
    646 */
    647int v4l2_jpeg_parse_quantization_tables(void *buf, size_t len, u8 precision,
    648					struct v4l2_jpeg_reference *q_tables)
    649{
    650	struct jpeg_stream stream;
    651
    652	stream.curr = buf;
    653	stream.end = stream.curr + len;
    654	return jpeg_parse_quantization_tables(&stream, precision, q_tables);
    655}
    656EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_quantization_tables);
    657
    658/**
    659 * v4l2_jpeg_parse_huffman_tables - parse huffman tables segment
    660 * @buf: address of the Huffman table segment, after the DHT marker
    661 * @len: length of the Huffman table segment
    662 * @huffman_tables: returns four references into the buffer for the
    663 *                  four possible Huffman table destinations, in
    664 *                  the order DC0, DC1, AC0, AC1
    665 *
    666 * Returns 0 or negative error if parsing failed.
    667 */
    668int v4l2_jpeg_parse_huffman_tables(void *buf, size_t len,
    669				   struct v4l2_jpeg_reference *huffman_tables)
    670{
    671	struct jpeg_stream stream;
    672
    673	stream.curr = buf;
    674	stream.end = stream.curr + len;
    675	return jpeg_parse_huffman_tables(&stream, huffman_tables);
    676}
    677EXPORT_SYMBOL_GPL(v4l2_jpeg_parse_huffman_tables);