On Wed, Oct 23, 2019 at 11:18:11AM +0200, Martin Pieuchot wrote:
> On 23/10/19(Wed) 08:43, Peter J. Philipp wrote:
> > Hi Holger & Tech,
> 
> Hello Peter,
> 
> > I have made my octeon router work again and I have a patch.  But I'm not an
> > openbsd developer, nor is this patch official in any way. 
> 
> Could you explain in words what is the issue?  Why does your diff
> prevent it?
> 
> Thanks!

Hi,

The system has a trap 2, which I looked up as:

#define T_TLB_LD_MISS           2       /* TLB miss on load or ifetch */

what happens before this patch, I think, is that there is a varargs size_t 
(which is size 8 in mips64), that gets promoted (I think) in varargs to int 
(which would likely be size 4).  Then what happens is the char * that is 
va_arg'ed after that is somehow corrupted on length 1, bcopy would trap #2 
on this.

If it is a varargs corruption in the builtin mips64 clang code then I don't
want to have to fix that, as I don't even know where to look.  Instead I 
laid out every buffer very carefully and using int's and char *'s so that 
trap 2 is not called.  I made a bitmask in the called function that usually 
gets the trap that it will treat length of one as an int and the rest as a 
char *.

I admit it was a lot of trial and error I must have gone through over 20+ 
compile/reboot cycles to get it right.  I tested this on a unifi security
gateway and an ER-8.  Both agreed to everything and at that spot is not trap 2.

I may have avoided the condition, but the condition may still be there on
other code.  I didn't look.  To easen debug of this I'll attach some config 
files for npppd that I used in my lab that you can see for yourself on any 
octeon pppoe.

I don't know if these were standard example npppd's or if they were left over
from an earlier project.

Thanks!

-peter

beta$ more npppd.conf
#######npppd.conf 

tunnel PPPOE protocol pppoe { 
         listen on interface ix1
         pppoe-desc-in-pktdump yes 
         pppoe-desc-out-pktdump yes 
         pppoe-session-in-pktdump yes 
         pppoe-session-out-pktdump yes 
         authentication-method pap
} 

ipcp IPCP { 
         pool-address 10.0.0.2-10.0.0.254 
         dns-servers 192.168.177.40
} 

interface tun1 address 10.0.0.1 ipcp IPCP 
authentication LOCAL type local { 
          users-file "/etc/npppd/npppd-users" 
} 
bind tunnel from PPPOE authenticated by LOCAL to tun1
##############################################################

beta# more /etc/npppd/npppd-users
# $OpenBSD: npppd-users,v 1.1 2012/09/20 12:51:43 yasuoka Exp $
# sample npppd-users file.  see npppd-users(5)

testcaller:\
        :password=Verizon:\
        :framed-ip-address=10.0.0.103

##############################################################




