On Sat, Jul 30, 2016 at 08:02:56PM +0200, Jeremie Courreges-Anglas wrote:
> 
> Theo Buehler <t...@math.ethz.ch> writes:
> 
> > On Sat, Jul 30, 2016 at 06:30:40PM +0200, Joerg Jung wrote:
> >> 
> >> > Am 30.07.2016 um 18:07 schrieb Theo Buehler <t...@math.ethz.ch>:
> >> > 
> >> > Currently, slock only clears the entered passwd buffer as part of
> >> > auth_userokay(3). If the user aborts the password entry with ESC or
> >> > clears the entered password with multiple backspaces, a cleartext
> >> > copy of the entered password is kept in memory. Use explicit_bzero()
> >> > to avoid this.
> >> 
> >> I think this is a useful addition.
> >> 
> >> You should try to bring this patch upstream (but be 
> >> prepared for flames).
> >
> > Thanks, I will try to do that when I have a patch that compiles without
> > additional warnings.
> >
> >> slock already contains various ifdef's so maybe add
> >> an #ifdef __OpenBSD__ around the explicit_bzero() 
> >> because AFAIK it is non-portable.
> >
> > Right, added.
> 
> The fact that it is not portable doesn't mean that it isn't / it won't
> be available on other platforms.  FreeBSD has it for example.
> 
> Those ifdefs don't serve any purpose in the ports tree, will (should)
> be rejected upstream and will do more harm than good in the larger
> ecosystem. You don't want new unix code to look like unix code from the
> 80's.
> 
> There are alternatives, eg use a macro that could look like
> CLEAR_PASSWORD(p, len) with a fallback implementation using memset.
> Then, a better implementation would be used if the user appropriately
> adds -DHAVE_EXPLICIT_BZERO to CPPFLAGS in config.mk.
> 
> Anyway, please don't add those #ifdef __OpenBSD__.

Thanks for this input, all this makes a lot of sense. I went with your
idea of adding a CLEAR_PASSWORD() macro.

> >> > While there, add __dead and printf attributes to the die() function.
> 
> The #ifdef __OpenBSD__ check is unrelated to the gcc attributes support.
> If you want ifdefs here, have a look at /usr/include/sys/cdefs.h.

I removed the ifdef's here.

[...]

> > The problem seems to be that it is guarded by
> >
> > #if __BSD_VISIBLE
> >
> > and I don't know why that isn't defined
> 
> Because slock.c starts with #define _XOPEN_SOURCE 500.  See sys/cdefs.h.

Okay, now I understand why __BSD_VISIBLE isn't defined, but I'm still
unsure about the proper way of dealing with this. For now I went with
jung@'s suggestion of adding -D_BSD_SOURCE to config.mk, which seems to
be a legitimate way of asking explicitly for __BSD_VISIBLE, if I read
sys/cdefs.h correctly.

Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/slock/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- Makefile    6 Jul 2016 21:34:15 -0000       1.14
+++ Makefile    30 Jul 2016 19:07:26 -0000
@@ -3,7 +3,7 @@
 COMMENT=               simple X screen locker
 
 DISTNAME=              slock-1.3
-REVISION=              0
+REVISION=              1
 
 CATEGORIES=            x11
 
Index: patches/patch-config_mk
===================================================================
RCS file: /cvs/ports/x11/slock/patches/patch-config_mk,v
retrieving revision 1.8
diff -u -p -r1.8 patch-config_mk
--- patches/patch-config_mk     5 Mar 2016 19:17:01 -0000       1.8
+++ patches/patch-config_mk     30 Jul 2016 19:07:26 -0000
@@ -1,7 +1,7 @@
 $OpenBSD: patch-config_mk,v 1.8 2016/03/05 19:17:01 jung Exp $
 --- config.mk.orig     Fri Feb 12 20:29:02 2016
-+++ config.mk  Sat Feb 27 10:43:40 2016
-@@ -4,28 +4,28 @@ VERSION = 1.3
++++ config.mk  Sat Jul 30 21:05:27 2016
+@@ -4,28 +4,29 @@ VERSION = 1.3
  # Customize below to fit your system
  
  # paths
@@ -25,7 +25,8 @@ $OpenBSD: patch-config_mk,v 1.8 2016/03/
 -CPPFLAGS = -DVERSION=\"${VERSION}\" -DHAVE_SHADOW_H
 -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
 -LDFLAGS = -s ${LIBS}
-+CPPFLAGS += -DVERSION=\"${VERSION}\" -DHAVE_BSD_AUTH
++CPPFLAGS += -DVERSION=\"${VERSION}\" -DHAVE_BSD_AUTH \
++          -DHAVE_EXPLICIT_BZERO -D_BSD_SOURCE
 +CFLAGS += -std=c99 -pedantic -Wall ${INCS} ${CPPFLAGS}
 +LDFLAGS += ${LIBS}
  
Index: patches/patch-slock_c
===================================================================
RCS file: patches/patch-slock_c
diff -N patches/patch-slock_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-slock_c       30 Jul 2016 19:07:26 -0000
@@ -0,0 +1,46 @@
+$OpenBSD$
+--- slock.c.orig       Fri Feb 12 20:29:02 2016
++++ slock.c    Sat Jul 30 21:04:33 2016
+@@ -23,6 +23,12 @@
+ #include <bsd_auth.h>
+ #endif
+ 
++#ifdef HAVE_EXPLICIT_BZERO
++#define CLEAR_PASSWORD(p, len) explicit_bzero((p), (len))
++#else
++#define CLEAR_PASSWORD(p, len) memset((p), 0, (len))
++#endif
++
+ enum {
+       INIT,
+       INPUT,
+@@ -47,7 +53,7 @@ static Bool rr;
+ static int rrevbase;
+ static int rrerrbase;
+ 
+-static void
++static void __attribute__((__noreturn__, __format__(printf, 1, 2)))
+ die(const char *errstr, ...)
+ {
+       va_list ap;
+@@ -172,10 +178,12 @@ readpw(Display *dpy, const char *pws)
+                               break;
+                       case XK_Escape:
+                               len = 0;
++                              CLEAR_PASSWORD(passwd, sizeof(passwd));
+                               break;
+                       case XK_BackSpace:
+                               if (len)
+                                       --len;
++                              CLEAR_PASSWORD(passwd + len, 1);
+                               break;
+                       default:
+                               if (num && !iscntrl((int)buf[0]) && (len + num 
< sizeof(passwd))) {
+@@ -185,6 +193,7 @@ readpw(Display *dpy, const char *pws)
+                               break;
+                       }
+                       color = len ? INPUT : (failure || failonclear ? FAILED 
: INIT);
++                      CLEAR_PASSWORD(buf, sizeof(buf));
+                       if (running && oldc != color) {
+                               for (screen = 0; screen < nscreens; screen++) {
+                                       XSetWindowBackground(dpy, 
locks[screen]->win, locks[screen]->colors[color]);

Reply via email to