aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-12 16:00:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-12 16:00:33 -0400
commit02c9c0e9b9d9e26f56aa74245c1a5a843878f899 (patch)
tree468b04a85175934166c656e67615991ab9e3af32
parente5ad8b6d1ef82a83b1469fe66e40e06f07f46222 (diff)
parent23c8a812dc3c621009e4f0e5342aa4e2ede1ceaa (diff)
Merge tag 'keys-fixes-20160512' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull keyring fix from David Howells: "Fix ASN.1 indefinite length object parsing" * tag 'keys-fixes-20160512' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: KEYS: Fix ASN.1 indefinite length object parsing
-rw-r--r--lib/asn1_decoder.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c
index 2b3f46c049d4..554522934c44 100644
--- a/lib/asn1_decoder.c
+++ b/lib/asn1_decoder.c
@@ -74,7 +74,7 @@ next_tag:
74 74
75 /* Extract a tag from the data */ 75 /* Extract a tag from the data */
76 tag = data[dp++]; 76 tag = data[dp++];
77 if (tag == 0) { 77 if (tag == ASN1_EOC) {
78 /* It appears to be an EOC. */ 78 /* It appears to be an EOC. */
79 if (data[dp++] != 0) 79 if (data[dp++] != 0)
80 goto invalid_eoc; 80 goto invalid_eoc;
@@ -96,10 +96,8 @@ next_tag:
96 96
97 /* Extract the length */ 97 /* Extract the length */
98 len = data[dp++]; 98 len = data[dp++];
99 if (len <= 0x7f) { 99 if (len <= 0x7f)
100 dp += len; 100 goto check_length;
101 goto next_tag;
102 }
103 101
104 if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { 102 if (unlikely(len == ASN1_INDEFINITE_LENGTH)) {
105 /* Indefinite length */ 103 /* Indefinite length */
@@ -110,14 +108,18 @@ next_tag:
110 } 108 }
111 109
112 n = len - 0x80; 110 n = len - 0x80;
113 if (unlikely(n > sizeof(size_t) - 1)) 111 if (unlikely(n > sizeof(len) - 1))
114 goto length_too_long; 112 goto length_too_long;
115 if (unlikely(n > datalen - dp)) 113 if (unlikely(n > datalen - dp))
116 goto data_overrun_error; 114 goto data_overrun_error;
117 for (len = 0; n > 0; n--) { 115 len = 0;
116 for (; n > 0; n--) {
118 len <<= 8; 117 len <<= 8;
119 len |= data[dp++]; 118 len |= data[dp++];
120 } 119 }
120check_length:
121 if (len > datalen - dp)
122 goto data_overrun_error;
121 dp += len; 123 dp += len;
122 goto next_tag; 124 goto next_tag;
123 125