diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-12 16:00:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-12 16:00:33 -0400 |
commit | 02c9c0e9b9d9e26f56aa74245c1a5a843878f899 (patch) | |
tree | 468b04a85175934166c656e67615991ab9e3af32 | |
parent | e5ad8b6d1ef82a83b1469fe66e40e06f07f46222 (diff) | |
parent | 23c8a812dc3c621009e4f0e5342aa4e2ede1ceaa (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.c | 16 |
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 | } |
120 | check_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 | ||