plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

commit 8a2a5b8f2568a665f00741994c1247f0f7d3dffe
parent 01e3847b7e6ff87f72a34a42cd98425e569250f6
Author: Xi Wang <xi.wang@gmail.com>
Date:   Tue, 19 Mar 2013 14:35:16 -0400

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:
Msrc/libsec/port/x509.c | 3+--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git 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)