WrapEarnPass left a comment (geany/geany-plugins#1566)
I copied commander.so directly to ~/.config/geany/plugins/, and stripped the x
bits.
```
$stat /home/build/.config/geany/plugins/commander.so
File: /home/build/.config/geany/plugins/commander.so
Size: 88920 Blocks: 176 IO Block: 4096 regular file
Device: 254,0 Inode: 5252599 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1002/ build) Gid: ( 1002/ build)
Context: user_u:object_r:xdg_config_t:s0
$strace 2>&1 >strace.log -- geany --verbose 2>&1 > geany.log
$less geany.log
...
Geany-INFO: 07:14:18.898: Can't load plugin:
/home/build/.config/geany/plugins/commander.so: failed to map segment from
shared object
Geany-INFO: 07:14:18.899: Failed to load
"/home/build/.config/geany/plugins/commander.so" - ignoring plugin!
...
$ grep -A4 commander.so strace.log
access("/home/build/.local/lib/geany/commander.so", F_OK) = 0
access("/home/build/.config/geany/keybindings.conf", F_OK) = 0
openat(AT_FDCWD, "/home/build/.config/geany/keybindings.conf",
O_RDONLY|O_CLOEXEC) = 11
fstat(11, {st_mode=S_IFREG|0660, st_size=5088, ...}) = 0
read(11, "[Bindings]\nmenu_new=<Primary>n\nm"..., 4096) = 4096
--
newfstatat(AT_FDCWD, "/home/build/.config/geany/plugins/commander.so",
{st_mode=S_IFREG|0644, st_size=88920, ...}, 0) = 0
openat(AT_FDCWD, "/home/build/.config/geany/plugins/commander.so",
O_RDONLY|O_CLOEXEC) = 13
read(13, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"...,
832) = 832
fstat(13, {st_mode=S_IFREG|0644, st_size=88920, ...}) = 0
mmap(NULL, 29472, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 13, 0) = 0x7f48a076e000
mmap(0x7f48a0770000, 12288, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 13, 0x2000) = -1 EACCES (Permission denied)
--
newfstatat(AT_FDCWD, "/home/build/.config/geany/plugins/commander.so",
{st_mode=S_IFREG|0644, st_size=88920, ...}, 0) = 0
openat(AT_FDCWD, "/home/build/.config/geany/plugins/commander.so",
O_RDONLY|O_CLOEXEC) = 13
read(13, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"...,
832) = 832
fstat(13, {st_mode=S_IFREG|0644, st_size=88920, ...}) = 0
mmap(NULL, 29472, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 13, 0) = 0x7f48a0766000
mmap(0x7f48a0768000, 12288, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 13, 0x2000) = -1 EACCES (Permission denied)
--
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/geany/commander.so",
{st_mode=S_IFREG|0644, st_size=27240, ...}, 0) = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/geany/commander.so",
O_RDONLY|O_CLOEXEC) = 13
read(13, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"...,
832) = 832
fstat(13, {st_mode=S_IFREG|0644, st_size=27240, ...}) = 0
mmap(NULL, 29504, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 13, 0) = 0x7f488ba6e000
mmap(0x7f488ba70000, 12288, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 13, 0x2000) = 0x7f488ba70000
```
Geany is trying to open /home/build/.config/geany/plugins/commander.so
PROT_EXEC, which is governed under the SELinux execute permission
```
type=AVC msg=audit(1781608458.896:573): avc: denied { execute } for
pid=88825 comm="geany" path="/home/build/.config/geany/plugins/commander.so"
dev="dm-0" ino=5252599 scontext=user_u:user_r:user_t:s0
tcontext=user_u:object_r:xdg_config_t:s0 tclass=file permissive=0
type=AVC msg=audit(1781608458.896:574): avc: denied { execute } for
pid=88825 comm="geany" path="/home/build/.config/geany/plugins/commander.so"
dev="dm-0" ino=5252599 scontext=user_u:user_r:user_t:s0
tcontext=user_u:object_r:xdg_config_t:s0 tclass=file permissive=0
```
Even if the file itself is not directly executable, it needs to be installed in
a location that has {execute}, which in the user space is user_bin_t, found on
~/.local/bin/ (or by older convention ~/bin)
~/.local/lib could be a potential location, if you object to the shared objects
being $PATH locatable.
```
File: /home/build/.local/lib Context: user_u:object_r::s0
newfstatat(AT_FDCWD, "/home/build/.local/lib/geany/plugins/commander.so",
{st_mode=S_IFREG|0644, st_size=88920, ...}, 0) = 0
openat(AT_FDCWD, "/home/build/.local/lib/geany/plugins/commander.so",
O_RDONLY|O_CLOEXEC) = 13
read(13, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"...,
832) = 832
fstat(13, {st_mode=S_IFREG|0644, st_size=88920, ...}) = 0
mmap(NULL, 29472, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 13, 0) = 0x7faba5a46000
mmap(0x7faba5a48000, 12288, PROT_READ|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 13, 0x2000) = 0x7faba5a48000
```
This seems to be supported by the default policy
https://packages.debian.org/sid/all/selinux-policy-default/filelist
```
$ bunzip2 /usr/share/selinux/default/unprivuser.pp.bz2 -c > /tmp/unprivuser.pp
&& semodule_unpackage /tmp/unprivuser.pp unprivuser.mod unprivuser.fc &&
./dismod -a 1 unprivuser.mod | grep xdg_data | grep exec
allow user_t [xdg_data_t] : [file] { ioctl read getattr lock map execute
open execute_no_trans };
```
--
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany-plugins/issues/1566#issuecomment-4718507150
You are receiving this because you are subscribed to this thread.
Message ID: <geany/geany-plugins/issues/1566/[email protected]>