Avoid null pointer dereference if error result lacks SQLSTATE.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 1 Nov 2020 16:26:16 +0000 (11:26 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 1 Nov 2020 16:26:16 +0000 (11:26 -0500)
Although error results received from the backend should always have
a SQLSTATE field, ones generated by libpq won't, making this code
vulnerable to a crash after, say, untimely loss of connection.
Noted by Coverity.

Oversight in commit 403a3d91c.  Back-patch to 9.5, as that was.

src/bin/pg_dump/pg_backup_db.c

index 28b2892538aec63141832c92e2616679687b534d..6a1e1d3acb26c797e8c79da7a8a878bec86a2ad8 100644 (file)
@@ -540,9 +540,9 @@ bool
 IsLockTableGeneric(Archive *AHX)
 {
        ArchiveHandle *AH = (ArchiveHandle *) AHX;
-       PGresult *res;
-       char     *sqlstate;
-       bool    retval;
+       PGresult   *res;
+       char       *sqlstate;
+       bool            retval;
 
        if (AHX->remoteVersion >= 140000)
                return true;
@@ -569,13 +569,15 @@ IsLockTableGeneric(Archive *AHX)
                        break;
                case PGRES_FATAL_ERROR:
                        sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
-                       if (strcmp(sqlstate, ERRCODE_WRONG_OBJECT_TYPE) == 0)
+                       if (sqlstate &&
+                               strcmp(sqlstate, ERRCODE_WRONG_OBJECT_TYPE) == 0)
                        {
                                retval = false;
                                break;
                        }
-                       else if (strcmp(sqlstate, ERRCODE_LOCK_NOT_AVAILABLE) == 0 ||
-                                        strcmp(sqlstate, ERRCODE_INSUFFICIENT_PRIVILEGE) == 0)
+                       else if (sqlstate &&
+                                        (strcmp(sqlstate, ERRCODE_LOCK_NOT_AVAILABLE) == 0 ||
+                                         strcmp(sqlstate, ERRCODE_INSUFFICIENT_PRIVILEGE) == 0))
                        {
                                retval = true;
                                break;