flamusdiu / xleapp

xLEAPP - Merging of iLEAPP/RLEAPP/vLEAPP, ALEAPP, cLEAPP
https://pypi.org/project/xleapp/
MIT License
48 stars 6 forks source link

sqlite3 OperationalError(disk I/O error) when accessing a DB with Python inside a Virtual Machine #5

Open flamusdiu opened 2 years ago

flamusdiu commented 2 years ago

I posted an SO question on the issue: sqlite3 OperationalError(disk I/O error) when accessing a DB with Python inside a Virtual Machine

Setup is as follows: [ Host (Win10) ] <- Shared Folders -> [ VM (Win10) ] The ZIP file used and the report are both stored in this shared folder between the Host and VM.

Note This does not affect iLEAPP that I can tell.

You can test this out with the following code:

import sqlite3
from pathlib import Path
# Change this to match your own system
file_path = Path(
    r'D:\VM Shares\Forensics\CTF21_Marsha_iPhoneX_FFS_Premium_2021_07_29'
    r'\xLEAPP_Reports_2021-11-23_Tuesday_115054\temp\filesystem2'
    r'\containers\Shared\SystemGroup\30CCFC92-08E6-458A-B78B-DA920EF2EF82'
    r'\Library\Database\com.apple.MobileBluetooth.ledevices.other.db')
db = sqlite3.connect(f'file:{file_path}?mode=ro', uri=True)
cursor = db.cursor()
# Test to see if we have a SQLite DB
cursor.execute("PRAGMA page_count").fetchone()

If done on my host, it works just fine without errors. If done in the VM, I get the following problem (as noted in the SO):

>>> cursor.execute("PRAGMA page_count").fetchone()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.OperationalError: disk I/O error

I did consider path length as an issue and used a modified version of open_sqlite_db_readonly from iLEAPP. Though, it did not seem to help.

The fix seems to be the following:

import sqlite3
from pathlib import Path
# Change this to match your own system
file_path = Path(
    r'D:\VM Shares\Forensics\CTF21_Marsha_iPhoneX_FFS_Premium_2021_07_29'
    r'\xLEAPP_Reports_2021-11-23_Tuesday_115054\temp\filesystem2'
    r'\containers\Shared\SystemGroup\30CCFC92-08E6-458A-B78B-DA920EF2EF82'
    r'\Library\Database\com.apple.MobileBluetooth.ledevices.other.db')
db = sqlite3.connect(f'file:{file_path}?immutable=1', uri=True)
cursor = db.cursor()
# Test to see if we have a SQLite DB
cursor.execute("PRAGMA page_count").fetchone()

I modified the connect() and changed mode=ro to immutable=1. This is documented on SQ Uniform Resource Identifiers (section 3.3).

The immutable query parameter is a boolean that signals to SQLite that the underlying database file is held on read-only media and cannot be modified, even by another process with elevated privileges. SQLite always opens immutable database files read-only and it skips all file locking and change detection on immutable database files. If these query parameter (or the SQLITE_IOCAP_IMMUTABLE bit in xDeviceCharacteristics) asserts that a database file is immutable and that file changes anyhow, then SQLite might return incorrect query results and/or SQLITE_CORRUPT errors.

I am unsure if it matters using this since NONE of the DB should be modified and this opens in read only as well. I am unsure of the long-term impact nor if this is a bug with Shared Folders inside a virtual machine.

flamusdiu commented 2 years ago

@abrignoni @ydkhatri - just so you are aware of the issue.