> > --- if_spppsubr.c.orig      Tue Oct 22 18:49:47 2019
> > +++ if_spppsubr.c   Wed Oct 23 08:03:35 2019
> > @@ -64,6 +64,7 @@
> >  #endif
> >  
> >  #include <net/if_sppp.h>
> > +#include <lib/libkern/libkern.h>
> >  
> >  # define UNTIMEOUT(fun, arg, handle)       \
> >     timeout_del(&(handle))
> > @@ -233,7 +234,7 @@
> >                              int newstate);
> >  void sppp_auth_send(const struct cp *cp,
> >                        struct sppp *sp, unsigned int type, u_int id,
> > -                      ...);
> > +                           u_int bitmask, ...);
> >  
> >  void sppp_up_event(const struct cp *cp, struct sppp *sp);
> >  void sppp_down_event(const struct cp *cp, struct sppp *sp);
> > @@ -3277,7 +3278,8 @@
> >     STDDCL;
> >     struct lcp_header *h;
> >     int len, x;
> > -   u_char *value, *name, digest[AUTHCHALEN], dsize;
> > +   u_char *value, *name, digest[AUTHCHALEN];
> > +   int dsize;
> >     int value_len, name_len;
> >     MD5_CTX ctx;
> >  
> > @@ -3335,8 +3337,8 @@
> >             MD5Final(digest, &ctx);
> >             dsize = sizeof digest;
> >  
> > -           sppp_auth_send(&chap, sp, CHAP_RESPONSE, h->ident,
> > -                          sizeof dsize, (const char *)&dsize,
> > +           sppp_auth_send(&chap, sp, CHAP_RESPONSE, h->ident, 0x1,
> > +                          1, dsize,
> >                            sizeof digest, digest,
> >                            strlen(sp->myauth.name),
> >                            sp->myauth.name,
> > @@ -3458,7 +3460,7 @@
> >             if (value_len != sizeof digest ||
> >                 timingsafe_bcmp(digest, value, value_len) != 0) {
> >                     /* action scn, tld */
> > -                   sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident,
> > +                   sppp_auth_send(&chap, sp, CHAP_FAILURE, h->ident, 0, 
> >                                    sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
> >                                    0);
> >                     chap.tld(sp);
> > @@ -3467,7 +3469,7 @@
> >             /* action sca, perhaps tlu */
> >             if (sp->state[IDX_CHAP] == STATE_REQ_SENT ||
> >                 sp->state[IDX_CHAP] == STATE_OPENED)
> > -                   sppp_auth_send(&chap, sp, CHAP_SUCCESS, h->ident,
> > +                   sppp_auth_send(&chap, sp, CHAP_SUCCESS, h->ident, 0,
> >                                    sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG,
> >                                    0);
> >             if (sp->state[IDX_CHAP] == STATE_REQ_SENT) {
> > @@ -3634,7 +3636,7 @@
> >  void
> >  sppp_chap_scr(struct sppp *sp)
> >  {
> > -   u_char clen;
> > +   int clen;
> >  
> >     /* Compute random challenge. */
> >     arc4random_buf(sp->chap_challenge, sizeof(sp->chap_challenge));
> > @@ -3642,8 +3644,8 @@
> >  
> >     sp->confid[IDX_CHAP] = ++sp->pp_seq;
> >  
> > -   sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP],
> > -                  sizeof clen, (const char *)&clen,
> > +   sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP], 0x1,
> > +                  1, clen,
> >                    (size_t)AUTHCHALEN, sp->chap_challenge,
> >                    strlen(sp->myauth.name),
> >                    sp->myauth.name,
> > @@ -3671,7 +3673,8 @@
> >     STDDCL;
> >     struct lcp_header *h;
> >     int len, x;
> > -   u_char *name, *passwd, mlen;
> > +   u_char *name, *passwd;
> > +   int mlen;
> >     int name_len, passwd_len;
> >  
> >     len = m->m_pkthdr.len;
> > @@ -3724,7 +3727,8 @@
> >                     /* action scn, tld */
> >                     mlen = sizeof(FAILMSG) - 1;
> >                     sppp_auth_send(&pap, sp, PAP_NAK, h->ident,
> > -                                  sizeof mlen, (const char *)&mlen,
> > +                                  0x1,
> > +                                  1, mlen,
> >                                    sizeof(FAILMSG) - 1, (u_char *)FAILMSG,
> >                                    0);
> >                     pap.tld(sp);
> > @@ -3735,7 +3739,8 @@
> >                 sp->state[IDX_PAP] == STATE_OPENED) {
> >                     mlen = sizeof(SUCCMSG) - 1;
> >                     sppp_auth_send(&pap, sp, PAP_ACK, h->ident,
> > -                                  sizeof mlen, (const char *)&mlen,
> > +                                  0x1,
> > +                                  1, mlen,
> >                                    sizeof(SUCCMSG) - 1, (u_char *)SUCCMSG,
> >                                    0);
> >             }
> > @@ -3941,17 +3946,19 @@
> >  void
> >  sppp_pap_scr(struct sppp *sp)
> >  {
> > -   u_char idlen, pwdlen;
> > +   int s_id, s_pwd;
> >  
> >     sp->confid[IDX_PAP] = ++sp->pp_seq;
> > -   pwdlen = strlen(sp->myauth.secret);
> > -   idlen = strlen(sp->myauth.name);
> >  
> > +   s_pwd = strlen(sp->myauth.secret);
> > +   s_id = strlen(sp->myauth.name);
> > +
> >     sppp_auth_send(&pap, sp, PAP_REQ, sp->confid[IDX_PAP],
> > -                  sizeof idlen, (const char *)&idlen,
> > -                  (size_t)idlen, sp->myauth.name,
> > -                  sizeof pwdlen, (const char *)&pwdlen,
> > -                  (size_t)pwdlen, sp->myauth.secret,
> > +                  0x5,
> > +                  1, s_id,
> > +                  s_id, sp->myauth.name,
> > +                  1, s_pwd,
> > +                  s_pwd, sp->myauth.secret,
> >                    0);
> >  }
> >  /*
> > @@ -3968,15 +3975,16 @@
> >  
> >  void
> >  sppp_auth_send(const struct cp *cp, struct sppp *sp,
> > -           unsigned int type, u_int id, ...)
> > +           unsigned int type, u_int id, u_int bitmask, ...)
> >  {
> >     STDDCL;
> >     struct lcp_header *lh;
> >     struct mbuf *m;
> > -   u_char *p;
> > -   int len, s;
> > -   unsigned int mlen;
> > -   const char *msg;
> > +   char *p;
> > +   int s, myval;
> > +   u_int seq = 1;
> > +   unsigned int mlen, len;
> > +   char *msg;
> >     va_list ap;
> >  
> >     MGETHDR (m, M_DONTWAIT, MT_DATA);
> > @@ -3992,11 +4000,15 @@
> >     lh->ident = id;
> >     p = (u_char*) (lh+1);
> >  
> > -   va_start(ap, id);
> > +   va_start(ap, bitmask);
> >     len = 0;
> >  
> > -   while ((mlen = (unsigned int)va_arg(ap, size_t)) != 0) {
> > -           msg = va_arg(ap, const char *);
> > +   while ((mlen = (unsigned int)va_arg(ap, int)) != 0) {
> > +           if (bitmask & seq)
> > +                   myval = va_arg(ap, int);
> > +           else
> > +                   msg = va_arg(ap, char *);
> > +
> >             len += mlen;
> >             if (len > MHLEN - PKTHDRLEN - LCP_HEADER_LEN) {
> >                     va_end(ap);
> > @@ -4004,10 +4016,16 @@
> >                     return;
> >             }
> >  
> > -           bcopy(msg, p, mlen);
> > +           if (bitmask & seq)
> > +                   *p = myval;
> > +           else
> > +                   memcpy(p, msg, mlen);
> > +
> >             p += mlen;
> > +           seq <<= 1;
> >     }
> >     va_end(ap);
> > +
> >  
> >     m->m_pkthdr.len = m->m_len = PKTHDRLEN + LCP_HEADER_LEN + len;
> >     lh->len = htons (LCP_HEADER_LEN + len);
> > 
> > 

Reply via email to