The 'access' syscall uses REAL uid to check aceess, we should use EFFECTIVE uid with 'eaccess' call. See man page for their difference. ## Detail: Issue in forked-daapd in OpenWRT, before patched, forked-daapd scanning multi files or doing database vacuum, 'unable to open database file' may appears in log. Using strace to trace it, shows that: ``` setresgid(-1, 3003, -1) = 0 ... setresuid(-1, 190, -1) = 0 ... newfstatat(AT_FDCWD, "/var/tmp", {st_mode=S_IFDIR|0755, st_size=40, ...}, 0) = 0 faccessat(AT_FDCWD, "/var/tmp", W_OK|X_OK) = 0 faccessat(AT_FDCWD, "/var/tmp/etilqs_d4c84886ce52e72a", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/var/tmp/etilqs_d4c84886ce52e72a", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE|O_NOFOLLOW|O_CLOEXEC, 0600) = -1 EACCES (Permission denied) openat(AT_FDCWD, "/var/tmp/etilqs_d4c84886ce52e72a", O_RDONLY|O_EXCL|O_LARGEFILE|O_NOFOLLOW|O_CLOEXEC) = -1 ENOENT (No such file or directory) ``` As shown above, forked-daapd was run by root, then it sets its effective uid to 190, then sqlite trying to check '/var/tmp' writeable with `faccessat(AT_FDCWD, "/var/tmp", W_OK|X_OK)`, kernel says ok, but failed when actually create file with `openat`. Because `faccessat` using real uid to check access by default, but `openat` using effective uid. PS, The information of '/var/tmp' : ``` drwxr-xr-x 2 root root 40 Aug 16 10:29 tmp ``` ## Patch: ``` --- a/sqlite3.c +++ b/sqlite3.c @@ -33842,7 +33842,7 @@ static struct unix_syscall { { "close", (sqlite3_syscall_ptr)close, 0 }, #define osClose ((int(*)(int))aSyscall[1].pCurrent) - { "access", (sqlite3_syscall_ptr)access, 0 }, + { "access", (sqlite3_syscall_ptr)eaccess, 0 }, #define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, ```