Модуль, реализующий поддержку протокола управления логическим каналом Logical Link Layer, IEEE 802.2 (net/llc)

Ниже представлены результаты анализа поверхности атаки для модуля LLC с точки зрения зависимости от сетевого трафика.

LLC (Logical Link Control, уровень управления логической связью) – верхний подуровень канального уровня модели OSI. Протокол LLC связывает протоколы сетевого уровня с протоколами уровня MAC.

В соответствии со стандартом IEEE 802.2 уровень управления логическим каналом предоставляет верхним уровням три типа процедур:

  • LLC1 – процедура без установления соединения и без подтверждения;
  • LLC2 – процедура с установлением соединения и подтверждением;
  • LLC3 – процедура без установления соединения, но с подтверждением.

По своему назначению кадры уровня LLC, называемые в стандарте блоками данных (Protocol Data Unit, PDU), подразделяются на три типа – информационные, управляющие и ненумерованные.

  • Информационные кадры предназначены для передачи информации в процедурах с установлением логического соединения и должны обязательно содержать поле информации. В процессе передачи информационных блоков осуществляется их нумерация в режиме скользящего окна.
  • Управляющие кадры предназначены для передачи команд и ответов в процедурах с установлением логического соединения, в том числе запросов на повторную передачу искаженных информационных блоков.
  • Ненумерованные кадры предназначены для передачи ненумерованных команд и ответов, выполняющих в процедурах без установления логического соединения передачу информации, идентификацию и тестирование LLC-уровня, а в процедурах с установлением логического соединения – установление и разъединение логического соединения, а также информирование об ошибках.

В режиме LLC1 используется только один тип кадра – ненумерованный.

В режиме LLC2 используются все три типа кадров. В этом режиме кадры делятся на команды и ответы на эти команды.

Стоит отметить, что кадры LLC могут переносить как пользовательские данные, так и команды самого протокола LLC (например, установить или разорвать соединение для соединений типа LLC2).

Минимальная функциональность протокола содержится в трех файлах:

  • llc_core.c – минимальная функциональность для управления точками доступа SAP (Service Access Point),
  • llc_input.c – обработка входящего трафика,
  • llc_output.c – обработка исходящего трафика.

Для использования протокола LLC с установлением соединения (LLC2) и поддержки сокетов типа PF_LLC требуется подключить дополнительный подмодуль. Соответствующая функциональность находится в следующих файлах:

  • af_llc.c – пользовательский интерфейс сокетов LLC,
  • llc_if.c – интерфейс LLC для протоколов верхнего уровня,
  • llc_conn.c – интерфейс драйвера для компонента соединений,
  • llc_sap.c – интерфейс драйвера для компонента SAP,
  • llc_station.c – компонент LLC station,
  • llc_pdu.c – управление значениями полей кадра PDU.

Описание конечного автомата (state machine) для компонента соединений содержится в файлах:

  • llc_c_ac.c – действия (actions) при переходах между состояниями,
  • llc_c_ev.c – события (events),
  • llc_c_st.c – переходы конечного автомата (state machine transitions).

Описание конечного автомата (state machine) компонента SAP:

  • llc_s_ac.c – действия (actions) при переходах между состояниями,
  • llc_s_ev.c – события (events),
  • llc_s_st.c – переходы конечного автомата (state machine transitions).

Дополнительные подмодули:

  • llc_proc.c – интерфейс специальной файловой системы proc,
  • sysctl_net_llc.c – интерфейс sysctl для сетевой подсистемы LLC.

Ниже на диаграмме косые четырехугольники – это статические (static) функции, которые вызываются или через функциональный указатель или внутри модуля.

Красным цветом выделены интерфейсные функции, которые могут являться поверхностью атаки.

Оранжевым цветом выделены интерфейсные функции, которые могут являться поверхностью атаки при вызовах из недоверенного пользовательского пространства.

Розовым цветом выделены интерфейсные функции, требующие более глубокого анализа с точки зрения поверхности атаки.

Темно-серые прямоугольники – это интерфейсные функции, которые не оперируют сетевыми данными и не является поверхностью атаки.

Зеленые ромбы на диаграммах - это один или несколько элементов некоторой структуры, которые являются указателями на функции. Если из ромба выходит стрелка, значит элементу соответствующей структуры присвоено имя функции, на которую указывает стрелка. Если стрелка входит в ромб из функции, значит в этой функции имеется вызов функции по соответствующему указателю. Зеленые прямоугольники – это структуры, переопределяющие структуру обозначенную зеленым ромбом.

llc

Сводная таблица результатов анализа

