On Tue, Jul 03, 2018 at 05:38:18PM -0400, Rob Pierce wrote:
> On Tue, Jul 03, 2018 at 09:25:06PM +0100, Stuart Henderson wrote:
> > On 2018/07/03 22:17, Claudio Jeker wrote:
> > > I have a hard time to understand why this is needed in snmpd.
> > > For single char reads ber_readbuf(b, c, 1) and ber_read(b, c, 1) should do
> > > exaclty the same. At least in the old code. I see that snmpd added br_offs
> > > in a way that causes this breakage. The update of br_offs is handled in
> > > the wrong place in my opinion.
> > > 
> > > I would prefer something like the appended diff.
> > > This also removes the r == 0 check in ber_read since ber_readbuf cannot
> > > return 0.  Can someone check against the snmpd usecase that failed?
> > 
> > Yes this fixes it, thanks. The use case that fails is "configure SNMPv3,
> > try to use it".
> > e.g.
> > 
> > user "username" authkey "authkey" enc aes enckey "privkey"
> > 
> > $ snmpwalk -v3 -l authPriv -a SHA -A authkey -u username -x AES -X privkey 
> > hostname
> > 
> > > -- 
> > > :wq Claudio
> > > 
> > > Index: ber.c
> > > ===================================================================
> > > RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
> > > retrieving revision 1.37
> > > diff -u -p -r1.37 ber.c
> > > --- ber.c 1 Jul 2018 20:03:48 -0000       1.37
> > > +++ ber.c 3 Jul 2018 20:16:13 -0000
> > > @@ -1212,8 +1212,7 @@ ber_read_element(struct ber *ber, struct
> > >  static ssize_t
> > >  ber_readbuf(struct ber *b, void *buf, size_t nbytes)
> > >  {
> > > - size_t   sz;
> > > - size_t   len;
> > > + size_t   sz, len;
> > >  
> > >   if (b->br_rbuf == NULL)
> > >           return -1;
> > > @@ -1227,6 +1226,7 @@ ber_readbuf(struct ber *b, void *buf, si
> > >  
> > >   bcopy(b->br_rptr, buf, len);
> > >   b->br_rptr += len;
> > > + b->br_offs += len;
> > >  
> > >   return (len);
> > >  }
> > > @@ -1271,7 +1271,7 @@ ber_free(struct ber *b)
> > >  static ssize_t
> > >  ber_getc(struct ber *b, u_char *c)
> > >  {
> > > - return ber_read(b, c, 1);
> > > + return ber_readbuf(b, c, 1);
> > >  }
> > >  
> > >  static ssize_t
> > > @@ -1284,14 +1284,10 @@ ber_read(struct ber *ber, void *buf, siz
> > >           r = ber_readbuf(ber, b, remain);
> > >           if (r == -1)
> > >                   return -1;
> > > -         if (r == 0)
> > > -                 return (b - (u_char *)buf);
> > >           b += r;
> > >           remain -= r;
> > >   }
> > > - r = b - (u_char *)buf;
> > > - ber->br_offs += r;
> > > - return r;
> > > + return (b - (u_char *)buf);
> > >  }
> > >  
> > >  int
> > > 
> 
> Your diff also passes the snmpd regression tests here, including that specific
> use case. LDAP also appears happy with this change. 
> 
> How about this larger diff (based on yours) for all ber.c instances?
> 
> Index: usr.bin/ldap/ber.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ldap/ber.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 ber.c
> --- usr.bin/ldap/ber.c        3 Jul 2018 18:49:10 -0000       1.8
> +++ usr.bin/ldap/ber.c        3 Jul 2018 21:33:26 -0000
> @@ -1212,8 +1212,7 @@ ber_read_element(struct ber *ber, struct
>  static ssize_t
>  ber_readbuf(struct ber *b, void *buf, size_t nbytes)
>  {
> -     size_t   sz;
> -     size_t   len;
> +     size_t   sz, len;
>  
>       if (b->br_rbuf == NULL)
>               return -1;
> @@ -1227,6 +1226,7 @@ ber_readbuf(struct ber *b, void *buf, si
>  
>       bcopy(b->br_rptr, buf, len);
>       b->br_rptr += len;
> +     b->br_offs += len;
>  
>       return (len);
>  }
> @@ -1284,14 +1284,10 @@ ber_read(struct ber *ber, void *buf, siz
>               r = ber_readbuf(ber, b, remain);
>               if (r == -1)
>                       return -1;
> -             if (r == 0)
> -                     return (b - (u_char *)buf);
>               b += r;
>               remain -= r;
>       }
> -     r = b - (u_char *)buf;
> -     ber->br_offs += r;
> -     return r;
> +     return (b - (u_char *)buf);
>  }
>  
>  int
> Index: usr.sbin/ldapd/ber.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 ber.c
> --- usr.sbin/ldapd/ber.c      3 Jul 2018 18:49:10 -0000       1.18
> +++ usr.sbin/ldapd/ber.c      3 Jul 2018 21:33:31 -0000
> @@ -1212,8 +1212,7 @@ ber_read_element(struct ber *ber, struct
>  static ssize_t
>  ber_readbuf(struct ber *b, void *buf, size_t nbytes)
>  {
> -     size_t   sz;
> -     size_t   len;
> +     size_t   sz, len;
>  
>       if (b->br_rbuf == NULL)
>               return -1;
> @@ -1227,6 +1226,7 @@ ber_readbuf(struct ber *b, void *buf, si
>  
>       bcopy(b->br_rptr, buf, len);
>       b->br_rptr += len;
> +     b->br_offs += len;
>  
>       return (len);
>  }
> @@ -1284,14 +1284,10 @@ ber_read(struct ber *ber, void *buf, siz
>               r = ber_readbuf(ber, b, remain);
>               if (r == -1)
>                       return -1;
> -             if (r == 0)
> -                     return (b - (u_char *)buf);
>               b += r;
>               remain -= r;
>       }
> -     r = b - (u_char *)buf;
> -     ber->br_offs += r;
> -     return r;
> +     return (b - (u_char *)buf);
>  }
>  
>  int
> Index: usr.sbin/ypldap/ber.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 ber.c
> --- usr.sbin/ypldap/ber.c     3 Jul 2018 18:49:10 -0000       1.20
> +++ usr.sbin/ypldap/ber.c     3 Jul 2018 21:33:38 -0000
> @@ -1212,8 +1212,7 @@ ber_read_element(struct ber *ber, struct
>  static ssize_t
>  ber_readbuf(struct ber *b, void *buf, size_t nbytes)
>  {
> -     size_t   sz;
> -     size_t   len;
> +     size_t   sz, len;
>  
>       if (b->br_rbuf == NULL)
>               return -1;
> @@ -1227,6 +1226,7 @@ ber_readbuf(struct ber *b, void *buf, si
>  
>       bcopy(b->br_rptr, buf, len);
>       b->br_rptr += len;
> +     b->br_offs += len;
>  
>       return (len);
>  }
> @@ -1284,14 +1284,10 @@ ber_read(struct ber *ber, void *buf, siz
>               r = ber_readbuf(ber, b, remain);
>               if (r == -1)
>                       return -1;
> -             if (r == 0)
> -                     return (b - (u_char *)buf);
>               b += r;
>               remain -= r;
>       }
> -     r = b - (u_char *)buf;
> -     ber->br_offs += r;
> -     return r;
> +     return (b - (u_char *)buf);
>  }
>  
>  int
> Index: usr.sbin/snmpd/ber.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v
> retrieving revision 1.37
> diff -u -p -r1.37 ber.c
> --- usr.sbin/snmpd/ber.c      1 Jul 2018 20:03:48 -0000       1.37
> +++ usr.sbin/snmpd/ber.c      3 Jul 2018 21:33:39 -0000
> @@ -1212,8 +1212,7 @@ ber_read_element(struct ber *ber, struct
>  static ssize_t
>  ber_readbuf(struct ber *b, void *buf, size_t nbytes)
>  {
> -     size_t   sz;
> -     size_t   len;
> +     size_t   sz, len;
>  
>       if (b->br_rbuf == NULL)
>               return -1;
> @@ -1227,6 +1226,7 @@ ber_readbuf(struct ber *b, void *buf, si
>  
>       bcopy(b->br_rptr, buf, len);
>       b->br_rptr += len;
> +     b->br_offs += len;
>  
>       return (len);
>  }
> @@ -1271,7 +1271,7 @@ ber_free(struct ber *b)
>  static ssize_t
>  ber_getc(struct ber *b, u_char *c)
>  {
> -     return ber_read(b, c, 1);
> +     return ber_readbuf(b, c, 1);
>  }
>  
>  static ssize_t
> @@ -1284,14 +1284,10 @@ ber_read(struct ber *ber, void *buf, siz
>               r = ber_readbuf(ber, b, remain);
>               if (r == -1)
>                       return -1;
> -             if (r == 0)
> -                     return (b - (u_char *)buf);
>               b += r;
>               remain -= r;
>       }
> -     r = b - (u_char *)buf;
> -     ber->br_offs += r;
> -     return r;
> +     return (b - (u_char *)buf);
>  }
>  
>  int
> 

Looks good to me. I made the same for some of them already.

-- 
:wq Claudio

Reply via email to