Yep. Martijn van Duren <openbsd+t...@list.imperialat.at> wrote:
> Just reminded myself of this one. > The manpage says nothing about ober_read_elements setting errno upon > failure, yet it does in most cases. Furthermore, applications like > snmpd use errno in ober_read_elements to determine if a read is > incomplete (checking for ECANCELED), without initializing errno to > 0. > > The danger here is that since some stale errno might linger and a > return from ober_read_elements with NULL could test against an old > errno. > > Diff below tries to remedy this. > > OK? > > martijn@ > > Index: ber.c > =================================================================== > RCS file: /cvs/src/lib/libutil/ber.c,v > retrieving revision 1.15 > diff -u -p -r1.15 ber.c > --- ber.c 24 Oct 2019 12:39:26 -0000 1.15 > +++ ber.c 3 Sep 2020 15:58:23 -0000 > @@ -1266,8 +1266,10 @@ ober_read_element(struct ber *ber, struc > > /* smallest number of contents octets only */ > if ((i == 1 && last == 0 && (c & 0x80) == 0) || > - (i == 1 && last == 0xff && (c & 0x80) != 0)) > + (i == 1 && last == 0xff && (c & 0x80) != 0)) { > + errno = EINVAL; > return -1; > + } > > val <<= 8; > val |= c; > @@ -1299,8 +1301,10 @@ ober_read_element(struct ber *ber, struc > ((u_char *)elm->be_val)[len] = '\0'; > break; > case BER_TYPE_NULL: /* no payload */ > - if (len != 0) > + if (len != 0) { > + errno = EINVAL; > return -1; > + } > break; > case BER_TYPE_SEQUENCE: > case BER_TYPE_SET: > @@ -1346,8 +1350,10 @@ ober_read(struct ber *ber, void *buf, si > { > size_t sz; > > - if (ber->br_rbuf == NULL) > + if (ber->br_rbuf == NULL) { > + errno = ENOBUFS; > return -1; > + } > > sz = ber->br_rend - ber->br_rptr; > if (len > sz) { >