Имя подмодуля и/или функцииНазначениеПоверхность атаки
llc_core.c: llc_sap_find, llc_sap_open, llc_sap_closeМинимальная функциональность для управления точками доступа SAPНет
llc_input.cОбработка входящего трафика
llc_add_pack, llc_remove_packНет
llc_set_station_handlerУстанавливает указатель на обработчик входящих пакетов.Нет
llc_rcvПервичная обработка входящего трафика. Точка входа для протоколов нижнего уровня.Да
llc_output.cобработка исходящего трафика
llc_mac_hdr_initИнициализация заголовка MACДа
llc_build_and_send_ui_pktИнтерфейсная функция отправки данных без установления соединения (connection-less) для протоколов верхнего уровня.Да
af_llc.cПользовательский интерфейс сокетов LLC
llc_ui_create, llc_ui_release, llc_ui_bind, llc_ui_shutdown, llc_ui_connect, llc_ui_listen, llc_ui_accept, llc_ui_sendmsg, llc_ui_getname, llc_ui_ioctl, llc_ui_setsockopt, llc_ui_getsockoptСтандартные методы интерфейса сокетовДа
llc_ui_recvmsgПолучение пришедших данныхДа
llc_if.c: llc_build_and_send_pkt, llc_establish_connection, llc_send_discИнтерфейс LLC для протоколов верхнего уровня. Все функции вызываются через интерфейс LLC сокета.Да
llc_conn.cИнтерфейс драйвера для компонента соединений
llc_sk_alloc, llc_sk_stop_all_timers, llc_sk_free, llc_sk_reset, llc_conn_remove_acked_pdus, llc_lookup_established, llc_data_accept_state, llc_build_offset_table, llc_sap_add_socket, llc_sap_remove_socketНет
llc_conn_send_pdu, llc_conn_resend_i_pdu_as_cmd, llc_conn_resend_i_pdu_as_rspОтправка кадровДа
llc_conn_rtn_pdu, llc_conn_state_process, llc_conn_handler, llc_backlog_rcvОбработка входящих кадровДа
llc_sap.cИнтерфейс драйвера для компонента SAP
llc_alloc_frameВыделение памятиНет
llc_save_primitiveДа
llc_sap_rtn_pduИнформирование протокола верхнего уровня о типе пришедших данных.Да
llc_sap_handlerОбработчик входящих данных компонентом SAP.Да
llc_build_and_send_test_pkt, llc_build_and_send_xid_pktИнтерфейсные функции для протоколов верхнего уровня для отправки разных типов PDU.Да
llc_station.c: llc_station_rcvКомпонент LLC station. Передача полученного PDU для обработки в конечный автомат станции (station state machine).Да
llc_proc.cИнтерфейс специальной файловой системы procДа
sysctl_net_llc.cИнтерфейс sysctl для сетевой подсистемы LLCДа
llc_pdu.cУправление значениями полей кадра PDUДа, требуется дополнительный анализ
llc_c_ac.cДействия (actions) при переходах между состояниями конечного автомата (КА) компонента соединений (КС)Требуется дополнительный анализ
llc_c_ev.cСобытия (events) КА КСТребуется дополнительный анализ
llc_c_st.cПереходы (transitions) КА КСНет
llc_s_ac.cДействия (actions) при переходах между состояниями конечного автомата (КА) компонента SAPТребуется дополнительный анализ
llc_s_ev.cСобытия (events) КА SAPТребуется дополнительный анализ
llc_s_st.cПереходы (transitions) КА SAPНет

Распределение функций, являющихся поверхностью атаки, по направлению трафика

Имя функцииНаправление трафика
llc_input.c
llc_rcvВходящий
llc_output.c
llc_mac_hdr_init, llc_build_and_send_ui_pktИсходящий
af_llc.c
llc_ui_create, llc_ui_release, llc_ui_bind, llc_ui_shutdown, llc_ui_connect, llc_ui_listen, llc_ui_accept, llc_ui_getname, llc_ui_ioctl, llc_ui_setsockopt, llc_ui_getsockoptИз пользовательского пространства
llc_ui_sendmsgИсходящий
llc_ui_recvmsgВходящий
llc_if.c
llc_build_and_send_pkt, llc_establish_connection, llc_send_discИсходящий
llc_conn.c
llc_conn_send_pdu, llc_conn_resend_i_pdu_as_cmd, llc_conn_resend_i_pdu_as_rspИсходящий
llc_conn_rtn_pdu, llc_conn_handler, llc_backlog_rcvВходящий
llc_conn_state_processВ обоих направлениях
llc_sap.c
llc_sap_rtn_pdu, llc_sap_handlerВходящий
llc_save_primitiveВ обоих направлениях
llc_build_and_send_test_pkt, llc_build_and_send_xid_pktИсходящий
llc_station.c
llc_station_rcvВходящий
llc_proc.cИз пользовательского пространства
sysctl_net_llc.cИз пользовательского пространства
llc_pdu.cТребуется дополнительный анализ
llc_c_ac.cТребуется дополнительный анализ
llc_c_ev.cТребуется дополнительный анализ
llc_s_ac.cТребуется дополнительный анализ
llc_s_ev.cТребуется дополнительный анализ

