Re: re(4) reads the pci-e max packet size wrongly

2015-02-19 Thread Jan Stary
On Feb 19 10:01:22, j...@insec.sh wrote:
 On Wed, Feb 18, 2015 at 11:23:15AM +1000, David Gwynne wrote:
  it looks like it reads the DCSR register and then keeps everything
  except the MPS field.
  
  this might cause it to erronously consider the mps to be much bigger
  than 2048, which in turn could prevent it from setting it correctly.
  
  i dont actually have one of these chips. can someone give it a spin?
 
 nothing broke on my 8168D and 8168E running -current with this, for
 what it's worth.

Nothing broke on my 8168G.

re0 at pci2 dev 0 function 0 Realtek 8168 rev 0x0c: RTL8168G/8111G (0x4c00), 
msi, address e0:3f:49:6f:f3:1c
rgephy0 at re0 phy 7: RTL8251 PHY, rev. 0

Jan



Re: splassert: rtrequest1: want 5 have 0

2015-02-19 Thread Alexander Bluhm
On Wed, Feb 18, 2015 at 12:14:15PM +0100, Matthieu Herrb wrote:
 Feb 18 12:09:59 castor /bsd: splassert: rtrequest1: want 5 have 0
 Feb 18 12:09:59 castor /bsd: Starting stack trace...
 Feb 18 12:09:59 castor /bsd: splassert_check() at splassert_check+0x78
 Feb 18 12:09:59 castor /bsd: rtrequest1() at rtrequest1+0x5e
 Feb 18 12:09:59 castor /bsd: nd6_prefix_offlink() at
 nd6_prefix_offlink+0x1bf
 Feb 18 12:09:59 castor /bsd: pfxlist_onlink_check() at
 pfxlist_onlink_check+0x25e
 Feb 18 12:09:59 castor /bsd: in6_control() at in6_control+0x894
 Feb 18 12:09:59 castor /bsd: ifioctl() at ifioctl+0x175
 Feb 18 12:09:59 castor /bsd: sys_ioctl() at sys_ioctl+0x169
 Feb 18 12:09:59 castor /bsd: syscall() at syscall+0x297
 Feb 18 12:09:59 castor /bsd: --- syscall (number 54) ---
 Feb 18 12:09:59 castor /bsd: end of kernel
 Feb 18 12:09:59 castor /bsd: end trace frame: 0xc8115948400, count:
 249
 Feb 18 12:09:59 castor /bsd: 0xc8115715cda:
 Feb 18 12:09:59 castor /bsd: End of stack trace.
 Feb 18 12:10:00 castor /bsd: carp0: state transition: BACKUP - MASTER

Most calls to pfxlist_onlink_check() are protected by splsoftnet.
Only the path in your trace does not set it.  So I suggest to set
splsoftnet() in in6_control().  I have included the dohooks() as
this is done in IPv4.  While there I have moved some splsoftnet()
hiding in the declarations to the beginning of the code.

ok?

bluhm

Index: netinet6/in6.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.152
diff -u -p -r1.152 in6.c
--- netinet6/in6.c  27 Jan 2015 10:34:27 -  1.152
+++ netinet6/in6.c  19 Feb 2015 18:47:06 -
@@ -552,6 +552,7 @@ in6_control(struct socket *so, u_long cm
pr-ndpr_refcnt++;
}
 
