Yep.
Martijn van Duren <[email protected]> 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) {
>