aboutsummaryrefslogtreecommitdiff
path: root/src/libsec
diff options
context:
space:
mode:
authorXi Wang <xi.wang@gmail.com>2013-03-19 14:35:16 -0400
committerRuss Cox <rsc@swtch.com>2013-03-19 14:35:16 -0400
commit8a2a5b8f2568a665f00741994c1247f0f7d3dffe (patch)
tree054259e5f4ee1c94e0afde8fbf0fb518940e5264 /src/libsec
parent01e3847b7e6ff87f72a34a42cd98425e569250f6 (diff)
downloadplan9port-8a2a5b8f2568a665f00741994c1247f0f7d3dffe.tar.gz
plan9port-8a2a5b8f2568a665f00741994c1247f0f7d3dffe.tar.bz2
plan9port-8a2a5b8f2568a665f00741994c1247f0f7d3dffe.zip
libsec: avoid undefined C
gcc compiles `p + length < p' into 'length < 0' since pointer overflow is undefined behavior in C. This breaks the check against a large `length'. Use `length > pend - p' instead. There's no need to check `length < 0' since `length' is from length_decode() and should be non-negative. === Try the simplified code. void bar(void); void foo(unsigned char *p, int length) { if (p + length < p) bar(); } $ gcc -S -o - t.c -O2 ... foo: .LFB0: .cfi_startproc testl %esi, %esi js .L4 rep ret .L4: jmp bar .cfi_endproc Clearly `p' is not used at all. R=rsc CC=plan9port.codebot https://codereview.appspot.com/7231069
Diffstat (limited to 'src/libsec')
-rw-r--r--src/libsec/port/x509.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/src/libsec/port/x509.c b/src/libsec/port/x509.c
index 60b3d073..2bbf8538 100644
--- a/src/libsec/port/x509.c
+++ b/src/libsec/port/x509.c
@@ -2077,8 +2077,7 @@ digest_certinfo(Bytes *cert, DigestFun digestfun, uchar *digest)
if(tag_decode(&p, pend, &tag, &isconstr) != ASN_OK ||
tag.class != Universal || tag.num != SEQUENCE ||
length_decode(&p, pend, &length) != ASN_OK ||
- p+length > pend ||
- p+length < p)
+ length > pend - p)
return;
info = p;
if(ber_decode(&p, pend, &elem) != ASN_OK || elem.tag.num != SEQUENCE)