+   s = splsoftnet();
/*
 * this might affect the status of autoconfigured addresses,
 * that is, this address might make other addresses detached.
@@ -559,6 +560,7 @@ in6_control(struct socket *so, u_long cm
pfxlist_onlink_check();
 
dohooks(ifp-if_addrhooks, 0);
+   splx(s);
break;
}
 
Index: netinet6/nd6_rtr.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_rtr.c,v
retrieving revision 1.97
diff -u -p -r1.97 nd6_rtr.c
--- netinet6/nd6_rtr.c  27 Jan 2015 03:17:36 -  1.97
+++ netinet6/nd6_rtr.c  19 Feb 2015 17:39:18 -
@@ -707,10 +707,10 @@ defrouter_reset(void)
 void
 defrouter_select(void)
 {
-   int s = splsoftnet();
struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL;
struct rtentry *rt = NULL;
struct llinfo_nd6 *ln = NULL;
+   int s = splsoftnet();
 
/*
 * This function should be called only when acting as an autoconfigured
@@ -1139,12 +1139,13 @@ prelist_update(struct nd_prefix *new, st
struct ifaddr *ifa;
struct ifnet *ifp = new-ndpr_ifp;
struct nd_prefix *pr;
-   int s = splsoftnet();
-   int error = 0;
+   int s, error = 0;
int tempaddr_preferred = 0, autoconf = 0, statique = 0;
int auth;
struct in6_addrlifetime lt6_tmp;
char addr[INET6_ADDRSTRLEN];
+
+   s = splsoftnet();
 
auth = 0;
if (m) {



Re: fusefs_readdir() should set eofflag

2015-02-19 Thread Martin Natano
  @@ -733,6 +734,9 @@
   
  fb_delete(fbuf);
  }
  +
  +   if (!error  ap-a_eofflag != NULL)
  +   *ap-a_eofflag = eofflag;
 
 Is the null check here necessary? Other file systems don't do this, so I'm
 wondering if you encountered a null pointer here.
I didn't encounter a null pointer and none of the callers pass NULL as a
eofflag here, so I guess I included the check out of sheer paranoia. ;)

cheers,
natano



Re: syslogd SSL3_WRITE_PENDING:bad write retry

2015-02-19 Thread Alexander Bluhm
On Tue, Feb 17, 2015 at 09:10:05AM +0100, Reyk Floeter wrote:
 But workaround is a harsh word - this is the way you were supposed to
 use SSL_write().  It is adapted from relayd and was turned into
 tls_write().

I came from the other direction.  I had no idea about SSL API and
expected to use libtls as a simple replacement for plain TCP.  The
partial write and moving buffer semantics are not documented within
libtls, so I tried the naive way.

 I even wonder why you didn't pick this up in your
 evbuffer TLS implementation for syslogd;  looks a bit reinvented.

My goal was to keep my TLS buffer imlementation as close as possible
to libevent.  So I can merge it back into libevent.  If we don't
want this, I can still clean it up.

  - set SSL_MODE_ENABLE_PARTIAL_WRITE in libtls
  - remove the clt_buf workaround in httpd
  - ignore ftp client
  
 
 This approach sounds sane and I would love to have tls_write(3) behave
 just like write(2).

Yes, but after unlock.

 - What is the impact of adding the flags by default?

I think it makes sense for non-blocking operations in httpd and
syslogd.  They do propper buffer handling anyway.  The ftp client
is blocking and just wants to write the HTTP header.  There short
writes are uncomfortable.

 - What is the reason for OpenSSL's defaults?
 
 There is an old thread with some dicussion about it:
 http://marc.info/?l=openssl-devm=118766345824094w=2

I found another thread from 2006.
http://marc.info/?t=11510126221r=1w=2

I have the impression Bodo Moeller knows something about it.

| If SSL_write() has started writing a first record, but delayed other
| data to later records, then it may have to return -1 to indicate
| a WANT_WRITE or WANT_READ condition.

My interpretation is, OpenSSL cannot indicate a short write in a
want read condition.  You must not change the buffer content or
decrease its length.  This buffer move check is a hint that you
must be careful.

Anyway, libtls is locked.  We can either release a broken syslogd
over TLS implementation or commit this diff.  It has the smallest
impact of everything I have tried.

ok or better idea?

bluhm

Index: usr.sbin/syslogd/evbuffer_tls.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/evbuffer_tls.c,v
retrieving revision 1.2
diff -u -p -r1.2 evbuffer_tls.c
--- usr.sbin/syslogd/evbuffer_tls.c 30 Jan 2015 14:00:55 -  1.2
+++ usr.sbin/syslogd/evbuffer_tls.c 19 Feb 2015 16:47:44 -
@@ -186,6 +186,7 @@ buffertls_writecb(int fd, short event, v
if (res = 0)
goto error;
}
+   buftls-bt_flags = ~BT_WRITE_AGAIN;
 
event_set(bufev-ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
if (EVBUFFER_LENGTH(bufev-output) != 0)
@@ -202,6 +203,7 @@ buffertls_writecb(int fd, short event, v
return;
 
  reschedule:
+   buftls-bt_flags |= BT_WRITE_AGAIN;
if (EVBUFFER_LENGTH(bufev-output) != 0)
bufferevent_add(bufev-ev_write, bufev-timeout_write);
return;
@@ -276,6 +278,7 @@ buffertls_set(struct buffertls *buftls, 
event_set(bufev-ev_write, fd, EV_WRITE, buffertls_writecb, buftls);
buftls-bt_bufev = bufev;
buftls-bt_ctx = ctx;
+   buftls-bt_flags = 0;
 }
 
 void
Index: usr.sbin/syslogd/evbuffer_tls.h
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/evbuffer_tls.h,v
retrieving revision 1.1
diff -u -p -r1.1 evbuffer_tls.h
--- usr.sbin/syslogd/evbuffer_tls.h 18 Jan 2015 19:37:59 -  1.1
+++ usr.sbin/syslogd/evbuffer_tls.h 19 Feb 2015 16:47:44 -
@@ -28,6 +28,8 @@ struct buffertls {
struct bufferevent  *bt_bufev;
struct tls  *bt_ctx;
const char  *bt_hostname;
+   int  bt_flags;
+#define BT_WRITE_AGAIN 0x1
 };
 
 void   buffertls_set(struct buffertls *, struct bufferevent *, struct tls *,
Index: usr.sbin/syslogd/syslogd.c
===
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.156
diff -u -p -r1.156 syslogd.c
--- usr.sbin/syslogd/syslogd.c  14 Feb 2015 09:02:15 -  1.156
+++ usr.sbin/syslogd/syslogd.c  19 Feb 2015 16:47:44 -
@@ -1265,8 +1265,22 @@ fprintlog(struct filed *f, int flags, ch
}
break;
 
-   case F_FORWTCP:
case F_FORWTLS:
+   if (f-f_un.f_forw.f_buftls.bt_flags  BT_WRITE_AGAIN) {
+   /*
+* After an OpenSSL SSL_ERROR_WANT_WRITE you must not
+* modify the buffer pointer or length until the next
+* successful write.  Otherwise there will be an
+* error SSL3_WRITE_PENDING:bad write retry.
+* XXX This should be handled in 

Re: fusefs_readdir() should set eofflag

2015-02-19 Thread Ted Unangst
Martin Natano wrote:
 fuse_readdir() fails to set the eofflag correctly. The consequence of
 this is, that callers of VOP_READDIR, that examine the value of the
 eofflag after the call, might be mislead about the eof status, as the
 flag hasn't been modified (and my even be uninitialized).
 
 The manual page for VOP_READDIR() mentions, that the eofflag is set to a
 non-zero value when the eof of the directory contents has (successfully)
 been reached, but in the following diff I chose to also in addition set
 the flag to 0 when eof has not been reached for uniformity with other
 filesystem implementations.

Thanks, fixed.

 @@ -733,6 +734,9 @@
  
   fb_delete(fbuf);
   }
 +
 + if (!error  ap-a_eofflag != NULL)
 + *ap-a_eofflag = eofflag;

Is the null check here necessary? Other file systems don't do this, so I'm
wondering if you encountered a null pointer here.



Double fault handling on amd64

2015-02-19 Thread Wei Liu
Hi all

When I was trying to debug a double fault on 5.6, I found the trap frame
looked a bit strange. After some investigation and reading source
code, I found that double fault handling looked problematic.

Per Intel SDM volume 3A, processor will push 0 to stack as error code when
double fault occurs. Shouldn't it use TRAP instead of ZTRAP in vector.S?
I think i386's locore.S looks OK in that regard.

I only started reading OpenBSD source code since yesterday, feel free
to correct / ignore me if I'm wrong.

Wei.

--- vector.S.~1.34.~Sat Nov  2 14:23:38 2013
+++ vector.SThu Feb 19 12:01:16 2015
@@ -126,7 +126,7 @@
call_C_LABEL(fpudna)
INTRFASTEXIT
 IDTVEC(trap08)
-   ZTRAP(T_DOUBLEFLT)
+   TRAP(T_DOUBLEFLT)
 IDTVEC(trap09)
ZTRAP(T_FPOPFLT)
 IDTVEC(trap0a)



diff xmalloc

2015-02-19 Thread Ted Unangst
For after release, but since I was looking in the file...

Some of the checks in xmalloc.c are excessive. I think we've moved past the
mid-90s era when coping with various busted libcs was important for ssh (where
this file originated). I'll note that the error messages aren't particuarly
helpful in many cases (NULL) and even incorrect (xfree calls err() but doesn't
set errno).

Gathering up NULL checks in one place makes sense; imposing some sort of
runtime portability check doesn't.


Index: diffdir.c
===
RCS file: /cvs/src/usr.bin/diff/diffdir.c,v
retrieving revision 1.43
diff -u -p -r1.43 diffdir.c
--- diffdir.c   16 Jan 2015 06:40:07 -  1.43
+++ diffdir.c   19 Feb 2015 15:02:26 -
@@ -166,13 +166,13 @@ diffdir(char *p1, char *p2, int flags)
 closem:
if (dirp1 != NULL) {
for (dp1 = dirp1; dp1  edp1; dp1++)
-   xfree(*dp1);
-   xfree(dirp1);
+   free(*dp1);
+   free(dirp1);
}
if (dirp2 != NULL) {
for (dp2 = dirp2; dp2  edp2; dp2++)
-   xfree(*dp2);
-   xfree(dirp2);
+   free(*dp2);
+   free(dirp2);
}
 }
 
Index: diffreg.c
===
RCS file: /cvs/src/usr.bin/diff/diffreg.c,v
retrieving revision 1.85
diff -u -p -r1.85 diffreg.c
--- diffreg.c   5 Feb 2015 12:59:57 -   1.85
+++ diffreg.c   19 Feb 2015 15:02:47 -
@@ -385,7 +385,7 @@ diffreg(char *file1, char *file2, int fl
case -1:
warnx(No more processes);
status |= 2;
-   xfree(header);
+   free(header);
rval = D_ERROR;
goto closem;
case 0:
@@ -406,7 +406,7 @@ diffreg(char *file1, char *file2, int fl
}
close(pfd[0]);
rewind(stdout);
-   xfree(header);
+   free(header);
}
}
prepare(0, f1, stb1.st_size, flags);
@@ -429,13 +429,13 @@ diffreg(char *file1, char *file2, int fl
clistlen = 100;
clist = xcalloc(clistlen, sizeof(*clist));
i = stone(class, slen[0], member, klist, flags);
-   xfree(member);
-   xfree(class);
+   free(member);
+   free(class);
 
J = xrealloc(J, len[0] + 2, sizeof(*J));
unravel(klist[i]);
-   xfree(clist);
-   xfree(klist);
+   free(clist);
+   free(klist);
 
ixold = xrealloc(ixold, len[0] + 2, sizeof(*ixold));
ixnew = xrealloc(ixnew, len[1] + 2, sizeof(*ixnew));
@@ -899,7 +899,7 @@ unsort(struct line *f, int l, int *b)
a[f[i].serial] = f[i].value;
for (i = 1; i = l; i++)
b[i] = a[i];
-   xfree(a);
+   free(a);
 }
 
 static int
@@ -1006,7 +1006,7 @@ ignoreline(char *line)
int ret;
 
ret = regexec(ignore_re, line, 0, NULL, 0);
-   xfree(line);
+   free(line);
return (ret == 0);  /* if it matched, it should be ignored. */
 }
 
