Eu tenho um link simbólico para um arquivo legível por todo o mundo que um programa não consegue ler. redshift
deveria pegar a configuração $HOME/.config/redshift/redsihft.conf
automaticamente, mas não foi. Tentei rastrear chamadas do sistema para entender quais arquivos estão sendo testados:
debian-x1-7th][redshift-1.12][130]$ strace -fe trace=file redshift
execve("/usr/bin/redshift", ["redshift"], 0x7ffd2d3c2680 /* 78 vars */) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdrm.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libwayland-client.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libxcb.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libxcb-randr.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libX11.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXxf86vm.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgio-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgobject-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libglib-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libffi.so.7", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXau.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXdmcp.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXext.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgmodule-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libmount.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libbsd.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libblkid.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libmd.so.0", O_RDONLY|O_CLOEXEC) = 3
statfs("/sys/fs/selinux", 0x7ffc678ee320) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffc678ee320) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
access("/etc/selinux/config", F_OK) = 0
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/redshift.conf", O_RDONLY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "/home/ealfonso/.config/redshift.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/redshift.conf", O_RDONLY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "/home/ealfonso/.config/redshift.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/redshift.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
Trying location provider `geoclue2'...
Using provider `geoclue2'.
strace: Process 78213 attached
Could not connect to wayland display, exiting.
Failed to start adjustment method wayland.
Trying next method...
[pid 78212] access("/home/ealfonso/.Xauthority", R_OK) = 0
[pid 78212] openat(AT_FDCWD, "/home/ealfonso/.Xauthority", O_RDONLY) = 6
strace: Process 78214 attached
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 78213] openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/glib20.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
Using method `randr'.
Waiting for initial location to become available...
strace: Process 78215 attached
strace: Process 78216 attached
[pid 78215] +++ exited with 0 +++
`
A linha que me surpreende é esta permissão negada:
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/redshift.conf", O_RDONLY) = -1 EACCES (Permission denied)
Sugerindo que a abertura do processo está sendo negada /home/ealfonso/.config/redshift/redshift.conf
. Isso é estranho porque o arquivo deve ser legível por todo o mundo. Todos os diretórios pai são executáveis pelo proprietário, incluindo o destino do link simbólico:
[debian-x1-7th][redshift-1.12][1]$ ls -l /home/ealfonso/.config/redshift/redshift.conf
lrwxrwxrwx 1 ealfonso ealfonso 47 Jul 21 15:47 /home/ealfonso/.config/redshift/redshift.conf -> /home/ealfonso/git/dotfiles/inits/redshift.conf
█[debian-x1-7th][redshift-1.12][0]$ ls -l /home/ealfonso/git/dotfiles/inits/redshift.conf
-rw-r--r-- 1 ealfonso ealfonso 138 Jul 21 15:32 /home/ealfonso/git/dotfiles/inits/redshift.conf
█[debian-x1-7th][redshift-1.12][0]$ ls -ld ~/.config/
drwx------ 29 ealfonso ealfonso 4096 Jul 21 15:47 /home/ealfonso/.config/
█[debian-x1-7th][redshift-1.12][0]$ ls -ld ~/
drwxr-xr-x 56 ealfonso ealfonso 4096 Jul 21 16:10 /home/ealfonso/
█[debian-x1-7th][redshift-1.12][0]$ ls -ld /home/
drwxr-xr-x 3 root root 4096 Apr 27 17:10 /home/
█[debian-x1-7th][redshift-1.12][0]$
█[debian-x1-7th][redshift-1.12][0]$ ls -ld /home/ealfonso/git/dotfiles/inits/
drwxr-xr-x 8 ealfonso ealfonso 4096 Jul 21 15:32 /home/ealfonso/git/dotfiles/inits/
Tentei compilar o redshift da fonte e adicionar alguns logs de depuração e, surpreendentemente, não consegui reproduzir o erro:
█[debian-x1-7th][redshift-1.12][130]$ strace -f -e trace=file ./src/redshift
execve("./src/redshift", ["./src/redshift"], 0x7ffc655cd728 /* 78 vars */) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libwayland-client.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libxcb.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libxcb-randr.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgio-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgobject-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libglib-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libffi.so.7", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXau.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libXdmcp.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgmodule-2.0.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libmount.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libbsd.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libblkid.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libmd.so.0", O_RDONLY|O_CLOEXEC) = 3
statfs("/sys/fs/selinux", 0x7fff8353fa80) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7fff8353fa80) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
access("/etc/selinux/config", F_OK) = 0
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
DDEBUG 7w6d: cp /home/ealfonso/.config/redshift/redshift.conf
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/redshift.conf", O_RDONLY) = 3
DDEBUG TRACE (config-ini.c) nlbc ()
DDEBUG wo2r: value randr
DDEBUG iwyt: m->name wayland
DDEBUG iwyt: m->name randr
access("/home/ealfonso/.Xauthority", R_OK) = 0
openat(AT_FDCWD, "/home/ealfonso/.Xauthority", O_RDONLY) = 4
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/local/share/locale/en_US.UTF-8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/share/locale/en_US.utf8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/share/locale/en_US/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/share/locale/en.UTF-8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/share/locale/en.utf8/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/local/share/locale/en/LC_MESSAGES/redshift.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
Waiting for initial location to become available...
Location: 28.56 N, 81.21 E
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/hooks", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
^Cstrace: Process 78851 detached
█[debian-x1-7th][redshift-1.12][130]$
Em particular:
DDEBUG 7w6d: cp /home/ealfonso/.config/redshift/redshift.conf
openat(AT_FDCWD, "/home/ealfonso/.config/redshift/redshift.conf", O_RDONLY) = 3
O arquivo é aberto com sucesso e a configuração correta é carregada.
Como posso depurar ainda mais esse erro estranho?
Para contextualizar, estou no debian 11 usando redshift 1.12, mas isso é uma questão geral de como depurar essas chamadas do sistema.
...
Pouco depois de postar a pergunta, examinei os arquivos empacotados como parte do redshift e notei um arquivo apparmor com conteúdo incluindo:
#include <tunables/global>
/usr/bin/redshift {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/dbus-strict>
#include <abstractions/wayland>
#include <abstractions/X>
dbus send
bus=system
path=/org/freedesktop/GeoClue2/Client/[0-9]*,
dbus receive
bus=system
path=/org/freedesktop/GeoClue2/Manager,
# Allow but log any other dbus activity
audit dbus bus=system,
owner @{HOME}/.config/redshift.conf r,
owner /run/user/*/redshift-shared-* rw,
# Site-specific additions and overrides. See local/README for details.
#include <local/usr.bin.redshift>
}
A partir da origem, o ~/.config/redshift.conf
é referido como o caminho alternativo "anteriormente usado":
if (f == NULL && (env = getenv("XDG_CONFIG_HOME")) != NULL &&
env[0] != '\0') {
snprintf(cp, sizeof(cp),
"%s/redshift/redshift.conf", env);
f = fopen(cp, "r");
if (f == NULL) {
/* Fall back to formerly used path. */
snprintf(cp, sizeof(cp),
"%s/redshift.conf", env);
f = fopen(cp, "r");
}
}
Mas depois de adicionar a linha owner @{HOME}/.config/redshift/redshift.conf r
a esta configuração, o arquivo ainda foi negado.
Se houver um arquivo que todos os programas em execução com os mesmos privilégios não possam acessar, é por causa das permissões do arquivo. Se há um arquivo que alguns programas podem acessar e outros não, é por causa de seu contexto de segurança.
Como depurar: procure algo nos logs do kernel. A localização e o conteúdo do arquivo de log dependem de qual estrutura de segurança está envolvida e como sua distribuição o configura. Procure um arquivo em
/var/log
(possivelmente em um subdiretório) que é modificado quando o acesso falha. Spoiler: é o AppArmor, os logs estão dentro/var/log/syslog
e ficam assim:O pacote redshift do Debian vem com um perfil AppArmor
/usr/bin/redshift
que impede o acesso a arquivos arbitrários em diretórios pessoais. (O perfil não se aplica a executáveis chamadosredshift
localizados em diretórios diferentes de/usr/bin
.) O perfil está localizado em/etc/apparmor.d/usr.bin.redshift
e nega acesso a arquivos em/home
excetoComo seu arquivo de configuração é um link simbólico que aponta para fora da área permitida, o redshift não pode seguir o link.
Uma solução é dar
/usr/bin/redshift
permissões mais amplas. Você pode adicionar linhas personalizadas em/etc/apparmor.d/local/usr.bin.redshift
. Acho que a seguinte linha deve funcionar para você:Em seguida, execute
service apparmor reload
para recarregar a configuração do AppArmor.Como alternativa, faça do local usual uma cópia do arquivo gerenciado pelo git, em vez de um link simbólico para ele.