Encrypted password causes segmentation fault

Bug #1698758 reported by John Bester on 2017-06-19
This bug affects 1 person
Affects Status Importance Assigned to Milestone
libapache2-mod-auth-pgsql (Debian)
libapache2-mod-auth-pgsql (Ubuntu)
Andreas Hasenack

Bug Description

I have configured a .htaccess to use libapache2-mod-auth-pgsql to authenticate a user against a postgres database. The settings are as follows:

AuthType basic
AuthName "My Auth"
Require valid-user
AuthBasicProvider pgsql
Auth_PG_authoritative On
Auth_PG_port 5432
Auth_PG_user www
Auth_PG_pwd password
Auth_PG_database userdb
Auth_PG_encrypted off
Auth_PG_pwd_table UserLogin
Auth_PG_uid_field Username
Auth_PG_pwd_field ApachePassword

If I set Auth_PG_encrypted to off, then authentication works but the downside is that I have to save plain unencrypted password on the database. If I set Auth_PG_encrypted to on, a segmentation fault occurs. A typical password to be contained in ApachePassword field is the following (for password "password"): "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=" - This matches exactly to what would be generated by htpasswd -s.

Here is the error log entry I get:
[pid 9662] AH00052: child pid 9670 exit signal Segmentation fault (11)

ProblemType: Bug
DistroRelease: Ubuntu 16.04
Package: apache2 2.4.18-2ubuntu3.2
ProcVersionSignature: Ubuntu 4.4.0-79.100-generic 4.4.67
Uname: Linux 4.4.0-79-generic x86_64
Apache2ConfdDirListing: False
 Error: command ['/usr/sbin/apachectl', '-D DUMP_MODULES'] failed with exit code 1: [Mon Jun 19 09:48:04.146971 2017] [so:warn] [pid 8403] AH01574: module dav_module is already loaded, skipping
 apache2: Syntax error on line 140 of /etc/apache2/apache2.conf: Syntax error on line 2 of /etc/apache2/mods-enabled/session_dbd.load: Cannot load /usr/lib/apache2/modules/mod_session_dbd.so into server: /usr/lib/apache2/modules/mod_session_dbd.so: undefined symbol: ap_hook_session_save
 Action '-D DUMP_MODULES' failed.
 The Apache error log may have more information.
ApportVersion: 2.20.1-0ubuntu2.6
Architecture: amd64
Date: Mon Jun 19 09:47:34 2017
SourcePackage: apache2
UpgradeStatus: No upgrade log present (probably fresh install)
modified.conffile..etc.apache2.apache2.conf: [modified]
modified.conffile..etc.apache2.mods-available.dav.load: [modified]
modified.conffile..etc.apache2.sites-available.000-default.conf: [modified]
mtime.conffile..etc.apache2.apache2.conf: 2017-06-03T16:27:12.439856
mtime.conffile..etc.apache2.mods-available.dav.load: 2017-06-03T16:31:51.028040
mtime.conffile..etc.apache2.sites-available.000-default.conf: 2016-11-11T14:57:50

Related branches

John Bester (john-bester) wrote :
Andreas Hasenack (ahasenack) wrote :

Confirmed in my xenial testing:

==> /var/log/apache2/error.log <==
[Tue Jun 20 18:44:20.612899 2017] [core:notice] [pid 7038:tid 140431534086016] AH00051: child pid 7041 exit signal Segmentation fault (11), possible coredump in /etc/apache2

Changed in apache2 (Ubuntu):
importance: Undecided → High
status: New → Triaged
tags: added: server-next
Changed in apache2 (Ubuntu):
assignee: nobody → Andreas Hasenack (ahasenack)
status: Triaged → In Progress
Andreas Hasenack (ahasenack) wrote :

It's segfaulting because of this odd usage of crypt(3):
                        sent_pw = (char *) crypt(sent_pw, real_pw);

That returns NULL, because in the SHA case the real_pw contains the { character which is invalid for the second parameter which is meant to be the salt.

Later on strcmp is used and that's what causes the segfault.

I can't reach the upstream website: http://www.giuseppetanzilli.it/mod_auth_pgsql2/

I wonder if it's abandoned, or just a temporary issue.

Andreas Hasenack (ahasenack) wrote :

Ok, got a better hang of it. crypt(3) can indeed be used like that, but the code needs to check for it returning NULL in the case of errors:
diff --git a/mod_auth_pgsql.c b/mod_auth_pgsql.c
index 0a16e05..4f80917 100644
--- a/mod_auth_pgsql.c
+++ b/mod_auth_pgsql.c
@@ -868,6 +868,12 @@ static authn_status check_password(request_rec *r, const char *user,
                case AUTH_PG_HASH_TYPE_CRYPT:
                        sent_pw = (char *) crypt(sent_pw, real_pw);
+ if (!sent_pw) {
+ apr_snprintf(pg_errstr, MAX_STRING_LEN,
+ "PG user %s: password mismatch", user);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr);
+ return AUTH_DENIED;
+ }
                case AUTH_PG_HASH_TYPE_BASE64:
                        sent_pw = auth_pg_base64(sent_pw);

What happened is that the hash format you used, "{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=", is not the type of input crypt(3) expects for the salt argument, hence the NULL return value (and the crash since that wasn't checked for).

The salt argument (the second argument) should either be:
- 2 characters for standard DES from the range [a-zA-Z0-9./]. Note how "{" or "}" are not there
- $id$salt$encrypted, where id means:
              ID | Method
              1 | MD5
              2a | Blowfish (not in mainline glibc; added in some
                  | Linux distributions)
              5 | SHA-256 (since glibc 2.7)
              6 | SHA-512 (since glibc 2.7)

So the above patch fixes the crash, but you should use a different type of hash format. {SHA} is not supported. It is supported by apache's apr_password_validate(), but that is not used in this code.

Andreas Hasenack (ahasenack) wrote :

One can use mkpasswd(1) from the "whois" package (!) to generate these hashes supported by crypt(3):
$ mkpasswd -5 secret

$ mkpasswd -m sha-256 secret

$ mkpasswd -m sha-512 secret $6$mbXQ/gDvUCn$Hs6sz8LAWN3fX1I/MoaJjsYSIYs8tqOUjgoQnXLY4X1dTSlBhbyiJYpTZZDEALXw.hRL97e7l/.xI7qZi0Phe.

and of course plain DES:
$ mkpasswd secret

All of the above are supported by libapache2-mod-auth-pgsql's "Auth_PG_hash_type CRYPT".

affects: apache2 (Ubuntu) → libapache2-mod-auth-pgsql (Ubuntu)
Changed in libapache2-mod-auth-pgsql (Debian):
status: Unknown → New
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.