Index: xmalloc.c
===
RCS file: /cvs/src/usr.bin/diff/xmalloc.c,v
retrieving revision 1.5
diff -u -p -r1.5 xmalloc.c
--- xmalloc.c   5 Feb 2015 12:59:57 -   1.5
+++ xmalloc.c   19 Feb 2015 15:05:00 -
@@ -27,11 +27,9 @@ xmalloc(size_t size)
 {
void *ptr;
 
-   if (size == 0)
-   errx(2, xmalloc: zero size);
ptr = malloc(size);
if (ptr == NULL)
-   err(2, NULL);
+   err(2, xmalloc %zu, size);
return ptr;
 }
 
@@ -40,14 +38,10 @@ xcalloc(size_t nmemb, size_t size)
 {
void *ptr;
 
-   if (size == 0 || nmemb == 0)
-   errx(2, xcalloc: zero size);
-   if (SIZE_MAX / nmemb  size)
-   errx(2, xcalloc: nmemb * size  SIZE_MAX);
ptr = calloc(nmemb, size);
if (ptr == NULL)
-   errx(2, xcalloc: out of memory (allocating %lu bytes),
-   (u_long)(size * nmemb));
+   err(2, xcalloc: out of memory (allocating %zu*%zu bytes),
+   nmemb, size);
return ptr;
 }
 
