On Mon, Nov 27, 2017 at 11:46:54PM +0100, Claudio Jeker wrote:
> On Mon, Nov 27, 2017 at 11:34:49PM +0100, Alexander Bluhm wrote:
> > On Mon, Nov 27, 2017 at 11:26:06PM +0100, Claudio Jeker wrote:
> > > Guess we should make the 3 fatalx() in that code different so that it
> > > becomes more clear on which call it fails.
> > 
> > As in the diff below?
> > 
> > > Wonder what kind of startup race we lose...
> > 
> > I can reproduce one of the errors on my laptop:
> > 
> > make run-regress-args-https-inspect.pl      # create test certificates
> > find / >/dev/null                   # clear the  buffer cache for a while
> > make run-regress-args-https-inspect.pl      # fails at the first try
> > 
> > ======== run-regress-args-https-inspect.pl ========
> > time SUDO=sudo KTRACE= RELAYD= perl -I/usr/src/regress/usr.sbin/relayd 
> > /usr/src/regress/usr.sbin/relayd/relayd.pl copy 
> > /usr/src/regress/usr.sbin/relayd/args-https-inspect.pl
> > Client child status: 65280 exit: 255 at 
> > /usr/src/regress/usr.sbin/relayd/Proc.pm line 161.
> > *** Error 255 in /usr/src/regress/usr.sbin/relayd (Makefile:68 
> > 'run-regress-args-https-inspect.pl')
> > 
> > Now amd64, T430s, ssd, single machine
> > 
> > execute: sudo relayd -dvv -f relayd.conf
> > startup
> > relay_load_certfiles: using ca certificate ca.crt
> > pfe: filter init done
> > socket_rlimit: max open files 1024
> > socket_rlimit: max open files 1024
> > relay_load_certfiles: using ca key ca.key
> > relay_load_certfiles: using certificate /etc/ssl/127.0.0.1.crt
> > relay_load_certfiles: using private key /etc/ssl/private/127.0.0.1.key
> > parent_tls_ticket_rekey: rekeying tickets
> > relay_privinit: adding relay relay-args-https-inspect.pl
> > protocol 1: name proto-args-https-inspect.pl
> >     flags: used, relay flags: tls, tls client, tls inspect
> >     tcp flags: no splice
> >     tls flags: tlsv1.2, cipher-server-preference
> >     tls session tickets: disabled
> >     type: http
> >             match request header log "foo" value "*" 
> >             match response header log "bar" value "*" 
> > ca_engine_init: using RSA privsep engine
> > ca_engine_init: using RSA privsep engine
> > relay_tls_ctx_create: loading certificate
> > failed to load tls CA certificate: Invalid argument
> > relay: relay_launch: failed to create TLS context
> > pfe exiting, pid 18436
> > hce exiting, pid 69282
> > lost child: pid 5175 exited abnormally
> > ca exiting, pid 40825
> > parent terminating, pid 53770
> > 
> > bluhm
> > 
> > Index: ca.c
> > ===================================================================
> > RCS file: /mount/openbsd/cvs/src/usr.sbin/relayd/ca.c,v
> > retrieving revision 1.29
> > diff -u -p -r1.29 ca.c
> > --- ca.c    27 Nov 2017 21:06:25 -0000      1.29
> > +++ ca.c    27 Nov 2017 21:45:59 -0000
> > @@ -123,14 +123,14 @@ ca_launch(void)
> >             if (rlay->rl_tls_cert_fd != -1) {
> >                     if ((buf = relay_load_fd(rlay->rl_tls_cert_fd,
> >                         &len)) == NULL)
> > -                           fatalx("ca_launch: cert");
> > +                           fatalx("ca_launch: cert relay_load_fd");
> >  
> >                     if ((in = BIO_new_mem_buf(buf, len)) == NULL)
> > -                           fatalx("ca_launch: cert");
> > +                           fatalx("ca_launch: cert BIO_new_mem_buf");
> >  
> >                     if ((cert = PEM_read_bio_X509(in, NULL,
> >                         NULL, NULL)) == NULL)
> > -                           fatalx("ca_launch: cert");
> > +                           fatalx("ca_launch: cert PEM_read_bio_X509");
> >  
> >                     hash_x509(cert, hash, sizeof(hash));
> >  
> > @@ -160,14 +160,14 @@ ca_launch(void)
> >             if (rlay->rl_tls_cacert_fd != -1) {
> >                     if ((buf = relay_load_fd(rlay->rl_tls_cacert_fd,
> >                         &len)) == NULL)
> > -                           fatalx("ca_launch: cacert");
> > +                           fatalx("ca_launch: cacert relay_load_fd");
> >  
> >                     if ((in = BIO_new_mem_buf(buf, len)) == NULL)
> > -                           fatalx("ca_launch: cacert");
> > +                           fatalx("ca_launch: cacert BIO_new_mem_buf");
> >  
> >                     if ((cert = PEM_read_bio_X509(in, NULL,
> >                         NULL, NULL)) == NULL)
> > -                           fatalx("ca_launch: cacert");
> > +                           fatalx("ca_launch: cacert PEM_read_bio_X509");
> >  
> >                     hash_x509(cert, hash, sizeof(hash));
> >  
> 
> Have the same diff in my tree. OK claudio@
> The problem is a race in relay_load_fd() according to guenther@ we should
> use pread instead of the lseek/ read combo. Lets see if that works. 
> 

Like this. Seems to fix it for me.

-- 
:wq Claudio

Index: relay.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/relay.c,v
retrieving revision 1.231
diff -u -p -r1.231 relay.c
--- relay.c     27 Nov 2017 21:09:55 -0000      1.231
+++ relay.c     27 Nov 2017 22:43:49 -0000
@@ -2580,15 +2580,14 @@ relay_load_fd(int fd, off_t *len)
        struct stat      st;
        off_t            size;
        ssize_t          rv;
+       int              err;
 
        if (fstat(fd, &st) != 0)
                goto fail;
        size = st.st_size;
        if ((buf = calloc(1, size + 1)) == NULL)
                goto fail;
-       if (lseek(fd, 0, SEEK_SET) != 0)
-               goto fail;
-       if ((rv = read(fd, buf, size)) != size)
+       if ((rv = pread(fd, buf, size, 0)) != size)
                goto fail;
 
        close(fd);
@@ -2597,8 +2596,10 @@ relay_load_fd(int fd, off_t *len)
        return (buf);
 
  fail:
+       err = errno;
        free(buf);
        close(fd);
+       errno = err;
        return (NULL);
 }
 

Reply via email to