]> granicus.if.org Git - postgresql/commitdiff
Replace a bunch more uses of strncpy() with safer coding.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Jan 2015 18:05:42 +0000 (13:05 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 24 Jan 2015 18:05:42 +0000 (13:05 -0500)
strncpy() has a well-deserved reputation for being unsafe, so make an
effort to get rid of nearly all occurrences in HEAD.

A large fraction of the remaining uses were passing length less than or
equal to the known strlen() of the source, in which case no null-padding
can occur and the behavior is equivalent to memcpy(), though doubtless
slower and certainly harder to reason about.  So just use memcpy() in
these cases.

In other cases, use either StrNCpy() or strlcpy() as appropriate (depending
on whether padding to the full length of the destination buffer seems
useful).

I left a few strncpy() calls alone in the src/timezone/ code, to keep it
in sync with upstream (the IANA tzcode distribution).  There are also a
few such calls in ecpg that could possibly do with more analysis.

AFAICT, none of these changes are more than cosmetic, except for the four
occurrences in fe-secure-openssl.c, which are in fact buggy: an overlength
source leads to a non-null-terminated destination buffer and ensuing
misbehavior.  These don't seem like security issues, first because no stack
clobber is possible and second because if your values of sslcert etc are
coming from untrusted sources then you've got problems way worse than this.
Still, it's undesirable to have unpredictable behavior for overlength
inputs, so back-patch those four changes to all active branches.

26 files changed:
contrib/fuzzystrmatch/dmetaphone.c
contrib/isn/isn.c
contrib/pg_trgm/trgm_regexp.c
contrib/pgbench/pgbench.c
contrib/pgcrypto/crypt-des.c
contrib/xml2/xpath.c
src/backend/libpq/hba.c
src/backend/postmaster/pgstat.c
src/backend/regex/regerror.c
src/backend/replication/logical/logical.c
src/backend/replication/slot.c
src/backend/utils/adt/datetime.c
src/backend/utils/adt/name.c
src/backend/utils/adt/varlena.c
src/backend/utils/error/elog.c
src/bin/initdb/initdb.c
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_backup_db.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/pgtypeslib/datetime.c
src/interfaces/ecpg/pgtypeslib/dt_common.c
src/interfaces/ecpg/test/pg_regress_ecpg.c
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/fe-protocol2.c
src/interfaces/libpq/fe-secure-openssl.c

index b1f8b78d3be11f862920d25baf9a79d54b5fed8f..7c8457e734427ed801f6e5441a2b0d5b9f4eb2e0 100644 (file)
@@ -247,7 +247,7 @@ NewMetaString(char *init_str)
        META_MALLOC(s->str, s->bufsize, char);
        assert(s->str != NULL);
 
-       strncpy(s->str, init_str, s->length + 1);
+       memcpy(s->str, init_str, s->length + 1);
        s->free_string_on_destroy = 1;
 
        return s;
index 903b9378d84bf5004c40254058dd0ae9983bc356..5fbd253491a5835bda0dfa423e2b343fd00da77d 100644 (file)
@@ -825,18 +825,18 @@ string2ean(const char *str, bool errorOK, ean13 *result,
                                goto eanwrongtype;
                        break;
                case ISMN:
-                       strncpy(buf, "9790", 4);        /* this isn't for sure yet, for now
+                       memcpy(buf, "9790", 4);         /* this isn't for sure yet, for now
                                                                                 * ISMN it's only 9790 */
                        valid = (valid && ((rcheck = checkdig(buf, 13)) == check || magic));
                        break;
                case ISBN:
-                       strncpy(buf, "978", 3);
+                       memcpy(buf, "978", 3);
                        valid = (valid && ((rcheck = weight_checkdig(buf + 3, 10)) == check || magic));
                        break;
                case ISSN:
-                       strncpy(buf + 10, "00", 2); /* append 00 as the normal issue
+                       memcpy(buf + 10, "00", 2);      /* append 00 as the normal issue
                                                                                 * publication code */
-                       strncpy(buf, "977", 3);
+                       memcpy(buf, "977", 3);
                        valid = (valid && ((rcheck = weight_checkdig(buf + 3, 8)) == check || magic));
                        break;
                case UPC:
index 529e1dbfe976fb799ac8712da12c8a0bf8d4fe02..a91e6186bae953d816d000ba9722e094a3136382 100644 (file)
@@ -877,7 +877,7 @@ convertPgWchar(pg_wchar c, trgm_mb_char *result)
 #endif
 
        /* Fill result with exactly MAX_MULTIBYTE_CHAR_LEN bytes */
-       strncpy(result->bytes, s, MAX_MULTIBYTE_CHAR_LEN);
+       memcpy(result->bytes, s, MAX_MULTIBYTE_CHAR_LEN);
        return true;
 }
 
index 25616ceff671d5789ccab416abe5d70591f377a8..ddd11a09c5b1762b59a91f2c2b5be54dc9a903ed 100644 (file)
@@ -829,7 +829,7 @@ replaceVariable(char **sql, char *param, int len, char *value)
 
        if (valueln != len)
                memmove(param + valueln, param + len, strlen(param + len) + 1);
-       strncpy(param, value, valueln);
+       memcpy(param, value, valueln);
 
        return param + valueln;
 }