@@ -55,38 +49,21 @@ void *
 xrealloc(void *ptr, size_t nmemb, size_t size)
 {
void *new_ptr;
-   size_t new_size = nmemb * size;
 
-   if (new_size == 0)
-   errx(2, xrealloc: zero size);
-   if (SIZE_MAX / nmemb  size)
-   errx(2, xrealloc: nmemb * size  SIZE_MAX);
-   if (ptr == NULL)
-   new_ptr = malloc(new_size);
-   else
-   new_ptr = realloc(ptr, new_size);
+   new_ptr = reallocarray(ptr, nmemb, size);
if (new_ptr == NULL)
-   err(2, NULL);
+   err(2, xrealloc %zu*%zu, nmemb, size);

Re: splassert: rtrequest1: want 5 have 0

2015-02-19 Thread Mike Belopuhov
On 19 February 2015 at 21:30, Alexander Bluhm alexander.bl...@gmx.net wrote:
 On Wed, Feb 18, 2015 at 12:14:15PM +0100, Matthieu Herrb wrote:
 Feb 18 12:09:59 castor /bsd: splassert: rtrequest1: want 5 have 0
 Feb 18 12:09:59 castor /bsd: Starting stack trace...
 Feb 18 12:09:59 castor /bsd: splassert_check() at splassert_check+0x78
 Feb 18 12:09:59 castor /bsd: rtrequest1() at rtrequest1+0x5e
 Feb 18 12:09:59 castor /bsd: nd6_prefix_offlink() at
 nd6_prefix_offlink+0x1bf
 Feb 18 12:09:59 castor /bsd: pfxlist_onlink_check() at
 pfxlist_onlink_check+0x25e
 Feb 18 12:09:59 castor /bsd: in6_control() at in6_control+0x894
 Feb 18 12:09:59 castor /bsd: ifioctl() at ifioctl+0x175
 Feb 18 12:09:59 castor /bsd: sys_ioctl() at sys_ioctl+0x169
 Feb 18 12:09:59 castor /bsd: syscall() at syscall+0x297
 Feb 18 12:09:59 castor /bsd: --- syscall (number 54) ---
 Feb 18 12:09:59 castor /bsd: end of kernel
 Feb 18 12:09:59 castor /bsd: end trace frame: 0xc8115948400, count:
 249
 Feb 18 12:09:59 castor /bsd: 0xc8115715cda:
 Feb 18 12:09:59 castor /bsd: End of stack trace.
 Feb 18 12:10:00 castor /bsd: carp0: state transition: BACKUP - MASTER

 Most calls to pfxlist_onlink_check() are protected by splsoftnet.
 Only the path in your trace does not set it.  So I suggest to set
 splsoftnet() in in6_control().  I have included the dohooks() as
 this is done in IPv4.  While there I have moved some splsoftnet()
 hiding in the declarations to the beginning of the code.

 ok?

 bluhm


OK, thanks for taking a look!



Re: splassert: rtrequest1: want 5 have 0

2015-02-19 Thread Matthieu Herrb
On Thu, Feb 19, 2015 at 09:30:40PM +0100, Alexander Bluhm wrote:
 On Wed, Feb 18, 2015 at 12:14:15PM +0100, Matthieu Herrb wrote:
  Feb 18 12:09:59 castor /bsd: splassert: rtrequest1: want 5 have 0
  Feb 18 12:09:59 castor /bsd: Starting stack trace...
  Feb 18 12:09:59 castor /bsd: splassert_check() at splassert_check+0x78
  Feb 18 12:09:59 castor /bsd: rtrequest1() at rtrequest1+0x5e
  Feb 18 12:09:59 castor /bsd: nd6_prefix_offlink() at
  nd6_prefix_offlink+0x1bf
  Feb 18 12:09:59 castor /bsd: pfxlist_onlink_check() at
  pfxlist_onlink_check+0x25e
  Feb 18 12:09:59 castor /bsd: in6_control() at in6_control+0x894
  Feb 18 12:09:59 castor /bsd: ifioctl() at ifioctl+0x175
  Feb 18 12:09:59 castor /bsd: sys_ioctl() at sys_ioctl+0x169
  Feb 18 12:09:59 castor /bsd: syscall() at syscall+0x297
  Feb 18 12:09:59 castor /bsd: --- syscall (number 54) ---
  Feb 18 12:09:59 castor /bsd: end of kernel
  Feb 18 12:09:59 castor /bsd: end trace frame: 0xc8115948400, count:
  249
  Feb 18 12:09:59 castor /bsd: 0xc8115715cda:
  Feb 18 12:09:59 castor /bsd: End of stack trace.
  Feb 18 12:10:00 castor /bsd: carp0: state transition: BACKUP - MASTER
 
 Most calls to pfxlist_onlink_check() are protected by splsoftnet.
 Only the path in your trace does not set it.  So I suggest to set
 splsoftnet() in in6_control().  I have included the dohooks() as
 this is done in IPv4.  While there I have moved some splsoftnet()
 hiding in the declarations to the beginning of the code.
 
 ok?

This fixes the issue (which was reproducible) for me. so ok as far as
I understand the issue.

 
 bluhm
 
 Index: netinet6/in6.c
 ===
 RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/in6.c,v
 retrieving revision 1.152
 diff -u -p -r1.152 in6.c
 --- netinet6/in6.c27 Jan 2015 10:34:27 -  1.152
 +++ netinet6/in6.c19 Feb 2015 18:47:06 -
 @@ -552,6 +552,7 @@ in6_control(struct socket *so, u_long cm
   pr-ndpr_refcnt++;
   }
  
 + s = splsoftnet();
   /*
* this might affect the status of autoconfigured addresses,
* that is, this address might make other addresses detached.
 @@ -559,6 +560,7 @@ in6_control(struct socket *so, u_long cm
   pfxlist_onlink_check();
  
   dohooks(ifp-if_addrhooks, 0);
 + splx(s);
   break;
   }
  
 Index: netinet6/nd6_rtr.c
 ===
 RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6_rtr.c,v
 retrieving revision 1.97
 diff -u -p -r1.97 nd6_rtr.c
 --- netinet6/nd6_rtr.c27 Jan 2015 03:17:36 -  1.97
 +++ netinet6/nd6_rtr.c19 Feb 2015 17:39:18 -
 @@ -707,10 +707,10 @@ defrouter_reset(void)
  void
  defrouter_select(void)
  {
 - int s = splsoftnet();
   struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL;
   struct rtentry *rt = NULL;
   struct llinfo_nd6 *ln = NULL;
 + int s = splsoftnet();
  
   /*
* This function should be called only when acting as an autoconfigured
 @@ -1139,12 +1139,13 @@ prelist_update(struct nd_prefix *new, st
   struct ifaddr *ifa;
   struct ifnet *ifp = new-ndpr_ifp;
   struct nd_prefix *pr;
 - int s = splsoftnet();
 - int error = 0;
 + int s, error = 0;
   int tempaddr_preferred = 0, autoconf = 0, statique = 0;
   int auth;
   struct in6_addrlifetime lt6_tmp;
   char addr[INET6_ADDRSTRLEN];
 +
 + s = splsoftnet();
  
   auth = 0;
   if (m) {
 

-- 
Matthieu Herrb



Re: syslogd SSL3_WRITE_PENDING:bad write retry

2015-02-19 Thread Ted Unangst
Alexander Bluhm wrote:
 Anyway, libtls is locked.  We can either release a broken syslogd
 over TLS implementation or commit this diff.  It has the smallest
 impact of everything I have tried.
 
 ok or better idea?

ok



Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Maxime Villard
Hi,
I put here a bug among others:

-- sys/net/pf_ioctl.c --

1027qs = pool_get(pf_queue_pl, PR_WAITOK|PR_LIMITFAIL|PR_ZERO);
if (qs == NULL) {
error = ENOMEM;
break;
}
bcopy(q-queue, qs, sizeof(*qs));
qs-qid = pf_qname2qid(qs-qname, 1);
if (qs-parent[0]  (qs-parent_qid =
pf_qname2qid(qs-parent, 0)) == 0)
return (ESRCH);



'qs' is leaked.

Found by The Brainy Code Scanner.

Maxime



Re: iwm(4): fix multicast receive

2015-02-19 Thread Brad Smith

On 02/19/15 12:01, Stefan Sperling wrote:

This fixes IPv6 autoconf over iwm for me. iwm users please test.


Does the trick for me.

--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.



iwm(4): fix multicast receive

2015-02-19 Thread Stefan Sperling
This fixes IPv6 autoconf over iwm for me. iwm users please test.

Index: if_iwm.c
===
RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
retrieving revision 1.18
diff -u -p -r1.18 if_iwm.c
--- if_iwm.c11 Feb 2015 01:12:42 -  1.18
+++ if_iwm.c19 Feb 2015 16:54:00 -
@@ -251,6 +251,7 @@ int iwm_prepare_card_hw(struct iwm_softc
 void   iwm_apm_config(struct iwm_softc *);
 intiwm_apm_init(struct iwm_softc *);
 void   iwm_apm_stop(struct iwm_softc *);
+intiwm_allow_mcast(struct iwm_softc *);
 intiwm_start_hw(struct iwm_softc *);
 void   iwm_stop_device(struct iwm_softc *);
 void   iwm_set_pwr(struct iwm_softc *);
@@ -5034,6 +5035,11 @@ iwm_auth(struct iwm_softc *sc)
int error;
 
in-in_assoc = 0;
+
+   error = iwm_allow_mcast(sc);
+   if (error)
+   return error;
+
if ((error = iwm_mvm_mac_ctxt_add(sc, in)) != 0) {
DPRINTF((%s: failed to add MAC\n, DEVNAME(sc)));
return error;
@@ -,6 +5561,32 @@ iwm_init_hw(struct iwm_softc *sc)
return error;
 }
 
+/* Allow multicast from our BSSID. */
+int
+iwm_allow_mcast(struct iwm_softc *sc)
+{
+   struct ieee80211com *ic = sc-sc_ic;
+   struct ieee80211_node *ni = ic-ic_bss;
+   struct iwm_mcast_filter_cmd *cmd;
+   size_t size;
+   int error;
+
+   size = roundup(sizeof(*cmd), 4);
+   cmd = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
+   if (cmd == NULL)
+   return ENOMEM;
+   cmd-filter_own = 1;
+   cmd-port_id = 0;
+   cmd-count = 0;
+   cmd-pass_all = 1;
+   IEEE80211_ADDR_COPY(cmd-bssid, ni-ni_bssid);
+
+   error = iwm_mvm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD,
+   IWM_CMD_SYNC, sizeof(*cmd), cmd);
+   free(cmd, M_DEVBUF, size);
+   return error;
+}
+
 /*
  * ifnet interfaces
  */
