Использование сигнала SEGV

Проанализировав исходный код NetworkManager, я обнаружил проблему. NetworkManager заблокирует соединение от автоматического -соединения, если не сможет получить секреты из набора ключей. Похоже, что это поведение -не настраивается и жестко прописано в nm -policy.c :

.

https://github.com/NetworkManager/NetworkManager/blob/master/src/nm-policy.c

Рядом со строкой 1830 есть следующий фрагмент кода:

if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
    /*... */
    con_v = nm_settings_connection_get_last_secret_agent_version_id (sett_conn);
    if (   con_v == 0
        || con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr))
            block_no_secrets = TRUE;
}

if (block_no_secrets) {
    _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets",
        nm_settings_connection_get_id (sett_conn));
        nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, TRUE);
}

Самый простой способ обойти это поведение и заставить NetworkManager НЕ блокировать соединение при автоматическом -подключении — это не устанавливать для block_no_secretsзначение TRUE (, а просто установить для него значение FALSE или полностью удалить первый оператор if ).

0
21.11.2021, 21:16
2 ответа

Therefore I was wondering, what is the use of being able to send a SEGV signal to another process?

Я полагаю, что кто-то может отправить его вручную для тестирования. Но даже если изначально для него не было придумано никакого применения, мы никогда не знаем, может ли кто-то придумать применение, и тогда произвольные ограничения просто помешают.

Futhermore, is there anyway for a process to know whether the SEGV signal was sent by the OS or by another process?

Да, как упоминалось в Поймать, какой пользователь отправляет сигнал уничтожения , обработчики сигналов, установленные с помощью sigaction()с флагом SA_SIGINFO, могут считывать ряд деталей из структуры siginfo_t. Они содержат причину отправки сигнала(si_code)и, если применимо, отправляющего пользователя и PID (si_uid, si_pid).

См. справочную страницу:https://man7.org/linux/man-pages/man2/sigaction.2.html

Вот простая программа для проверки, она устанавливает обработчик для SIGSEGV и отправляет его себе, сначала с kill(), а затем инициируя недопустимый доступ к памяти:

#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void action(int sig, siginfo_t *si, void *p)
{
    printf("sig: %d\n", sig);
    printf("si_signo: %d\n", si->si_signo);
    char *reason = "?";
    switch (si->si_code) {
        case SI_USER: reason = "Signal sent by user"; break;
        case SI_TKILL: reason = "Signal sent by user (tkill)"; break;
        case SI_KERNEL: reason = "Signal sent by kernel"; break;
        case SEGV_MAPERR:
            reason = "SIGSEGV - Address not mapped to object"; break;
        case SEGV_ACCERR: 
            reason = "SIGSEGV - Invalid permissions for mapped object"; break;
    }
    printf("si_code: %d (%s)\n", si->si_code, reason);
    printf("si_pid: %d\n", (int) si->si_pid);
    printf("si_uid: %d\n", (int) si->si_uid);
    printf("si_addr: 0x%016lx\n", (unsigned long) si->si_addr);
    if (si->si_code != SI_USER && si->si_code != SI_TKILL) {
        // if it's an actual error, exit instead of
        // returning to repeat the error 
        _exit(1);
    }
}   

int main(void)
{
    struct sigaction sa = {0}; 
    sa.sa_sigaction = action;
    sa.sa_flags = SA_SIGINFO;
    int ret = sigaction(SIGSEGV, &sa, NULL);
    if (ret == -1) {
        perror("sigaction");
        exit(1);
    }
    printf("raising SIGSEGV manually\n");
    kill(getpid(), SIGSEGV);
    printf("\n");
    printf("trying to trigger SIGSEGV\n");
    volatile int *p = (int *) 0xdeadbeef;
    (void) *p;
}

Вывод в моей системе::

raising SIGSEGV manually
sig: 11
si_signo: 11
si_code: 0 (Signal sent by user)
si_pid: 13868
si_uid: 1000
si_addr: 0x000003e80000362c

trying to trigger SIGSEGV
sig: 11
si_signo: 11
si_code: 1 (SIGSEGV - Address not mapped to object)
si_pid: -559038737
si_uid: 0
si_addr: 0x00000000deadbeef

(Обратите внимание, что некоторые поля, не относящиеся к рассматриваемому случаю, содержат мусор.)

1
22.11.2021, 08:55

Unix не накладывает ограничений на то, какие сигналы могут быть отправлены процессу. Он ограничивает сигналы только на основе владения процессом.

Как правило, нет способа определить источник сигнала.

0
22.11.2021, 01:13

Теги

Похожие вопросы