History

Merge tag 'asn1-fixes-20150805' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next

James Morris committed 11 years ago

Commit 459c15e2 parents 730daa1 233ce793 files · +48 −18Browse files

Unified · Split

3 files
  1. include/linux/asn1_ber_bytecode.h +11 −5
  2. lib/asn1_decoder.c +23 −4
  3. scripts/asn1_compiler.c +14 −9
include/linux/asn1_ber_bytecode.h+11−5
@@ -45,23 +45,27 @@ enum asn1_opcode { · 44 unmodified lines
4545 ASN1_OP_MATCH_JUMP = 0x04,
4646 ASN1_OP_MATCH_JUMP_OR_SKIP = 0x05,
4747 ASN1_OP_MATCH_ANY = 0x08,
48+ ASN1_OP_MATCH_ANY_OR_SKIP = 0x09,
4849 ASN1_OP_MATCH_ANY_ACT = 0x0a,
50+ ASN1_OP_MATCH_ANY_ACT_OR_SKIP = 0x0b,
4951 /* Everything before here matches unconditionally */
5052
5153 ASN1_OP_COND_MATCH_OR_SKIP = 0x11,
5254 ASN1_OP_COND_MATCH_ACT_OR_SKIP = 0x13,
5355 ASN1_OP_COND_MATCH_JUMP_OR_SKIP = 0x15,
5456 ASN1_OP_COND_MATCH_ANY = 0x18,
57+ ASN1_OP_COND_MATCH_ANY_OR_SKIP = 0x19,
5558 ASN1_OP_COND_MATCH_ANY_ACT = 0x1a,
59+ ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP = 0x1b,
5660
5761 /* Everything before here will want a tag from the data */
58−#define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT
62+#define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP
5963
6064 /* These are here to help fill up space */
61− ASN1_OP_COND_FAIL = 0x1b,
62− ASN1_OP_COMPLETE = 0x1c,
63− ASN1_OP_ACT = 0x1d,
64− ASN1_OP_RETURN = 0x1e,
65+ ASN1_OP_COND_FAIL = 0x1c,
66+ ASN1_OP_COMPLETE = 0x1d,
67+ ASN1_OP_ACT = 0x1e,
68+ ASN1_OP_MAYBE_ACT = 0x1f,
6569
6670 /* The following eight have bit 0 -> SET, 1 -> OF, 2 -> ACT */
6771 ASN1_OP_END_SEQ = 0x20,
@@ -76,6 +80,8 @@ enum asn1_opcode { · 8 unmodified lines
7680 #define ASN1_OP_END__OF 0x02
7781 #define ASN1_OP_END__ACT 0x04
7882
83+ ASN1_OP_RETURN = 0x28,
84+
7985 ASN1_OP__NR
8086 };
8187
lib/asn1_decoder.c+23−4
@@ -24,15 +24,20 @@ static const unsigned char asn1_op_lengths[ASN1_OP__NR] = { · 23 unmodified lines
2424 [ASN1_OP_MATCH_JUMP] = 1 + 1 + 1,
2525 [ASN1_OP_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
2626 [ASN1_OP_MATCH_ANY] = 1,
27+ [ASN1_OP_MATCH_ANY_OR_SKIP] = 1,
2728 [ASN1_OP_MATCH_ANY_ACT] = 1 + 1,
29+ [ASN1_OP_MATCH_ANY_ACT_OR_SKIP] = 1 + 1,
2830 [ASN1_OP_COND_MATCH_OR_SKIP] = 1 + 1,
2931 [ASN1_OP_COND_MATCH_ACT_OR_SKIP] = 1 + 1 + 1,
3032 [ASN1_OP_COND_MATCH_JUMP_OR_SKIP] = 1 + 1 + 1,
3133 [ASN1_OP_COND_MATCH_ANY] = 1,
34+ [ASN1_OP_COND_MATCH_ANY_OR_SKIP] = 1,
3235 [ASN1_OP_COND_MATCH_ANY_ACT] = 1 + 1,
36+ [ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP] = 1 + 1,
3337 [ASN1_OP_COND_FAIL] = 1,
3438 [ASN1_OP_COMPLETE] = 1,
3539 [ASN1_OP_ACT] = 1 + 1,
40+ [ASN1_OP_MAYBE_ACT] = 1 + 1,
3641 [ASN1_OP_RETURN] = 1,
3742 [ASN1_OP_END_SEQ] = 1,
3843 [ASN1_OP_END_SEQ_OF] = 1 + 1,
@@ -177,6 +182,7 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder, · 138 unmodified lines
177182 unsigned char flags = 0;
178183 #define FLAG_INDEFINITE_LENGTH 0x01
179184 #define FLAG_MATCHED 0x02
185+#define FLAG_LAST_MATCHED 0x04 /* Last tag matched */
180186 #define FLAG_CONS 0x20 /* Corresponds to CONS bit in the opcode tag
181187 * - ie. whether or not we are going to parse
182188 * a compound type.
@@ -208,9 +214,9 @@ next_op: · 25 unmodified lines
208214 unsigned char tmp;
209215
210216 /* Skip conditional matches if possible */
211− if ((op & ASN1_OP_MATCH__COND &&
212− flags & FLAG_MATCHED) ||
213− dp == datalen) {
217+ if ((op & ASN1_OP_MATCH__COND && flags & FLAG_MATCHED) ||
218+ (op & ASN1_OP_MATCH__SKIP && dp == datalen)) {
219+ flags &= ~FLAG_LAST_MATCHED;
214220 pc += asn1_op_lengths[op];
215221 goto next_op;
216222 }
@@ -302,7 +308,9 @@ next_op: · 85 unmodified lines
302308 /* Decide how to handle the operation */
303309 switch (op) {
304310 case ASN1_OP_MATCH_ANY_ACT:
311+ case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
305312 case ASN1_OP_COND_MATCH_ANY_ACT:
313+ case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
306314 ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
307315 if (ret < 0)
308316 return ret;
@@ -319,8 +327,10 @@ next_op: · 10 unmodified lines
319327 case ASN1_OP_MATCH:
320328 case ASN1_OP_MATCH_OR_SKIP:
321329 case ASN1_OP_MATCH_ANY:
330+ case ASN1_OP_MATCH_ANY_OR_SKIP:
322331 case ASN1_OP_COND_MATCH_OR_SKIP:
323332 case ASN1_OP_COND_MATCH_ANY:
333+ case ASN1_OP_COND_MATCH_ANY_OR_SKIP:
324334 skip_data:
325335 if (!(flags & FLAG_CONS)) {
326336 if (flags & FLAG_INDEFINITE_LENGTH) {
@@ -422,8 +432,15 @@ next_op: · 95 unmodified lines
422432 pc += asn1_op_lengths[op];
423433 goto next_op;
424434
435+ case ASN1_OP_MAYBE_ACT:
436+ if (!(flags & FLAG_LAST_MATCHED)) {
437+ pc += asn1_op_lengths[op];
438+ goto next_op;
439+ }
425440 case ASN1_OP_ACT:
426441 ret = actions[machine[pc + 1]](context, hdr, tag, data + tdp, len);
442+ if (ret < 0)
443+ return ret;
427444 pc += asn1_op_lengths[op];
428445 goto next_op;
429446
@@ -431,6 +448,7 @@ next_op: · 1 unmodified line
431448 if (unlikely(jsp <= 0))
432449 goto jump_stack_underflow;
433450 pc = jump_stack[--jsp];
451+ flags |= FLAG_MATCHED | FLAG_LAST_MATCHED;
434452 goto next_op;
435453
436454 default:
@@ -438,7 +456,8 @@ next_op: · 1 unmodified line
438456 }
439457
440458 /* Shouldn't reach here */
441− pr_err("ASN.1 decoder error: Found reserved opcode (%u)\n", op);
459+ pr_err("ASN.1 decoder error: Found reserved opcode (%u) pc=%zu\n",
460+ op, pc);
442461 return -EBADMSG;
443462
444463 data_overrun_error:
scripts/asn1_compiler.c+14−9
@@ -666,7 +666,7 @@ struct element { · 665 unmodified lines
666666 unsigned flags;
667667 #define ELEMENT_IMPLICIT 0x0001
668668 #define ELEMENT_EXPLICIT 0x0002
669−#define ELEMENT_MARKED 0x0004
669+#define ELEMENT_TAG_SPECIFIED 0x0004
670670 #define ELEMENT_RENDERED 0x0008
671671 #define ELEMENT_SKIPPABLE 0x0010
672672 #define ELEMENT_CONDITIONAL 0x0020
@@ -879,6 +879,7 @@ static struct element *parse_type(struct token **_cursor, struct token *end, · 206 unmodified lines
879879
880880 element->tag &= ~0x1f;
881881 element->tag |= strtoul(cursor->value, &p, 10);
882+ element->flags |= ELEMENT_TAG_SPECIFIED;
882883 if (p - cursor->value != cursor->size)
883884 abort();
884885 cursor++;
@@ -1376,7 +1377,7 @@ static void render_out_of_line_list(FILE *out) · 491 unmodified lines
13761377 */
13771378 static void render_element(FILE *out, struct element *e, struct element *tag)
13781379 {
1379− struct element *ec;
1380+ struct element *ec, *x;
13801381 const char *cond, *act;
13811382 int entry, skippable = 0, outofline = 0;
13821383
@@ -1400,7 +1401,8 @@ static void render_element(FILE *out, struct element *e, struct element *tag) · 17 unmodified lines
14001401 act = e->action ? "_ACT" : "";
14011402 switch (e->compound) {
14021403 case ANY:
1403− render_opcode(out, "ASN1_OP_%sMATCH_ANY%s,", cond, act);
1404+ render_opcode(out, "ASN1_OP_%sMATCH_ANY%s%s,",
1405+ cond, act, skippable ? "_OR_SKIP" : "");
14041406 if (e->name)
14051407 render_more(out, "\t\t// %*.*s",
14061408 (int)e->name->size, (int)e->name->size,
@@ -1435,15 +1437,17 @@ static void render_element(FILE *out, struct element *e, struct element *tag) · 28 unmodified lines
14351437 break;
14361438 }
14371439
1438− if (e->name)
1440+ x = tag ?: e;
1441+ if (x->name)
14391442 render_more(out, "\t\t// %*.*s",
1440− (int)e->name->size, (int)e->name->size,
1441− e->name->value);
1443+ (int)x->name->size, (int)x->name->size,
1444+ x->name->value);
14421445 render_more(out, "\n");
14431446
14441447 /* Render the tag */
1445− if (!tag)
1448+ if (!tag || !(tag->flags & ELEMENT_TAG_SPECIFIED))
14461449 tag = e;
1450+
14471451 if (tag->class == ASN1_UNIV &&
14481452 tag->tag != 14 &&
14491453 tag->tag != 15 &&
@@ -1465,7 +1469,8 @@ dont_render_tag: · 15 unmodified lines
14651469 case TYPE_REF:
14661470 render_element(out, e->type->type->element, tag);
14671471 if (e->action)
1468− render_opcode(out, "ASN1_OP_ACT,\n");
1472+ render_opcode(out, "ASN1_OP_%sACT,\n",
1473+ skippable ? "MAYBE_" : "");
14691474 break;
14701475
14711476 case SEQUENCE:
@@ -1539,7 +1544,7 @@ dont_render_tag: · 67 unmodified lines
15391544
15401545 case CHOICE:
15411546 for (ec = e->children; ec; ec = ec->next)
1542− render_element(out, ec, NULL);
1547+ render_element(out, ec, ec);
15431548 if (!skippable)
15441549 render_opcode(out, "ASN1_OP_COND_FAIL,\n");
15451550 if (e->action)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t