@@ -6126,6 +6158,9 @@ iwm_notif_intr(struct iwm_softc *sc)
}
wakeup(sc-sc_auth_prot);
break; }
+
+   case IWM_MCAST_FILTER_CMD:
+   break;
 
default:
printf(%s: frame %d/%d %x UNHANDLED (this should 



Re: Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Todd C. Miller
On Thu, 19 Feb 2015 18:31:01 -0500, Ted Unangst wrote:

 Thanks. I see two cases here where we need to pool_put the qs. Also need to
 change return to break so that we release the rwlock.

Not to mention the splx().  OK millert@

 - todd



Re: Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Alexander Bluhm
On Thu, Feb 19, 2015 at 06:31:01PM -0500, Ted Unangst wrote:
 Maxime Villard wrote:
  Hi,
  I put here a bug among others:
 
 Thanks. I see two cases here where we need to pool_put the qs. Also need to
 change return to break so that we release the rwlock.
 
 
 Index: pf_ioctl.c
 ===
 RCS file: /cvs/src/sys/net/pf_ioctl.c,v
 retrieving revision 1.282
 diff -u -p -r1.282 pf_ioctl.c
 --- pf_ioctl.c10 Feb 2015 06:45:55 -  1.282
 +++ pf_ioctl.c19 Feb 2015 23:28:33 -
 @@ -1032,10 +1032,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
   bcopy(q-queue, qs, sizeof(*qs));
   qs-qid = pf_qname2qid(qs-qname, 1);
   if (qs-parent[0]  (qs-parent_qid =
 - pf_qname2qid(qs-parent, 0)) == 0)
 - return (ESRCH);
 + pf_qname2qid(qs-parent, 0)) == 0) {
 + pool_put(pf_queue_pl, qs);
 + error = ESRCH;
 + break;
 + }
   qs-kif = pfi_kif_get(qs-ifname);
   if (!qs-kif-pfik_ifp) {

pfi_kif_get() may return NULL.  And if it mallocs the kif, we would
leak it here.  But it does not set pfik_ifp.  I think this check
should be if (qs-kif == NULL).

 + pool_put(pf_queue_pl, qs);
   error = ESRCH;
   break;
   }

