Well it seems I was wrong and this is a common-or-garden bug. Specifically, 
from xauth/gethost.c, starting at line 199:

#ifdef HAVE_STRLCPY
            strlcpy(path, fulldpyname, sizeof(path));
#else
            strncpy(path, fulldpyname, sizeof(path));
            path[sizeof(path) - 1] = '\0';
#endif
            if (0 == stat(path, &sbuf)) {
                is_path_to_socket = 1;
            } else {
                char *dot = strrchr(path, '.');
                if (dot) {
                    *dot = '\0';
                    /* screen = atoi(dot + 1); */
                    if (0 == stat(path, &sbuf)) {
                        is_path_to_socket = 1;
                    }
                }
            }

fulldpyname is "drogo.datum:0" and there is a directory in $HOME named "drogo".

is_path_to_socket then gets set to 1 and the strlcpy(buf, strrchr(fulldpyname, 
'/') + 1, sizeof(buf)) a few lines down passes 0x01 as the source pointer to 
strlcpy.

I don't know if it is or should be required that $DISPLAY pointing to a unix 
socket can be a relative path, but if they must be absolute then this patch 
enforces that (and fixes my segfault, though by making the same assumption that 
$DISPLAY will include a '/' in two places).

Matthew

Index: parsedpy.c
===================================================================
RCS file: /home/flask/src/openbsd/cvsync/xenocara/app/xauth/parsedpy.c,v
retrieving revision 1.5
diff -u -p -r1.5 parsedpy.c
--- parsedpy.c  19 Feb 2017 17:30:58 -0000      1.5
+++ parsedpy.c  18 Oct 2019 12:02:34 -0000
@@ -177,7 +177,7 @@ parse_displayname (const char *displayna
 #endif
         if (0 == stat(path, &sbuf)) {
             family = FamilyLocal;
-        } else {
+        } else if (strrchr(path, '/') == path) { /* I'm not sure this is the 
best way to test for this */
             char *dot = strrchr(path, '.');
             if (dot) {
                 *dot = '\0';

Reply via email to