index 4ed44beeff51707a2ca1b86842bbca7da4e5b647..b43141fed5cb667c508f0d8131e1be4f33b3f94f 100644 (file)
@@ -708,7 +708,7 @@ px_crypt_des(const char *key, const char *setting)
                        if (des_setkey((char *) keybuf))
                                return (NULL);
                }
-               strncpy(output, setting, 9);
+               StrNCpy(output, setting, 10);
 
                /*
                 * Double check that we weren't given a short setting. If we were, the
@@ -716,7 +716,6 @@ px_crypt_des(const char *key, const char *setting)
                 * salt, but we don't really care. Just make sure the output string
                 * doesn't have an extra NUL in it.
                 */
-               output[9] = '\0';
                p = output + strlen(output);
        }
        else
index f57b81302f3b7efed08ce8ef216fff11b78328d2..655c5322cdf21a7f107c0a86cf3b4dc3626a5fdf 100644 (file)
@@ -327,7 +327,7 @@ xpath_string(PG_FUNCTION_ARGS)
        /* We could try casting to string using the libxml function? */
 
        xpath = (xmlChar *) palloc(pathsize + 9);
-       strncpy((char *) xpath, "string(", 7);
+       memcpy((char *) xpath, "string(", 7);
        memcpy((char *) (xpath + 7), VARDATA(xpathsupp), pathsize);
        xpath[pathsize + 7] = ')';
        xpath[pathsize + 8] = '\0';