Otherwise OK bluhm@



Re: Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Ted Unangst
Maxime Villard wrote:
 Hi,
 I put here a bug among others:

Thanks. I see two cases here where we need to pool_put the qs. Also need to
change return to break so that we release the rwlock.


Index: pf_ioctl.c
===
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.282
diff -u -p -r1.282 pf_ioctl.c
--- pf_ioctl.c  10 Feb 2015 06:45:55 -  1.282
+++ pf_ioctl.c  19 Feb 2015 23:28:33 -
@@ -1032,10 +1032,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
bcopy(q-queue, qs, sizeof(*qs));
qs-qid = pf_qname2qid(qs-qname, 1);
if (qs-parent[0]  (qs-parent_qid =
-   pf_qname2qid(qs-parent, 0)) == 0)
-   return (ESRCH);
+   pf_qname2qid(qs-parent, 0)) == 0) {
+   pool_put(pf_queue_pl, qs);
+   error = ESRCH;
+   break;
+   }
qs-kif = pfi_kif_get(qs-ifname);
if (!qs-kif-pfik_ifp) {
+   pool_put(pf_queue_pl, qs);
error = ESRCH;
break;
}



Re: Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Ted Unangst
Alexander Bluhm wrote:
 On Thu, Feb 19, 2015 at 06:31:01PM -0500, Ted Unangst wrote:
  Maxime Villard wrote:
   Hi,
   I put here a bug among others:
  
  Thanks. I see two cases here where we need to pool_put the qs. Also need to
  change return to break so that we release the rwlock.
  
  
  Index: pf_ioctl.c
  ===
  RCS file: /cvs/src/sys/net/pf_ioctl.c,v
  retrieving revision 1.282
  diff -u -p -r1.282 pf_ioctl.c
  --- pf_ioctl.c  10 Feb 2015 06:45:55 -  1.282
  +++ pf_ioctl.c  19 Feb 2015 23:28:33 -
  @@ -1032,10 +1032,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
  bcopy(q-queue, qs, sizeof(*qs));
  qs-qid = pf_qname2qid(qs-qname, 1);
  if (qs-parent[0]  (qs-parent_qid =
  -   pf_qname2qid(qs-parent, 0)) == 0)
  -   return (ESRCH);
  +   pf_qname2qid(qs-parent, 0)) == 0) {
  +   pool_put(pf_queue_pl, qs);
  +   error = ESRCH;
  +   break;
  +   }
  qs-kif = pfi_kif_get(qs-ifname);
  if (!qs-kif-pfik_ifp) {
 
 pfi_kif_get() may return NULL.  And if it mallocs the kif, we would
 leak it here.  But it does not set pfik_ifp.  I think this check
 should be if (qs-kif == NULL).

Yes. That is consistent with other callers.


Index: pf_ioctl.c
===
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.282
diff -u -p -r1.282 pf_ioctl.c
--- pf_ioctl.c  10 Feb 2015 06:45:55 -  1.282
+++ pf_ioctl.c  20 Feb 2015 01:00:29 -
@@ -1032,10 +1032,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
bcopy(q-queue, qs, sizeof(*qs));
qs-qid = pf_qname2qid(qs-qname, 1);
if (qs-parent[0]  (qs-parent_qid =
-   pf_qname2qid(qs-parent, 0)) == 0)
-   return (ESRCH);
+   pf_qname2qid(qs-parent, 0)) == 0) {
+   pool_put(pf_queue_pl, qs);
+   error = ESRCH;
+   break;
+   }
qs-kif = pfi_kif_get(qs-ifname);
-   if (!qs-kif-pfik_ifp) {
+   if (qs-kif == NULL) {
+   pool_put(pf_queue_pl, qs);
error = ESRCH;
break;
}



Re: Brainy: Kernel Memory Leak in PF

2015-02-19 Thread Alexander Bluhm
On Thu, Feb 19, 2015 at 08:01:01PM -0500, Ted Unangst wrote:
 Yes. That is consistent with other callers.

OK bluhm@

 Index: pf_ioctl.c
 ===
 RCS file: /cvs/src/sys/net/pf_ioctl.c,v
 retrieving revision 1.282
 diff -u -p -r1.282 pf_ioctl.c
 --- pf_ioctl.c10 Feb 2015 06:45:55 -  1.282
 +++ pf_ioctl.c20 Feb 2015 01:00:29 -
 @@ -1032,10 +1032,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
   bcopy(q-queue, qs, sizeof(*qs));
   qs-qid = pf_qname2qid(qs-qname, 1);
   if (qs-parent[0]  (qs-parent_qid =
 - pf_qname2qid(qs-parent, 0)) == 0)
 - return (ESRCH);
 + pf_qname2qid(qs-parent, 0)) == 0) {
 + pool_put(pf_queue_pl, qs);
 + error = ESRCH;
 + break;
 + }
   qs-kif = pfi_kif_get(qs-ifname);
 - if (!qs-kif-pfik_ifp) {
 + if (qs-kif == NULL) {
 + pool_put(pf_queue_pl, qs);
   error = ESRCH;
   break;
   }



Re: USBD_NO_COPY problems

2015-02-19 Thread David Higgs
On Feb 13, 2015, at 7:29 AM, David Higgs hig...@gmail.com wrote:
 On Friday, February 13, 2015, Martin Pieuchot mpieuc...@nolizard.org wrote:
 On 13/02/15(Fri) 00:28, David Higgs wrote:
  I guess nobody else has tried calling uhidev_get_report_async() yet.  :)
 
  First I was getting a NULL pointer deref in the uhidev async callback.
  Then I realized that due to USBD_NO_COPY, xfer-buffer was always
  NULL.  Next, I tried to use the DMA buffer, but I ended up in DDB in a
  very cryptic way.  I believe this is because the DMA buffer isn't
  available when the callback is invoked.
 
  For the async callback to get a valid dmabuf, it needs to be invoked
  prior to usb_freemem() in usbd_transfer_complete().  The xfer-status
  determination would need to move up too.  I'd do this myself but I
  don't understand the logic and ordering of pipe-repeat stuff, and am
  concerned about unintentionally breaking other devices.
 
  This is partially my fault, because I tested the original diff that
  added the USBD_NO_COPY semantics to verify that it didn't break my
  synchronous code paths, but hadn't yet written anything for upd(4) to
  check the async ones.
 
 Does the diff below help? 
 
 Partially but not enough.  I had already figured out that I needed that to 
 solve the NULL pointer dereference.  See my 2nd paragraph above.
 
