| Summary: | Не запускается пользовательская systemd служба | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Sisyphus | Reporter: | Alexey Volkov <qualimock> | ||||
| Component: | kiosk | Assignee: | Олег Соловьев <mcpain> | ||||
| Status: | NEW --- | QA Contact: | qa-sisyphus | ||||
| Severity: | normal | ||||||
| Priority: | P5 | CC: | antohami, armatik, jqt4, mcpain, oleg | ||||
| Version: | unstable | ||||||
| Hardware: | x86_64 | ||||||
| OS: | Linux | ||||||
| Attachments: |
|
||||||
|
Description
Alexey Volkov
2025-07-09 21:43:41 MSK
(In reply to Alexey Volkov from comment #0) > Посмотрев код systemd, увидел, что там > используется функция secure_getenv(), которая сравнивает UID с EUID и GID с > EGID и только при их равенстве вызывает getenv(), который уже получает > нужные переменные окружения (XDG_RUNTIME_DIR и DBUS_SESSION_BUS_ADDRESS). А вот что я нашёл: В glibc/sysdeps/unix/sysv/linux/dl-parse_auxv.h [1]: /* Copy the auxiliary vector into AUXV_VALUES and set up GLRO variables. */ static inline void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) { ... unsigned security_mask = 0; ... security_mask |= auxv_values[AT_SECURE] != 0; security_mask |= ((uid != 0) << 1) | ((gid != 0) << 2); __libc_security_mask = security_mask; __libc_enable_secure = __libc_security_mask != 0; ... } В glibc/stdlib/secure-getenv.c [2]: /* Some programs and especially the libc itself have to be careful what values to accept from the environment. This special version checks for SUID or SGID first before doing any work. */ char * __libc_secure_getenv (const char *name) { return __libc_enable_secure ? NULL : getenv (name); } weak_alias (__libc_secure_getenv, secure_getenv) libc_hidden_weak (__libc_secure_getenv) В https://man7.org/linux/man-pages/man3/secure_getenv.3.html: > The GNU-specific secure_getenv() function is just like getenv() > except that it returns NULL in cases where "secure execution" is > required. > ... > Secure execution may also be required if triggered by some Linux security modules. А kiosk - LSM и включает secure execution для всех процессов, запущенных пользователем с uid >= 1000. В kernel-image-6.12/security/kiosk/kiosk_lsm.c [3]: static int kiosk_bprm_check_security(struct linux_binprm *bprm) { uid_t cur_uid = __kuid_val(bprm->cred->uid); struct kiosk_list_struct *node; if (kiosk_mode == KIOSK_PERMISSIVE) return 0; if (cur_uid >= 1000) { bprm->secureexec = 1; ... } [1] https://git.altlinux.org/gears/g/glibc.git?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/dl-parse_auxv.h;h=fb4124050f827dcd8c9567388886dc266212e12e;hb=8c5965291fac4d9814d13c492d45574fccf331c7#l27 [2] https://git.altlinux.org/gears/g/glibc.git?p=glibc.git;a=blob;f=stdlib/secure-getenv.c;h=88bff1b47abdb5a69614d6d7fc62d7f49ba3a83b;hb=8c5965291fac4d9814d13c492d45574fccf331c7#l24 [3] https://git.altlinux.org/gears/k/kernel-image-6.12.git?p=kernel-image-6.12.git;a=blob;f=security/kiosk/kiosk_lsm.c;h=18f810a1ce0f17631b5a18e40a92bad3f9ab8447;hb=5c8a6837cbfaf345ebf52635e02135793aaed3b8#l286 Таким образом, secure_getenv() в недрах systemd возвращает NULL из-за установленного в LSM-модуле флага AT_SECURE. Если бы флага не было и нет другой необходимости в secureexec, то вызывается уже getenv() |