SQLite Forum

A format string vulnerability in tool used to help build SQLite's TCL extension on Windows
Login

A format string vulnerability in SQLite nmakehelp.c allows code execution via a crated file

(1) By salmonx on 2021-06-15 07:04:08 updated by 1.1 [link]

### The 'printf' in SubstituteFile accepts a format string as an argument, but the format string originates from the argv[3] which is controlled by user.


```
static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    ...

    fp = fopen(filename, "rt");
    if (fp != NULL) {
    	
    	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
    	    list_item_t *p = NULL;
    	    for (p = substPtr; p != NULL; p = p->nextPtr) {
    		char *m = strstr(szBuffer, p->key);
    		if (m) {
    		    char *cp, *op, *sp;
    		    cp = szCopy;
    		    op = szBuffer;
    		    while (op != m) *cp++ = *op++;
    		    sp = p->value;
    		    while (sp && *sp) *cp++ = *sp++;
    		    op += strlen(p->key);
    		    while (*op) *cp++ = *op++;
    		    *cp = 0;
    		    memcpy(szBuffer, szCopy, sizeof(szCopy));
    		}
    	    }
    	    printf(szBuffer); // Vulnerability
    	}
    	
    	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}
```

A format string vulnerability in tool used to help build SQLite's TCL extension on Windows

(1.1) By salmonx on 2021-06-15 11:30:34 edited from 1.0 [link]

### The 'printf' in SubstituteFile accepts a format string as an argument, but the format string originates from the argv[3] which is controlled by user.


```
static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    ...

    fp = fopen(filename, "rt");
    if (fp != NULL) {
    	
    	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
    	    list_item_t *p = NULL;
    	    for (p = substPtr; p != NULL; p = p->nextPtr) {
    		char *m = strstr(szBuffer, p->key);
    		if (m) {
    		    char *cp, *op, *sp;
    		    cp = szCopy;
    		    op = szBuffer;
    		    while (op != m) *cp++ = *op++;
    		    sp = p->value;
    		    while (sp && *sp) *cp++ = *sp++;
    		    op += strlen(p->key);
    		    while (*op) *cp++ = *op++;
    		    *cp = 0;
    		    memcpy(szBuffer, szCopy, sizeof(szCopy));
    		}
    	    }
    	    printf(szBuffer); // Vulnerability
    	}
    	
    	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}
```

(2) By Larry Brasfield (larrybr) on 2021-06-15 13:36:10 in reply to 1.1 [link]

Thanks for keeping an eye out for bugs and vulnerabilities. And please do not let the following explanation discourage such efforts.

We do not consider it a problem when somebody who builds the SQLite library has the power to sabotage their results. The tool is normally used from a process governed by a Makefile and gets sensible arguments. That it might do something bizarre when invoked bizarrely is of no consequence to the project. And, as Richard mentioned elsewhere today, the tool is not authored as part of the project; it is merely reused from an outside source. So it is not the project's concern.

(3) By Jan Nijtmans (jan.nijtmans) on 2021-07-01 06:36:08 in reply to 1.1 [link]

This has been assigned a CVE number: CVE-2021-35331

It's fixed in this commit: [https://core.tcl-lang.org/tcl/info/28ef6c0c741408a2]

And also updated in sampleextension: [https://core.tcl-lang.org/sampleextension/info/53d84c7fb2b6d2da]

(4) By Jan Nijtmans (jan.nijtmans) on 2021-07-06 08:45:34 in reply to 3

This [CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35331) now has the status **DISPUTED**, we all know why ....

(5) By Larry Brasfield (larrybr) on 2021-07-06 11:15:37 in reply to 4 [link]

(Replying only after calming myself on this "CVE".)

In addition to being of zero (non-political) consequence to the SQLite project, the revised nmakehelp.c from its source project has now replaced that "buggy" version. See <u>[check-in 595bf95](https://www.sqlite.org/src/info/595bf95bf8884c54)</u>. So, it's fixed.

BTW, all C compilers should have a CVE because they will compile:<code>
  \#include <stdlib.h>
  int main(){
    return *((int *)rand());
  }
</code>

(6) By Scott Robison (casaderobison) on 2021-07-06 18:28:19 in reply to 5 [link]

+1