Re: __read_mostly

2022-03-24 Thread Theo de Raadt
Ingo Schwarze  wrote:

> Hi,
> 
> >> A downside of this is that it becomes easier to guess the addresses
> >> of the tagged variables.
> 
> > No kidding.  It partly undoes the effort of KARL.  
> 
> I don't feel qualified to comment on the patch,
> but i can't resist mentioning that i still love
> tedu@'s classical dictum "attack mitigation countermeasures"
> which he coined during the aftermath of the heartbleed debacle.

true, true.

That said, it is a small setset of objects.  The small set of objects
will still be randomly ordered within that region.  As the number of objects
increases, it becomes harder for an attacker to guess the relative-fixed
offset from one object (assuming they get a pointer) to specific other object.

So perhaps this is still acceptable?



Re: fix very small ntpd leak

2022-03-24 Thread Otto Moerbeek
On Thu, Mar 24, 2022 at 10:34:52AM +1000, Jonathan Matthew wrote:

> On Wed, Mar 23, 2022 at 04:59:06PM +0100, Otto Moerbeek wrote:
> > On Wed, Mar 23, 2022 at 09:09:01PM +1000, Jonathan Matthew wrote:
> > 
> > > We noticed that the ntpd engine process was getting a bit big on some 
> > > boxes
> > > that we'd accidentally cut off from the ntp servers (routing is hard).
> > > Reading through the code, I noticed the 'query' member of struct ntp_peer
> > > is never freed, which seems to account for the leak.
> > > 
> > > If you have a server pool in ntpd.conf and it resolves, but ntpd is unable
> > > to talk to the servers, it will re-resolve periodically, freeing the old 
> > > list
> > > of peers and creating new ones.
> > > 
> > > To show how slow the leak is, here's the leak report from MALLOC_OPTIONS=D
> > > after running for about two hours with four servers from two pools.
> > > 
> > > without diff:
> > >  
> > > Leak report
> > >  f sum  #avg
> > >0x09392128 73
> > >  0x889878b920b 512  1512
> > >  0x889878bc8e14096  4   1024
> > >  0x889878bd065 128  2 64
> > >  0x88bc91f0b4b   18280  1  18280
> > >  0x88bc926a9ed   65536  1  65536
> > >  
> > >  
> > > with diff:
> > >  
> > > Leak report
> > >  f sum  #avg
> > >0x06064 16379
> > >  0xbee1253320b 512  1512
> > >  0xbf0265f4b4b   18280  1  18280
> > >  0xbf02666e9ed   65536  1  65536
> > > 
> > > ok?
> > > 
> > > Index: ntp.c
> > > ===
> > > RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
> > > retrieving revision 1.168
> > > diff -u -p -r1.168 ntp.c
> > > --- ntp.c 24 Oct 2021 21:24:19 -  1.168
> > > +++ ntp.c 23 Mar 2022 10:43:59 -
> > > @@ -686,6 +686,7 @@ void
> > >  peer_remove(struct ntp_peer *p)
> > >  {
> > >   TAILQ_REMOVE(>ntp_peers, p, entry);
> > > + free(p->query);
> > >   free(p);
> > >   peer_cnt--;
> > >  }
> > > 
> > 
> > This is a bug that dlg reported last week. Serendepity or not? :-)
> 
> We found it together looking at systems we run at work, so not really.

heh, dlg was talking about a collegue but i did not connnect that to you,

anyway, thanks for the analysis,

-Otto