index f75c4b88be862c90def376a84ada5e6193670a1b..9cde6a21ce99003102dc9303288001d24e3ba2b6 100644 (file)
@@ -1996,6 +1996,8 @@ check_ident_usermap(IdentLine *identLine, const char *usermap_name,
 
                if ((ofs = strstr(identLine->pg_role, "\\1")) != NULL)
                {
+                       int                     offset;
+
                        /* substitution of the first argument requested */
                        if (matches[1].rm_so < 0)
                        {
@@ -2012,8 +2014,9 @@ check_ident_usermap(IdentLine *identLine, const char *usermap_name,
                         * plus null terminator
                         */
                        regexp_pgrole = palloc0(strlen(identLine->pg_role) - 2 + (matches[1].rm_eo - matches[1].rm_so) + 1);
-                       strncpy(regexp_pgrole, identLine->pg_role, (ofs - identLine->pg_role));
-                       memcpy(regexp_pgrole + strlen(regexp_pgrole),
+                       offset = ofs - identLine->pg_role;
+                       memcpy(regexp_pgrole, identLine->pg_role, offset);
+                       memcpy(regexp_pgrole + offset,
                                   ident_user + matches[1].rm_so,
                                   matches[1].rm_eo - matches[1].rm_so);
                        strcat(regexp_pgrole, ofs + 2);
index 827ad713b5850b1296ffb131754cc27b82bdbf3d..268bcd58fd8d7da3091f46a6760240a5b2876781 100644 (file)
@@ -3095,7 +3095,7 @@ pgstat_send_archiver(const char *xlog, bool failed)
         */
        pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ARCHIVER);
        msg.m_failed = failed;
-       strncpy(msg.m_xlog, xlog, sizeof(msg.m_xlog));
+       StrNCpy(msg.m_xlog, xlog, sizeof(msg.m_xlog));
        msg.m_timestamp = GetCurrentTimestamp();
        pgstat_send(&msg, sizeof(msg));
 }
index f863ee7344f4de3217d02f9787642e06b3c46748..f2fe696425c1314336e609c8097258abb2c2222f 100644 (file)
@@ -111,7 +111,7 @@ pg_regerror(int errcode,            /* error code, or REG_ATOI or REG_ITOA */
                        strcpy(errbuf, msg);
                else
                {                                               /* truncate to fit */
-                       strncpy(errbuf, msg, errbuf_size - 1);
+                       memcpy(errbuf, msg, errbuf_size - 1);
                        errbuf[errbuf_size - 1] = '\0';
                }
        }
index 939831b5576da05edef87dbff90dc89df742bb4b..30baa45383a3dc9f896755a3e0eb9f737e47a032 100644 (file)
@@ -244,9 +244,7 @@ CreateInitDecodingContext(char *plugin,
 
        /* register output plugin name with slot */
        SpinLockAcquire(&slot->mutex);
-       strncpy(NameStr(slot->data.plugin), plugin,
-                       NAMEDATALEN);
-       NameStr(slot->data.plugin)[NAMEDATALEN - 1] = '\0';
+       StrNCpy(NameStr(slot->data.plugin), plugin, NAMEDATALEN);
        SpinLockRelease(&slot->mutex);
 
        /*
index 5f64e494c5d7e3c2a60dccb5ea1a3d7c564e757d..dd7ff0f99a21e0646832f349ba38f689410e47d6 100644 (file)
@@ -266,8 +266,7 @@ ReplicationSlotCreate(const char *name, bool db_specific,
        slot->data.persistency = persistency;
        slot->data.xmin = InvalidTransactionId;
        slot->effective_xmin = InvalidTransactionId;
-       strncpy(NameStr(slot->data.name), name, NAMEDATALEN);
-       NameStr(slot->data.name)[NAMEDATALEN - 1] = '\0';
+       StrNCpy(NameStr(slot->data.name), name, NAMEDATALEN);
        slot->data.database = db_specific ? MyDatabaseId : InvalidOid;
        slot->data.restart_lsn = InvalidXLogRecPtr;
 
index 3b0402e3cfb4f33802723dd1b751875b3e1e6bf0..2a44b6e50375b353ab01676f7cb5407bef43171e 100644 (file)
@@ -4052,7 +4052,7 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, const char
                        day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
                        tm->tm_wday = j2day(day);
 
-                       strncpy(str, days[tm->tm_wday], 3);
+                       memcpy(str, days[tm->tm_wday], 3);
                        strcpy(str + 3, " ");
 
                        if (DateOrder == DATEORDER_DMY)
index fa13a9a5897db13b338566a14a51b61a3fec8a00..b6c6e393358d4d7eeae3af4ae5fd066b691b719b 100644 (file)
@@ -192,7 +192,7 @@ namecpy(Name n1, Name n2)
 {
        if (!n1 || !n2)
                return -1;
-       strncpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
+       StrNCpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
        return 0;
 }
 
index cfa192193b47e657a9d9336d1ef10e96c71ddf70..f48ce4901ca154be8b00e9cfe0e6ba979a59e71c 100644 (file)
@@ -2936,7 +2936,7 @@ SplitIdentifierString(char *rawstring, char separator,
                        len = endp - curname;
                        downname = downcase_truncate_identifier(curname, len, false);
                        Assert(strlen(downname) <= len);
-                       strncpy(curname, downname, len);
+                       strncpy(curname, downname, len);        /* strncpy is required here */
                        pfree(downname);
                }
 
index bee2c92301e52122682943c6c545e533c847df21..310c5bbffa05f87f65263b6be58abd214f7b3525 100644 (file)
@@ -2240,7 +2240,7 @@ setup_formatted_log_time(void)
 
        /* 'paste' milliseconds into place... */
        sprintf(msbuf, ".%03d", (int) (tv.tv_usec / 1000));
-       strncpy(formatted_log_time + 19, msbuf, 4);
+       memcpy(formatted_log_time + 19, msbuf, 4);
 }
 
 /*
index 9ac06086e788b697ba92eb0a45392336ec69c2e5..18614e7a678fc523ca143d98616f704b23d81329 100644 (file)
@@ -386,9 +386,9 @@ replace_token(char **lines, const char *token, const char *replacement)
 
                pre = where - lines[i];
 
-               strncpy(newline, lines[i], pre);
+               memcpy(newline, lines[i], pre);
 
-               strcpy(newline + pre, replacement);
+               memcpy(newline + pre, replacement, replen);
 
                strcpy(newline + pre + replen, lines[i] + pre + toklen);
 
index 9e6455861d92e90128b5603809cc63af4fc6e4be..f461393dc25790fe509e9423c066e93173861a31 100644 (file)
@@ -2064,7 +2064,7 @@ _discoverArchiveFormat(ArchiveHandle *AH)
        }
 
        /* Save it, just in case we need it later */
-       strncpy(&AH->lookahead[0], sig, 5);
+       memcpy(&AH->lookahead[0], sig, 5);
        AH->lookaheadLen = 5;
 
        if (strncmp(sig, "PGDMP", 5) == 0)
index 2c8778db94dfa4a1e7962ec42f9931d7d8d78c3a..5968c2032a11f7e0a235bb8a25337ed16b10e94a 100644 (file)
@@ -399,7 +399,7 @@ ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc)
                        break;
                default:
                        /* trouble */
-                       strncpy(errStmt, qry, DB_MAX_ERR_STMT);
+                       strncpy(errStmt, qry, DB_MAX_ERR_STMT);         /* strncpy required here */
                        if (errStmt[DB_MAX_ERR_STMT - 1] != '\0')
                        {
                                errStmt[DB_MAX_ERR_STMT - 4] = '.';
index a4c7151f9a3a3731dd40f06c72675a2c9a94f134..8a3dd759a1a49e766634dcadd567b0d78a3df7e8 100644 (file)
@@ -882,7 +882,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                                return false;
                                                        }
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                                       memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                        strcpy(mallocedval + strlen(mallocedval), ",");
                                                        ecpg_free(str);
                                                }
