CVE-2022-45866 (C++, published 2022-11-23T20:15Z)
Description: value: qpress before PierreLvx/qpress 20220819 and before version 11.3, as used in Percona XtraBackup and other products, allows directory traversal via ../ in a .qp file.
Severity: nan (CVSS v3 base score: 5.3)
Weakness: CWE-22 \u2014 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Repository: https://github.com/EvgeniyPatlan/qpress
Files changed:
qpress.cpp
Commit message: Fix qpress directory traversal vulnerability (#6)

A bad actor user can prepare the payload as:

```
mkdir -p AAAAAAAAA/secure_file_priv_dir
touch AAAAAAAAA/secure_file_priv_dir/evil.so
qpress -r AAAAAAAAA payload.qp
Then edit the payload.qp in a hex editor or sed to replace AAAAAAAAA with ../../../
(example: sed -i 's/AAAAAAAAA/..\/..\/..\//' payload.qp)
```

Fix bug by checking the directory and reject the command if find the attempt to traversal

Test: see example above and try to reproduce it. Before fix you can observe
traversal. After fix - the error message(File path contains directory traversal
which is not allowed.) shown, no traversal observe.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the BSD-new
license.  I am contributing on behalf of my employer Amazon Web Services,
Inc.

Co-authored-by: Mikhail Chalov <mcchalov@amazon.com>

Vulnerable code:
char tmp[200000];
            try_aread(tmp, chunk_size + 1); // read file name

Fixed code:
const long NAME_BUFFER_SIZE = 200000;
char tmp[NAME_BUFFER_SIZE];

bool check_if_path_has_dir_traversal(char * new_path)
{
    bool ret_val = false;
    char *found_template1 = NULL;
	found_template1 = strstr (new_path,"../");
	#ifdef WINDOWS 
	    char *found_template2 = NULL;
	    found_template2 = strstr (new_path,"..\\");
	    ret_val = (found_template1 !=  NULL) || (found_template2 != NULL);
	#else
	    ret_val = found_template1 !=  NULL;
	#endif
    
    return ret_val;
}
			if(NAME_BUFFER_SIZE < chunk_size + 1)
            {
                abort("File path string is bigger than buffer size");
            }
			/* RDS security fix: https://rds-jira.amazon.com/browse/MMCP-231
	 		Need to check if we try to decompress file or directory outside working directory
	 		*/
	        if(true == check_if_path_has_dir_traversal(tmp)) 
            {
	            abort("Directory path contains directory traversal which is not allowed.");
	        }
	        /* End of RDS security fix*/
            if(NAME_BUFFER_SIZE < chunk_size + 1)
	             {
	                 abort("File path string is bigger than buffer size");
	             }
	             try_aread(tmp, chunk_size + 1); // read file name to 'tmp' with size 'chunk_size + 1'
	         /* RDS security fix: https://rds-jira.amazon.com/browse/MMCP-231
	 		   Need to check if we try to decompress file or directory outside working directory
	 		*/
	         if(true == check_if_path_has_dir_traversal(tmp)) 
	         {
	             abort("File path contains directory traversal which is not allowed.");
	         }
	         /* End of RDS security fix*/