Ниже перечислены все файлы и функции, доступные для вызова вне модуля.

llc_core.c

Минимальная функциональность для управления точками доступа SAP (Service Access Point) и инициализации всего модуля LLC.

struct llc_sap *llc_sap_find(unsigned char sap_value)
struct llc_sap *llc_sap_open(unsigned char lsap,
                             int (*func)(struct sk_buff *skb, struct net_device *dev,
                                         struct packet_type *pt,
                                         struct net_device *orig_dev))
void llc_sap_close(struct llc_sap *sap)

static struct packet_type llc_packet_type __read_mostly = {
    .type = cpu_to_be16(ETH_P_802_2),
    .func = llc_rcv,
};

static struct packet_type llc_tr_packet_type __read_mostly = {
    .type = cpu_to_be16(ETH_P_TR_802_2),
    .func = llc_rcv,
};

С сетевыми данными функции модуля не работают. Две структуры используют указатель на функцию llc_rcv (llc_input.c).

llc_input.c

Обработка входящего трафика.

void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, struct sk_buff *skb))
void llc_remove_pack(int type)
void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
int llc_rcv(struct sk_buff *skb, struct net_device *dev,
            struct packet_type *pt, struct net_device *orig_dev)

С сетевыми данные обрабатываются только в функции llc_rcv, которая является первичным обработчиком входящих пакетов и точкой входа для протоколов нижнего уровня.

Функция llc_set_station_handler устанавливает указатель на обработчик входящих пакетов llc_station_rcv (llc_station.c), который затем вызывается через llc_rcv.

llc_output.c

Обработка исходящего трафика.

int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa, const unsigned char *da)
int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, unsigned char *dmac, 
                              unsigned char dsap)

llc_mac_hdr_init – инициализация заголовка MAC.

llc_build_and_send_ui_pkt – интерфейсная функция отправки данных для протоколов верхнего уровня при использовании соединений LLC1 (connection-less).

Обе функции являются поверхностью атаки при вызовах из пользовательского пространства.

af_llc.c

Пользовательский интерфейс сокетов LLC.

static int llc_ui_create(struct net *net, struct socket *sock, int protocol, int kern)
static int llc_ui_release(struct socket *sock)
static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
static int llc_ui_shutdown(struct socket *sock, int how)
static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, int addrlen, int flags)
static int llc_ui_listen(struct socket *sock, int backlog)
static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags, bool kern)
static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, int flags)
static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
static int llc_ui_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
static int llc_ui_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
                             unsigned int optlen)
static int llc_ui_getsockopt(struct socket *sock, int level, int optname, char __user *optval,
                             int __user *optlen)

static const struct net_proto_family llc_ui_family_ops = {
    .create = llc_ui_create,
};

static const struct proto_ops llc_ui_ops = {
    .release  = llc_ui_release,
    .bind      = llc_ui_bind,
    .connect  = llc_ui_connect,
    .accept  = llc_ui_accept,
    .getname  = llc_ui_getname,
    .ioctl  = llc_ui_ioctl,
    .listen  = llc_ui_listen,
    .shutdown = llc_ui_shutdown,
    .setsockopt = llc_ui_setsockopt,
    .getsockopt = llc_ui_getsockopt,
    .sendmsg  = llc_ui_sendmsg,
    .recvmsg  = llc_ui_recvmsg,
};

Данный модуль целиком является поверхностью атаки при вызовах из пользовательского пространства. С входящим трафиком работает только функция recvmsg.

llc_if.c

Интерфейс LLC для протоколов верхнего уровня.

int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
int llc_send_disc(struct sock *sk)

Все функции являются поверхностью атаки при вызовах из пользовательского пространства, вызываются через указанный выше интерфейс сокета af_llc.

llc_conn.c

Интерфейс драйвера для компонента соединений.

int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb)
void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked)
struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, struct llc_addr *laddr)
u8 llc_data_accept_state(u8 state)
void __init llc_build_offset_table(void)
void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk)
void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk)
void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb)
static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)

static void llc_sk_init(struct sock *sk)
{
    sk->sk_backlog_rcv = llc_backlog_rcv;
}

struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot, int kern)
void llc_sk_stop_all_timers(struct sock *sk, bool sync)
void llc_sk_free(struct sock *sk)
void llc_sk_reset(struct sock *sk)

С входящим трафиком работают функции llc_conn_rtn_pdu, llc_conn_handler, llc_backlog_rcv.

С иcходящим трафиком работают функции llc_conn_send_pdu, llc_conn_resend_i_pdu_as_cmd, llc_conn_resend_i_pdu_as_rsp.