@@ -949,7 +949,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                                return false;
                                                        }
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                                       memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                        strcpy(mallocedval + strlen(mallocedval), ",");
                                                        ecpg_free(str);
                                                }
@@ -969,7 +969,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                }
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                ecpg_free(str);
                                        }
 
@@ -1000,7 +1000,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                                return false;
                                                        }
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                                       memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                        strcpy(mallocedval + strlen(mallocedval), ",");
                                                        ecpg_free(str);
                                                }
@@ -1020,7 +1020,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                }
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                ecpg_free(str);
                                        }
 
@@ -1055,7 +1055,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                                return false;
                                                        }
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                                       memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                        strcpy(mallocedval + strlen(mallocedval), ",");
                                                        ecpg_free(str);
                                                }
@@ -1075,7 +1075,7 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                }
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
                                                ecpg_free(str);
                                        }
 
index e49ae3763ccc508ce7ac843d004065a533b7a4cb..983b242d0659db89977a0acc45a565bc5c7590b7 100644 (file)
@@ -82,7 +82,7 @@ replace_variables(char **text, int lineno)
                                return false;
                        }
 
-                       strncpy(newcopy, *text, ptr);
+                       memcpy(newcopy, *text, ptr);
                        strcpy(newcopy + ptr, buffer);
                        strcat(newcopy, (*text) +ptr + len);
 
index a271cdd7d15fee0d937f6ea53a91d21a91fa1ff2..49cb817a5076b0473422f6fe58e190625c22c26b 100644 (file)
@@ -264,8 +264,8 @@ PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf)
                        {
                                case PGTYPES_TYPE_STRING_MALLOCED:
                                case PGTYPES_TYPE_STRING_CONSTANT:
-                                       strncpy(start_pattern, replace_val.str_val,
-                                                       strlen(replace_val.str_val));
+                                       memcpy(start_pattern, replace_val.str_val,
+                                                  strlen(replace_val.str_val));
                                        if (replace_type == PGTYPES_TYPE_STRING_MALLOCED)
                                                free(replace_val.str_val);
                                        break;
@@ -277,7 +277,7 @@ PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf)
                                                        return -1;
                                                snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
                                                                 "%u", replace_val.uint_val);
-                                               strncpy(start_pattern, t, strlen(t));
+                                               memcpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
                                        break;
@@ -289,7 +289,7 @@ PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf)
                                                        return -1;
                                                snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
                                                                 "%02u", replace_val.uint_val);