OK, I figured out my issue - the crazy DDB backtrace is produced when you 
execute a NULL callback.

It still doesn’t seem legal for the callback to access DMA buffer contents 
after they are “freed”.  I assume this won’t work in all cases (host 
controllers / architectures / cache behaviors), but I don’t experience any 
problems in my i386 VM.  I tried reordering parts of usbd_transfer_complete(), 
but DIAGNOSTIC code became very unhappy with the results.

Fortunately, the diff below doesn’t touch that code path and just fixes the 
uhidev layer.  My async upd(4) changes will be forthcoming in a different 
thread.

Thanks.

--david

Index: uhidev.c
===
RCS file: /cvs/src/sys/dev/usb/uhidev.c,v
retrieving revision 1.69
diff -u -p -r1.69 uhidev.c
--- uhidev.c22 Jan 2015 10:27:47 -  1.69
+++ uhidev.c20 Feb 2015 02:27:29 -
@@ -53,6 +53,7 @@
 #include dev/usb/usbdi.h
 #include dev/usb/usbdi_util.h
 #include dev/usb/usbdivar.h
+#include dev/usb/usb_mem.h
 #include dev/usb/hid.h
 #include dev/usb/usb_quirks.h
 
@@ -747,15 +748,17 @@ void
 uhidev_get_report_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status err)
 {
struct uhidev_async_info *info = priv;
+   char *buf;
int len = -1;
 
if (err == USBD_NORMAL_COMPLETION || err == USBD_SHORT_XFER) {
len = xfer-actlen;
+   buf = KERNADDR(xfer-dmabuf, 0);
if (info-id  0) {
len--;
-   memcpy(info-data, xfer-buffer + 1, len);
+   memcpy(info-data, buf + 1, len);
} else {
-   memcpy(info-data, xfer-buffer, len);
+   memcpy(info-data, buf, len);
}
}
info-callback(info-priv, info-id, info-data, len);
@@ -803,7 +806,7 @@ uhidev_get_report_async(struct uhidev_so
USETW(req.wIndex, sc-sc_ifaceno);
USETW(req.wLength, len);
 
-   if (usbd_request_async(xfer, req, priv, uhidev_get_report_async_cb)) {
+   if (usbd_request_async(xfer, req, info, uhidev_get_report_async_cb)) {
free(info, M_TEMP, sizeof(*info));
actlen = -1;
}