> 
> > 
> > This is my diff that uses an approach I like a litle bit better.
> 
> I agree.  I wasn't sure if there was a reason the query was allocated
> separately, so I went with the more straightforward diff to start with.
> 
> > 
> > -Otto
> > 
> > Index: client.c
> > ===
> > RCS file: /cvs/src/usr.sbin/ntpd/client.c,v
> > retrieving revision 1.116
> > diff -u -p -r1.116 client.c
> > --- client.c21 Apr 2021 09:38:11 -  1.116
> > +++ client.c21 Mar 2022 07:31:54 -
> > @@ -51,10 +51,9 @@ set_deadline(struct ntp_peer *p, time_t 
> >  int
> >  client_peer_init(struct ntp_peer *p)
> >  {
> > -   if ((p->query = calloc(1, sizeof(struct ntp_query))) == NULL)
> > -   fatal("client_peer_init calloc");
> > -   p->query->fd = -1;
> > -   p->query->msg.status = MODE_CLIENT | (NTP_VERSION << 3);
> > +   p->query.fd = -1;
> > +   p->query.msg.status = MODE_CLIENT | (NTP_VERSION << 3);
> > +   p->query.xmttime = 0;
> > p->state = STATE_NONE;
> > p->shift = 0;
> > p->trustlevel = TRUSTLEVEL_PATHETIC;
> > @@ -91,7 +90,7 @@ client_addr_init(struct ntp_peer *p)
> > }
> > }
> >  
> > -   p->query->fd = -1;
> > +   p->query.fd = -1;
> > set_next(p, 0);
> >  
> > return (0);
> > @@ -100,9 +99,9 @@ client_addr_init(struct ntp_peer *p)
> >  int
> >  client_nextaddr(struct ntp_peer *p)
> >  {
> > -   if (p->query->fd != -1) {
> > -   close(p->query->fd);
> > -   p->query->fd = -1;
> > +   if (p->query.fd != -1) {
> > +   close(p->query.fd);
> > +   p->query.fd = -1;
> > }
> >  
> > if (p->state == STATE_DNS_INPROGRESS)
> > @@ -148,26 +147,26 @@ client_query(struct ntp_peer *p)
> > if (p->state < STATE_DNS_DONE || p->addr == NULL)
> > return (-1);
> >  
> > -   if (p->query->fd == -1) {
> > +   if (p->query.fd == -1) {
> > struct sockaddr *sa = (struct sockaddr *)>addr->ss;
> > struct sockaddr *qa4 = (struct sockaddr *)>query_addr4;
> > struct sockaddr *qa6 = (struct sockaddr *)>query_addr6;
> >  
> > -   if ((p->query->fd = socket(p->addr->ss.ss_family, SOCK_DGRAM,
> > +   if ((p->query.fd = socket(p->addr->ss.ss_family, SOCK_DGRAM,
> > 0)) == -1)
> > fatal("client_query socket");
> >  
> > if (p->addr->ss.ss_family == qa4->sa_family) {
> > -   if (bind(p->query->fd, qa4, SA_LEN(qa4)) == -1)
> > +   if (bind(p->query.fd, qa4, SA_LEN(qa4)) == -1)
> > 

Re: sndio: add sio_flush() function

2022-03-24 Thread Alexandre Ratchov
On Thu, Mar 24, 2022 at 07:11:42AM +0100, Alexandre Ratchov wrote:
> Most audio/video players do a stop/start cycle whenever the play
> position is changed, track is changed, etc. Currently, stopping drains
> the play buffer, which by default is very large (to workaround very
> long kernel non-preemptive code-paths). This makes player controls
> sluggish.
> 
> This diff adds a new sio_flush() function to workaround the jumbo
> buffer sizes: it stops playback immediately, discarding buffered
> data. Basically it's the same as sio_stop() but doesn't wait. The plan
> is to make players use it.
> 
> In the network protocol, sio_flush() is implemented by adding a flag
> to the message corresponding to sio_stop(). Old sndiod servers ignore
> it and just work with new libraries. New sndiod servers see that the
> flag is not set by old libraries and properly drain the play buffer.
> 
> Tested with mplayer, mpv and audacious, if we go this way other ports
> will follow.
> 

Here's the diff to make mplayer, mpv and audacious use the new
function.

As you see, sio_stop() and sio_flush() are perfectly
interchangable. The only difference is the time the function takes to
complete (and the resulting silence).

Index: x11/mplayer/Makefile
===
RCS file: /cvs/ports/x11/mplayer/Makefile,v
retrieving revision 1.319
diff -u -p -r1.319 Makefile
--- x11/mplayer/Makefile11 Mar 2022 20:16:48 -  1.319
+++ x11/mplayer/Makefile23 Mar 2022 19:49:08 -
@@ -3,7 +3,7 @@ COMMENT=movie player supporting many fo
 V= 20211106
 FFMPEG_V=  4.4.1
 DISTNAME=  mplayer-${V}
-REVISION=  0
+REVISION=  1
 CATEGORIES=x11 multimedia
 MASTER_SITES=  https://comstyle.com/source/
 EXTRACT_SUFX=  .tar.xz
Index: x11/mplayer/patches/patch-libao2_ao_sndio_c
===
RCS file: x11/mplayer/patches/patch-libao2_ao_sndio_c
diff -N x11/mplayer/patches/patch-libao2_ao_sndio_c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ x11/mplayer/patches/patch-libao2_ao_sndio_c 23 Mar 2022 19:49:08 -
@@ -0,0 +1,21 @@
+Index: libao2/ao_sndio.c
+--- libao2/ao_sndio.c.orig
 libao2/ao_sndio.c
+@@ -179,7 +179,7 @@ static void uninit(int immed)
+  */
+ static void reset(void)
+ {
+-if (!sio_stop(hdl))
++if (!sio_flush(hdl))
+ mp_msg(MSGT_AO, MSGL_ERR, "ao2: reset: couldn't stop\n");
+ delay = 0;
+ if (!sio_start(hdl))
+@@ -235,7 +235,7 @@ static void audio_pause(void)
+  * sndio can't pause, so just stop
+  */
+ prepause_delay = delay;
+-if (!sio_stop(hdl))
++if (!sio_flush(hdl))
+ mp_msg(MSGT_AO, MSGL_ERR, "ao2: pause: couldn't stop\n");
+ delay = 0;
+ }
Index: multimedia/mpv/Makefile
===
RCS file: /cvs/ports/multimedia/mpv/Makefile,v
retrieving revision 1.81
diff -u -p -r1.81 Makefile
--- multimedia/mpv/Makefile 11 Mar 2022 19:39:24 -  1.81
+++ multimedia/mpv/Makefile 23 Mar 2022 19:49:08 -
@@ -4,7 +4,7 @@ GH_ACCOUNT =mpv-player
 GH_PROJECT =   mpv
 GH_TAGNAME =   v0.34.1
 
-REVISION = 0
+REVISION = 1
 
 SHARED_LIBS += mpv 0.2 # 1.109
 
Index: multimedia/mpv/patches/patch-audio_out_ao_sndio_c
===
RCS file: /cvs/ports/multimedia/mpv/patches/patch-audio_out_ao_sndio_c,v
retrieving revision 1.6
diff -u -p -r1.6 patch-audio_out_ao_sndio_c
--- multimedia/mpv/patches/patch-audio_out_ao_sndio_c   11 Mar 2022 19:39:24 
-  1.6
+++ multimedia/mpv/patches/patch-audio_out_ao_sndio_c   23 Mar 2022 19:49:09 
-
@@ -245,8 +245,8 @@ Index: audio/out/ao_sndio.c
 +if (p->playing) {
 +p->playing = false;
 +
-+if (!sio_stop(p->hdl)) {
-+MP_ERR(ao, "reset: couldn't sio_stop()\n");
++if (!sio_flush(p->hdl)) {
++MP_ERR(ao, "reset: couldn't sio_flush()\n");
 +}
 +p->delay = 0;
 +if (!sio_start(p->hdl)) {
Index: audio/audacious/plugins/Makefile
===
RCS file: /cvs/ports/audio/audacious/plugins/Makefile,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile
--- audio/audacious/plugins/Makefile8 Mar 2022 08:53:50 -   1.10
+++ audio/audacious/plugins/Makefile23 Mar 2022 19:49:09 -
@@ -1,7 +1,7 @@
 COMMENT =  input and output plugins for Audacious
 
 DISTNAME = audacious-plugins-${VERSION}
-REVISION = 2
+REVISION = 3
 
 # BSD / GPL
 PERMIT_PACKAGE =   Yes
Index: audio/audacious/plugins/patches/patch-src_sndio_sndio_cc
===
RCS file: audio/audacious/plugins/patches/patch-src_sndio_sndio_cc
diff -N audio/audacious/plugins/patches/patch-src_sndio_sndio_cc
--- /dev/null 

sndio: add sio_flush() function

2022-03-24 Thread Alexandre Ratchov
Most audio/video players do a stop/start cycle whenever the play
position is changed, track is changed, etc. Currently, stopping drains
the play buffer, which by default is very large (to workaround very
long kernel non-preemptive code-paths). This makes player controls
sluggish.

This diff adds a new sio_flush() function to workaround the jumbo
buffer sizes: it stops playback immediately, discarding buffered
data. Basically it's the same as sio_stop() but doesn't wait. The plan
is to make players use it.

In the network protocol, sio_flush() is implemented by adding a flag
to the message corresponding to sio_stop(). Old sndiod servers ignore
it and just work with new libraries. New sndiod servers see that the
flag is not set by old libraries and properly drain the play buffer.

Tested with mplayer, mpv and audacious, if we go this way other ports
will follow.

ok?

Index: include/sndio.h
===
RCS file: /cvs/src/include/sndio.h,v
retrieving revision 1.13
diff -u -p -r1.13 sndio.h
--- include/sndio.h 28 Jun 2020 05:21:38 -  1.13
+++ include/sndio.h 23 Mar 2022 20:23:29 -
@@ -164,6 +164,7 @@ size_t sio_write(struct sio_hdl *, const
 size_t sio_read(struct sio_hdl *, void *, size_t);
 int sio_start(struct sio_hdl *);
 int sio_stop(struct sio_hdl *);
+int sio_flush(struct sio_hdl *);
 int sio_nfds(struct sio_hdl *);
 int sio_pollfd(struct sio_hdl *, struct pollfd *, int);
 int sio_revents(struct sio_hdl *, struct pollfd *);
Index: lib/libsndio/Symbols.map
===
RCS file: /cvs/src/lib/libsndio/Symbols.map,v
retrieving revision 1.2
diff -u -p -r1.2 Symbols.map
--- lib/libsndio/Symbols.map26 Feb 2020 13:53:58 -  1.2
+++ lib/libsndio/Symbols.map23 Mar 2022 20:23:29 -
@@ -11,6 +11,7 @@
sio_read;
sio_start;
sio_stop;
+   sio_flush;
sio_nfds;
sio_pollfd;
sio_revents;
Index: lib/libsndio/amsg.h
===
RCS file: /cvs/src/lib/libsndio/amsg.h,v
retrieving revision 1.14
diff -u -p -r1.14 amsg.h
--- lib/libsndio/amsg.h 1 Nov 2021 14:43:24 -   1.14
+++ lib/libsndio/amsg.h 23 Mar 2022 20:23:29 -
@@ -96,6 +96,9 @@ struct amsg {
 #define AMSG_DATAMAX   0x1000
uint32_t size;
} data;
+   struct amsg_stop {
+   uint8_t drain;
+   } stop;
struct amsg_ts {
int32_t delta;
} ts;
Index: lib/libsndio/shlib_version
===
RCS file: /cvs/src/lib/libsndio/shlib_version,v
retrieving revision 1.12
diff -u -p -r1.12 shlib_version
--- lib/libsndio/shlib_version  26 Feb 2020 13:53:58 -  1.12
+++ lib/libsndio/shlib_version  23 Mar 2022 20:23:29 -
@@ -1,2 +1,2 @@
 major=7
-minor=1
+minor=2
Index: lib/libsndio/sio.c
===
RCS file: /cvs/src/lib/libsndio/sio.c,v
retrieving revision 1.26
diff -u -p -r1.26 sio.c
--- lib/libsndio/sio.c  1 Nov 2021 14:43:24 -   1.26
+++ lib/libsndio/sio.c  23 Mar 2022 20:23:29 -
@@ -129,6 +129,8 @@ sio_start(struct sio_hdl *hdl)
 int
 sio_stop(struct sio_hdl *hdl)
 {
+   if (hdl->ops->stop == NULL)
+   return sio_flush(hdl);
if (hdl->eof) {
DPRINTF("sio_stop: eof\n");
return 0;
@@ -139,6 +141,28 @@ sio_stop(struct sio_hdl *hdl)
return 0;
}
if (!hdl->ops->stop(hdl))
+   return 0;
+#ifdef DEBUG
+   DPRINTFN(2, "libsndio: polls: %llu, samples = %llu\n",
+   hdl->pollcnt, hdl->cpos);
+#endif
+   hdl->started = 0;
+   return 1;
+}
+
+int
+sio_flush(struct sio_hdl *hdl)
+{
+   if (hdl->eof) {
+   DPRINTF("sio_flush: eof\n");
+   return 0;
+   }
+   if (!hdl->started) {
+   DPRINTF("sio_flush: not started\n");
+   hdl->eof = 1;
+   return 0;
+   }
+   if (!hdl->ops->flush(hdl))
return 0;
 #ifdef DEBUG
DPRINTFN(2, "libsndio: polls: %llu, samples = %llu\n",
Index: lib/libsndio/sio_aucat.c
===
RCS file: /cvs/src/lib/libsndio/sio_aucat.c,v
retrieving revision 1.20
diff -u -p -r1.20 sio_aucat.c
--- lib/libsndio/sio_aucat.c9 Jan 2016 08:27:24 -   1.20
+++ lib/libsndio/sio_aucat.c23 Mar 2022 20:23:29 -
@@ -49,6 +49,7 @@ struct sio_aucat_hdl {
 static void sio_aucat_close(struct sio_hdl *);
 static int sio_aucat_start(struct sio_hdl *);
 static int sio_aucat_stop(struct sio_hdl *);
+static int sio_aucat_flush(struct sio_hdl *);
 static int sio_aucat_setpar(struct sio_hdl *, struct sio_par *);
 static int