-                                               strncpy(start_pattern, t, strlen(t));
+                                               memcpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
                                        break;
@@ -301,7 +301,7 @@ PGTYPESdate_fmt_asc(date dDate, const char *fmtstring, char *outbuf)
                                                        return -1;
                                                snprintf(t, PGTYPES_DATE_NUM_MAX_DIGITS,
                                                                 "%04u", replace_val.uint_val);
-                                               strncpy(start_pattern, t, strlen(t));
+                                               memcpy(start_pattern, t, strlen(t));
                                                free(t);
                                        }
                                        break;
index 7fdd09b3068ee9a2e77a0d6fc8e9db5caed91782..7fe29820cf037a0843be84c6b1f30ed6c787ca38 100644 (file)
@@ -929,7 +929,7 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, bool print_tz, int tz, const char *t
                        day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
                        tm->tm_wday = (int) ((day + date2j(2000, 1, 1) + 1) % 7);
 
-                       strncpy(str, days[tm->tm_wday], 3);
+                       memcpy(str, days[tm->tm_wday], 3);
                        strcpy(str + 3, " ");
 
                        if (EuroDates)
index 16dd44056135879b1fba368d8942f07ea329334e..a4d443291dca04077e16baf382a87691e513ee5a 100644 (file)
@@ -60,8 +60,7 @@ ecpg_filter(const char *sourcefile, const char *outfile)
                        if (plen > 1)
                        {
                                n = (char *) malloc(plen);
-                               strncpy(n, p + 1, plen - 1);
-                               n[plen - 1] = '\0';
+                               StrNCpy(n, p + 1, plen);
                                replace_string(linebuf, n, "");
                        }
                }
index 0d2e59cec5c085b502f90c03a7a1f747c3da33be..691202894fa06bcfa1ff60e62079ec57b57fae66 100644 (file)
@@ -2910,9 +2910,9 @@ PQoidStatus(const PGresult *res)
                return "";
 
        len = strspn(res->cmdStatus + 7, "0123456789");
-       if (len > 23)
-               len = 23;
-       strncpy(buf, res->cmdStatus + 7, len);
+       if (len > sizeof(buf) - 1)
+               len = sizeof(buf) - 1;
+       memcpy(buf, res->cmdStatus + 7, len);
        buf[len] = '\0';
 
        return buf;
index 1eeb97669833c344e32dbc12e3a7d40b9ec879c9..eeba7f35047089d849864f18ee4db5f5a348ca26 100644 (file)
@@ -1586,6 +1586,7 @@ pqBuildStartupPacket2(PGconn *conn, int *packetlen,
 
        startpacket->protoVersion = htonl(conn->pversion);
 
+       /* strncpy is safe here: postmaster will handle full fields correctly */
        strncpy(startpacket->user, conn->pguser, SM_USER);
        strncpy(startpacket->database, conn->dbName, SM_DATABASE);
        strncpy(startpacket->tty, conn->pgtty, SM_TTY);
index d8b5995f5b4c8067d7c6ed7fca5d2e7a626c24de..8cdf53ec7f8f1199e9e6deda7f1dfb5769f13c17 100644 (file)
@@ -941,7 +941,7 @@ initialize_SSL(PGconn *conn)
 
        /* Read the client certificate file */
        if (conn->sslcert && strlen(conn->sslcert) > 0)
-               strncpy(fnbuf, conn->sslcert, sizeof(fnbuf));
+               strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
        else if (have_homedir)
                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
        else
@@ -1132,7 +1132,7 @@ initialize_SSL(PGconn *conn)
 #endif   /* USE_SSL_ENGINE */
                {
                        /* PGSSLKEY is not an engine, treat it as a filename */
-                       strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
+                       strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
                }
        }
        else if (have_homedir)
@@ -1195,7 +1195,7 @@ initialize_SSL(PGconn *conn)
         * verification after the connection has been completed.
         */
        if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
-               strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
+               strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
        else if (have_homedir)
                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
        else
@@ -1233,7 +1233,7 @@ initialize_SSL(PGconn *conn)
                if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
                {
                        if (conn->sslcrl && strlen(conn->sslcrl) > 0)
-                               strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
+                               strlcpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
                        else if (have_homedir)
                                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
                        else