sqlite3 OperationalError(disk I/O error) when accessing a DB with Python inside a Virtual Machine
flamusdiu opened this issue · 1 comments
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.
@abrignoni @ydkhatri - just so you are aware of the issue.