Функция llc_conn_state_process используется в обоих направлениях, она используется для отправки события (event) в компонент, отвечающий за соединения (connection state machine).

Также устанавливаются обработчики по таймеру: llc_conn_ack_tmr_cb, llc_conn_pf_cycle_tmr_cb, llc_conn_rej_tmr_cb, llc_conn_busy_tmr_cb (из файла llc_c_ac.c), которые влияют на состояние автомата соединений (connection state machine).

static void llc_sk_init(struct sock *sk)
{
 …
    timer_setup(&llc->ack_timer.timer, llc_conn_ack_tmr_cb, 0);
    llc->ack_timer.expire      = sysctl_llc2_ack_timeout;

    timer_setup(&llc->pf_cycle_timer.timer, llc_conn_pf_cycle_tmr_cb, 0);
    llc->pf_cycle_timer.expire     = sysctl_llc2_p_timeout;

    timer_setup(&llc->rej_sent_timer.timer, llc_conn_rej_tmr_cb, 0);
    llc->rej_sent_timer.expire     = sysctl_llc2_rej_timeout;

    timer_setup(&llc->busy_state_timer.timer, llc_conn_busy_tmr_cb, 0);
    llc->busy_state_timer.expire      = sysctl_llc2_busy_timeout;
    …
}
llc_sap.c

Интерфейс драйвера для компонента SAP.

struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, u8 type, u32 data_size)
void llc_save_primitive(struct sock *sk, struct sk_buff *skb, u8 prim)
void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb)
void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb, u8 *dmac, u8 dsap)
void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb, u8 *dmac, u8 dsap)
void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb)

llc_sap_handler – обработчик входящих данных на уровне компонента SAP, вызывается через llc_rcv (llc_input.c).

С входящим трафиком работают функции llc_save_primitive, llc_sap_rtn_pdu, llc_sap_handler.

С иcходящим трафиком работают функции llc_build_and_send_test_pkt, llc_build_and_send_xid_pkt.

llc_station.c

Компонент LLC station.

static void llc_station_rcv(struct sk_buff *skb)

void __init llc_station_init(void)
{
    llc_set_station_handler(llc_station_rcv);
}

С входящим трафиком работает функция llc_station_rcv, которая передает полученный кадр PDU для обработки в конечный автомат станции (station state machine).

llc_proc.c

Реализует интерфейс специальной файловой системы proc.

С входящим трафиком не работает, является поверхностью атаки при вызовах из пользовательского пространства.

sysctl_net_llc.c

Реализует интерфейс sysctl для сетевой подсистемы LLC. С входящим трафиком не работает, является поверхностью атаки при вызовах из пользовательского пространства.

Ниже представлены подмодули, описывающие конечные автоматы (state machine) для компонента соединений и компонента SAP. Данные подмодули рассмотрены очень поверхностно. Для анализа возможной поверхности атаки требуется детальное изучение спецификации протокола.

llc_pdu.c

Модуль управления значениями полей кадра PDU.

void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
                              u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)

Все функции работают с кадрами протокола, устанавливая для разных типов сообщений соответствующие биты управляющего поля.

Описание конечного автомата (state machine) SAP

llc_s_ac.c

Модуль действий (actions) при переходах между состояниями.

int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb)

Все функции работают с сетевыми данными (напомним, что под сетевыми данными понимаются не только данные верхнего протокола, но и управляющие команды протокола LLC).

llc_s_ev.c

Модуль событий (events).

int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb)
int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb)

Все функции работают с сетевыми данными.

llc_s_st.c

Модуль переходов конечного автомата (state machine transitions). Обработка данных отсутствует, только устанавливается соответствие между событиями и необходимыми действиями.

Описание конечного автомата (state machine) для соединений

  • llc_c_ac.c – действия (actions) при переходах между состояниями. Все функции работают с сетевыми данными.
  • llc_c_ev.c – события (events). Все функции работают с сетевыми данными.
  • llc_c_st.c – переходы конечного автомата (state machine transitions). Обработка данных отсутствует, только устанавливается соответствие между событиями и необходимыми действиями.

Заключение

Проведенный анализ модуля LLC (net/LLC) показал, что 8 функций этого модуля представляют поверхность атаки для входящего сетевого трафика, 11 – используются для исходящего трафика, 2 – могут использоваться в обоих направлениях. Кроме этого, три подмодуля af_llc.c (11 функций), llc_proc.c, sysctl_net_llc являются поверхностью атаки при использовании из пользовательского пространства (данные функции оперируют не сетевыми данными, а настройками сетевых соединений). Также 5 подмодулей (llc_pdu.c, llc_c_ac.c, llc_c_ev.c, llc_s_ac.c, llc_s_ev.c), отвечающих за работу конечных автоматов протокола, требуют детального изучения спецификации протокола и дополнительного анализа.