Bug 987394 - (CVE-2016-6153) VUL-2: CVE-2016-6153: sqlite2,sqlite3: SQLite Tempdir Selection Vulnerability
(CVE-2016-6153)
VUL-2: CVE-2016-6153: sqlite2,sqlite3: SQLite Tempdir Selection Vulnerability
Status: RESOLVED FIXED
Classification: Novell Products
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents
unspecified
Other Other
: P3 - Medium : Minor
: ---
Assigned To: Security Team bot
Security Team bot
maint:running:62888:moderate CVSSv2:S...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-07-01 16:07 UTC by Andreas Stieger
Modified: 2021-04-06 18:46 UTC (History)
3 users (show)

See Also:
Found By: Security Response Team
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Stieger 2016-07-01 16:07:40 UTC
KL-001-2016-003 : SQLite Tempdir Selection Vulnerability

Title: SQLite Tempdir Selection Vulnerability
Advisory ID: KL-001-2016-003
Publication Date: 2016.07.01
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2016-003.txt


1. Vulnerability Details

     Affected Vendor: SQLite/Hwaci
     Affected Product: SQLite
     Affected Version: All versions prior to 3.13.0
     Platform: UNIX, GNU/Linux
     CWE Classification: CWE-379: Creation of Temporary File in Directory
                         with Incorrect Permissions
     Impact: Data Leakage
     Attack vector: Local

2. Vulnerability Description

     Usually processes writing to temporary directories do not need to
     perform readdir() because they control the filenames they create, so
     setting /tmp/ , /var/tmp/ , etc. to be mode 1733 is a not uncommon
     UNIX hardening practice.

     Affected versions of SQLite reject potential tempdir locations if
     they are not readable, falling back to '.'.  Thus, SQLite will favor
     e.g. using cwd for tempfiles on such a system, even if cwd is an
     unsafe location.  Notably, SQLite also checks the permissions of '.',
     but ignores the results of that check.

     By itself, this is only a POLA (Principle of Least Astonishment)
     violation that may cause unexpected failures.  However, this might
     in turn cause software that uses SQLite libraries to behave in
     unsafe ways, leaking sensitive data, opening up SQLite libraries to
     attack by deliberately corrupted tempfiles, etc.


