Как ограничить получение универсальной многоадресной рассылки netlink для пользователя root?

Я написал модуль ядра, который отправляет общие многоадресные рассылки Netlink, и написал пользовательского клиента, использующего libmnl, который их получает.

Все это работает нормально, но мой клиент работает, даже если он не является пользователем root, и я хочу предотвратить это.

человек 7 нетлинк говорит:

Only processes with an effective UID of 0 or the CAP_NET_ADMIN capability
may send or listen to a netlink multicast group.

Очевидно, что слушающая часть этого не соответствует действительности. Я пробовал CentOS 5 (2.6.18), CentOS 6 (2.6.32) и Ubuntu 14.04 (3.13).

Я знаю, что с помощью флага GENL_ADMIN_PERM можно ограничить получение общих команд netlink, входящих в ядро, только от root, но можно ли отправлять многоадресные рассылки из ядра, которые могут быть получены только root?

РЕДАКТИРОВАТЬ: я поделился некоторым кодом для модуля ядра, который отправляет многоадресные рассылки по сети, и клиента, который их получает, по адресу https://github.com/craig65535/mcast-exmpl. Инструкции по сборке находятся в README.md, но я вставлю их сюда.

В одном терминале:

$ make
$ sudo insmod mcast-exmpl.ko
$ cd client
$ make
$ ./client
genl ctrl msg
Family ID: 26
Mcast group ID: 4

(идентификаторы могут отличаться)

В другом терминале запустите команду, которая установит TCP-соединение. Перехватчики mcast-exmpl подключаются через jprobe, поэтому это приведет к отправке многоадресной рассылки netlink.

$ nc yahoo.com 80
^C
$

В первом терминале вы увидите, что многоадресная рассылка netlink была получена, даже если вы не запускали клиент с правами root:

mcast-exmpl msg
SEND_NUM 55555

Я хотел бы изменить это, чтобы многоадресные рассылки принимались только тогда, когда client работает от имени пользователя root, или, в противном случае, подтверждение того, что я нашел ошибку либо в документации Linux, либо в самой Linux.


person craig65535    schedule 06.03.2015    source источник


Ответы (1)


Во-первых, я не знаком с механизмом IPC netlink. Тем не менее, я считаю, что у меня есть полезная информация, чтобы поделиться.

Причина, по которой вы можете получать, несмотря на то, что вы не root, заключается в том, что это изменение, внесенное в ядро ​​некоторое время назад, которое позволило пользователям без полномочий root читать uevents.

Глядя на Multicast из ядра в пространство пользователя через Netlink в C, похоже, модуль ядра может/должен указывать файл struct netlink_kernel_cfg.

Из LXR кажется, что это определяется как

struct netlink_kernel_cfg {
        unsigned int    groups;
        unsigned int    flags;
        void            (*input)(struct sk_buff *skb);
        struct mutex    *cb_mutex;
        int             (*bind)(struct net *net, int group);
        void            (*unbind)(struct net *net, int group);
        bool            (*compare)(struct net *net, struct sock *sk);
};

Googling для атрибута flags <давала A HREF = "https://books.google.com/books?id=RpsQAwAAQBAJ&pg=PA17&lpg=PA17&dq=struct%20netlink_kernel_cfg%20flags&source=bl&ots=rArNamtE-f&sig=dAD6OzTzEZvloU57pnorpTw1WkE&hl=en&sa=X&ei=7In9VKPpBsKuggTZv4D4Dw&ved =0CD4Q6AEwBQ" rel="nofollow noreferrer">этот результат, который говорит

Элемент flags может быть NL_CFG_F_NONROOT_RECV или NL_CFG_F_NONROOT_SEND. Когда установлено NL_CFG_F_NONROOT_RECV, пользователь без прав суперпользователя может привязываться к группе многоадресной рассылки.

person Guru Prasad    schedule 09.03.2015
comment
Спасибо за объяснение. В net/netlink/genetlink.c netlink_kernel_cfg имеет .flags = NL_CFG_F_NONROOT_RECV. Поэтому я полагаю, что это ожидаемое поведение для универсального сетевого соединения. - person craig65535; 09.03.2015
comment
Я предлагаю вам попробовать инициализировать flags в 0 и посмотреть, что произойдет. Возможно, ядро ​​по умолчанию имеет значение NL_CFG_F_NONROOT_RECV, но, возможно, его стоит изучить. - person Guru Prasad; 09.03.2015
comment
К сожалению, я не могу изменить конфигурацию универсального сетевого соединения. Другой код использует его и ожидает определенного поведения, и, конечно, сокет ядра будет создан задолго до загрузки моего модуля. Я думаю, что в конечном итоге я перестану выполнять многоадресную рассылку из своего модуля и вместо этого буду выполнять одноадресную рассылку на определенный идентификатор порта, который, как я знаю, используется процессом, принадлежащим root. - person craig65535; 10.03.2015