3. Technical Description

     SQLite creates tempfiles only under certain specific circumstances,
     and the behavior is tunable in various ways; see
     https://www.sqlite.org/tempfiles.html for more background.
     Generally speaking, the below does not apply for rollback journals,
     master journals, write-ahead log (WAL) files, or shared-memory
     (-shm) files.  They may apply for various other tempfile types.

     When a tempfile must be created, sanity checks are performed on
     candidate tempdir locations; these checks are flawed.

     src/os_unix.c (which is merged into sqlite3.c during the
     release-tarball preparation process) performs these checks when
     considering candidate temporary directory locations (quoted from
     commit 0064a8c77b, 2016-02-23):

       /*
       ** Return the name of a directory in which to put temporary files.
       ** If no suitable temporary file directory can be found, return NULL.
       */
       static const char *unixTempFileDir(void){
         static const char *azDirs[] = {
            0,
            0,
            "/var/tmp",
            "/usr/tmp",
            "/tmp",
            "."
         };
         unsigned int i;
         struct stat buf;
         const char *zDir = sqlite3_temp_directory;

         if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
         if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
         for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
           if( zDir==0 ) continue;
           if( osStat(zDir, &buf) ) continue;
           if( !S_ISDIR(buf.st_mode) ) continue;
           if( osAccess(zDir, 07) ) continue;
           break;
         }
         return zDir;
       }

     osAccess is defined elsewhere as a wrapper around the access system
     call:

         { "access",       (sqlite3_syscall_ptr)access,     0  },
       #define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)

     So, a candidate directory will be rejected if it does not match mode
     07; that is to say it must be readable, writable, and executable.

     Furthermore, the comment that "If no suitable temporary file
     directory can be found, return NULL." is incorrect: in fact, if all
     directories including "." fail, then "." is returned, because zDir
     has already been assigned before the checks fail.  (Also,
     unixGetTempname, which calls unixTempFileDir, does not check if NULL
     was returned.)

     The specific lines of code embodying this check have subtly changed
     a dozen times over SQLite's history (and things like the NULL check
     might have been valid in some past version).  The first time a check
     for readability was included appears to have been in fossil commit
     e7b65e37fd, imported from this CVS commit:

       -** @(#) $Id: KL-001-2016-003.txt,v 1.1 2016/07/01 15:48:13 hlein Exp $
       +** @(#) $Id: KL-001-2016-003.txt,v 1.1 2016/07/01 15:48:13 hlein Exp $


          for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
       -    if( stat(azDirs[i], &buf)==0 && S_ISDIR(buf.st_mode)
       -         && access(azDirs[i], W_OK) ){
       -       return azDirs[i];
       -    }
       +    if( stat(azDirs[i], &buf) ) continue;
       +    if( !S_ISDIR(buf.st_mode) ) continue;
       +    if( access(azDirs[i], 07) ) continue;
       +    return azDirs[i];
          }

     As seen here, prior to 2001.09.14 the only permission checked was
     W_OK, writability.  The commit message for e7b65e37fd does not call
     out this change; perhaps there was some problem that changing from
     W_OK to R_OK+W_OK+X_OK was intended to solve at the time.

     As stated above, this by itself is only a POLA violation: a
     developer or system administrator might not expect a candidate
     temporary directory to be rejected if it is not readable.  This
     would result in SQLITE_TMPDIR , TMPDIR , /var/tmp , /tmp , etc.
     being rejected by the above if they are mode 1733 or similar, and
     also cause sqlite to fail at runtime if cwd is not writable.

     SQLite does the right things when creating its tempfile, once the
     tempdir is chosen.  It randomly generates the filename (although
     weirdly, using a home-grown implementation instead of mkstemp,
     possibly for cross-platform purposes), uses file mode 600, with good
     file-open flags (O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC), etc.  If
     possible (such as for 'TEMP' databases), the file is unlinked
     immediately.

     However, this could lead to insecure behavior by some application
     using SQLite under these conditions.  As a contrived example, a
     program which writes sensitive data to an sqlite database, and
     during execution chdir()'s to a directory in which it is not safe to
     write sensitive data even temporarily, such as an NFS or SMB network
     share (allowing network capture), or a removable device which will
     later leave the user's physical control (leaving on-disk residue,
     possibly mitigated by SQLite's SECURE_DELETE settings).

     It is also possible that the failure of unixTempFileDir to return
     NULL, and of unixGetTempname to check for that NULL, may lead to
     abrupt crashes or otherwise unexpected or undefined behavior by the
     calling program when "." is also not writable.

4. Mitigation and Remediation Recommendation

     The vendor released version 3.13.0 on 2016.05.18 in which the reported
     vulnerability was patched. Release notes available at:
     https://www.sqlite.org/releaselog/3_13_0.html

5. Credit

     This vulnerability was discovered by Hank Leininger of KoreLogic, Inc.

6. Disclosure Timeline

     2016.03.24 - KoreLogic sends vulnerability report and PoC to SQLite.
     2016.03.24 - SQLite acknowledges receipt of vulnerability report.
     2016.04.21 - KoreLogic asks for an update on the remediation effort.
     2016.04.21 - SQLite responds that the vulnerability has been patched
                  and will be public in the next update.
     2016.05.18 - SQLite 3.13.0 released.
     2016.07.01 - Public disclosure.

7. Proof of Concept

     ########################################################################
     #
     # Copyright 2016 KoreLogic Inc., All Rights Reserved.
     #
     # This proof of concept, having been partly or wholly developed
     # and/or sponsored by KoreLogic, Inc., is hereby released under
     # the terms and conditions set forth in the Creative Commons
     # Attribution Share-Alike 4.0 (United States) License:
     #
     #   http://creativecommons.org/licenses/by-sa/4.0/
     #
     #######################################################################*

     Reproduction using the sqlite3 binary (but an application linked
     against libsqlite would behave similarly):

patsy@foo ~/sqlite-test $ ls -la
total 16
drwxr-xr-x  4 root  root  4096 Feb 23 22:45 .
drwxr-xr-x 19 patsy root  4096 Feb 23 23:04 ..
drwx-wx-wt  2 root  patsy 4096 Feb 23 22:41 tmp
drwxrwxrwx  2 patsy patsy 4096 Feb 23 22:45 unsafe

patsy@foo ~/sqlite-test $ export TMPDIR=~/sqlite-test/tmp
patsy@foo ~/sqlite-test $ cd unsafe
patsy@foo ~/sqlite-test/unsafe $ sqlite3
SQLite version 3.10.2 2016-01-20 15:27:19
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TEMP TABLE testtemp(text);
sqlite>

foo ~ # ls -l /proc/$(pidof sqlite3)/fd/ | egrep /patsy/
lrwx------ 1 patsy patsy 64 Feb 23 23:04 3 -> /home/patsy/sqlite-test/unsafe/etilqs_1974c47b45a40cc9 (deleted)
lrwx------ 1 patsy patsy 64 Feb 23 23:04 4 -> /home/patsy/sqlite-test/unsafe/etilqs_81d3a73a2307205a (deleted)
Comment 1 Andreas Stieger 2016-07-01 17:40:41 UTC
Commits:

http://www.sqlite.org/cgi/src/info/67985761aa93fb61
Change the temporary directory search algorithm on unix so that directories with only -wx permission are allowed. And do not allow "." to be returned if it lacks -wx permission. 

http://www.sqlite.org/cgi/src/info/b38fe522cfc971b3
Fix the fix to the temporary directory search algorithm so that it continues to return "." as a fallback if that directory has the correct permissions. 

http://www.sqlite.org/cgi/src/info/614bb709d34e1148
Fix the temporary directory search algorithm for unix so that it fails gracefully even if all candidate directories are inaccessible. This fixes a bug that was introduced by check-in [9b8fec60d8e].
Comment 2 Andreas Stieger 2016-07-01 21:09:02 UTC
CVE-2016-6153 was assigned to this issue
http://seclists.org/oss-sec/2016/q3/1
Comment 3 Swamp Workflow Management 2016-07-01 22:00:28 UTC
bugbot adjusting priority
Comment 4 Swamp Workflow Management 2016-07-04 11:18:58 UTC
An update workflow for this issue was started.
This issue was rated as moderate.
Please submit fixed packages until 2016-07-18.
When done, reassign the bug to security-team@suse.de.
https://swamp.suse.de/webswamp/wf/62888
Comment 5 Reinhard Max 2016-07-21 16:18:47 UTC
Done for sqlite3 on SLE11-SP2, SLE12* and 13.2.

The code for SLE11-SP0 is quite different and would need more backporting and testing effort, so please let me know if we need it for this (or anything else) as well.
Comment 7 Andreas Stieger 2016-07-22 14:09:26 UTC
(In reply to Reinhard Max from comment #5)
> The code for SLE11-SP0 is quite different and would need more backporting
> and testing effort, so please let me know if we need it for this (or
> anything else) as well.

Do not progress further, as on second consideration the vulnerability has somewhat esoteric triggers. We'll take the submitted ones.
Comment 8 Swamp Workflow Management 2016-08-01 03:13:43 UTC
openSUSE-SU-2016:1932-1: An update that fixes one vulnerability is now available.

Category: security (low)
Bug References: 987394
CVE References: CVE-2016-6153
Sources used:
openSUSE 13.2 (src):    sqlite3-3.8.6-3.1
Comment 9 Swamp Workflow Management 2016-08-03 17:09:17 UTC
SUSE-SU-2016:1945-1: An update that fixes one vulnerability is now available.

Category: security (moderate)
Bug References: 987394
CVE References: CVE-2016-6153
Sources used:
SUSE Linux Enterprise Software Development Kit 12-SP1 (src):    sqlite3-3.8.10.2-3.1
SUSE Linux Enterprise Server 12-SP1 (src):    sqlite3-3.8.10.2-3.1
SUSE Linux Enterprise Desktop 12-SP1 (src):    sqlite3-3.8.10.2-3.1
Comment 10 Swamp Workflow Management 2016-08-10 10:09:38 UTC
SUSE-SU-2016:2021-1: An update that fixes one vulnerability is now available.

Category: security (moderate)
Bug References: 987394
CVE References: CVE-2016-6153
Sources used:
SUSE Studio Onsite 1.3 (src):    sqlite3-3.7.6.3-1.4.6.1
SUSE Linux Enterprise Software Development Kit 11-SP4 (src):    sqlite3-3.7.6.3-1.4.6.1
SUSE Linux Enterprise Server 11-SP4 (src):    sqlite3-3.7.6.3-1.4.6.1
SUSE Linux Enterprise Debuginfo 11-SP4 (src):    sqlite3-3.7.6.3-1.4.6.1
Comment 11 Swamp Workflow Management 2016-08-11 15:19:13 UTC
openSUSE-SU-2016:2041-1: An update that fixes one vulnerability is now available.

Category: security (moderate)
Bug References: 987394
CVE References: CVE-2016-6153
Sources used:
openSUSE Leap 42.1 (src):    sqlite3-3.8.10.2-7.1
Comment 12 Marcus Meissner 2017-10-26 05:46:11 UTC
released
Comment 13 he zhiping 2017-11-16 04:42:06 UTC
Did this CVE have been fixed for SLES11-SP3? Because in this CVE page, the state of SLES11-SP3 was released, but there was no download link provided for SLES11-SP3 in List of released packages. Our customer wanted a fixed version for SLES11-SP3, thanks.
Comment 15 Swamp Workflow Management 2019-04-17 16:10:42 UTC
SUSE-SU-2019:0973-1: An update that fixes three vulnerabilities is now available.

Category: security (moderate)
Bug References: 1119687,1131576,987394
CVE References: CVE-2016-6153,CVE-2018-20346,CVE-2018-20506
Sources used:
SUSE Linux Enterprise Server 12-LTSS (src):    sqlite3-3.8.3.1-2.7.1

*** NOTE: This information is not intended to be used for external
    communication, because this may only be a partial fix.
    If you have questions please reach out to maintenance coordination.