lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAM95viF6QsbSq0u3D361Xif28q-yGLGJT_qk7+C3fj2=Op3o4Q@mail.gmail.com>
Date: Sun, 21 Jul 2024 16:55:30 +0300
From: Guy Avraham <guyavrah1986@...il.com>
To: netdev@...r.kernel.org
Subject: Potential issue in networking sub system when handling packet with IP
 router alert option

Hi all,

1. Introduction:
First, if there is anything I should do differently with respect to
the mailing list "procedure" please
let me know (I have never written nor subscribed to any mailing list
related to Linux kernel
development).

My name is Guy Avraham and I am an embedded Linux engineer.
I am new in the world of Linux kernel networking domain.
I am facing an issue related to the handling of IP packets that have
the IP router alert option present in their options section.

I am working with kernel version 5.2.20 which is compiled to X86_64
architecture (let me know if further information is needed). Also, I
am quite sure that the issue is also present in later versions of the
kernel.

2. Preface (problem description):
According to RFC 2113, the presence of the IP router alert option in
the IP packet header means that (section 2.0):

"The goal, then, is to provide a mechanism whereby routers can
intercept packets not addressed to them directly".

One such protocol that leverages this option, is the RSVP. The
situation I am facing is the following: I have 4 routers in a "row"
topology (for the matter and for simplicity). Lets name them:

R1 ---> R2 ---> R3 ---> R4

R1 is the RSVP tunnel "head". R4 is the RSVP tunnel "tail".

The RSVP's goal is to construct a tunnel from R1 ---> R4. For that to
happen, R1 sends an RSVP message (i.e. - RSVP Path message towards
R4). Note that the source IP of this packet is R1's IP and the
destination IP address of this packet is R4's IP. It (the RSVP Path
message) should pass and be processed by ALL routers along the path,
which in this case are R2 & R3 (and finally of course R4), just as it
says according to the RSVP RFC, section 3.1.3:

"Each RSVP-capable node along the path(s) captures a Path message and
processes it to create path state..."

At some point of time, due to network issues (which are legitimate),
R2 does NOT have a route to R4, i.e. - in the RIB and FIB (Routing
Information Base and Forwarding Information Base) of R2, the address
of R4 is not present, therefor, R2's networking layer in the kernel
"thinks" it can NOT "route" packets (and in particular the RSVP Path
message) towards R4. The RSVP application on R2, HOWEVER, as mentioned
above, due to the presence of the IP router alert option, MUST receive
the RSVP Path message that arrives at him (in order to process it, and
forward it to the next "hop" down the tunnel path), but it does NOT.


3. Linux kernel networking part:
When the situation above takes place, i.e. - R2 does NOT have a route
to R4, it appears, that the ROUTING logic (phase of the netfilter
flow) that this packet traverses within R2 Linux kernel causing the
message to be dropped, thus leaving the RSVP application NOT getting
the message even though it should. While, on the other hand, where the
same situation takes place, BUT R2 does HAVE a route to R4 --> the
message is passed towards the RSVP application (via the proper
socket). The RSVP application opens a socket and set the
IP_ROUTER_ALERT option for it (like so: setsockopt(sockfd, IPPROTO_IP,
IP_ROUTER_ALERT, &router_alert, sizeof(router_alert)).

Recall, that in BOTH situations, the IP router alert option is present
in the IP header packet (of the RSVP Path message), HOWEVER, it seems
that in the "problematic" situation, it is not being considered (or
its presence is not "strong enough" to enforce the message to be
passed to the RSVP application).

4. The "relevant" function:
I looked a little into the Linux kernel networking code, and found the
following function: ip_call_ra_chain (from the net/ipv4/ip_input.c
file).
The (main) objective of this function is to "pass" the packet to any
"relevant" socket, which in my case will be the socket of the RSVP
application.
This function is invoked (used) twice:

net/ipv4/ip_forward.c, line 110
net/ipv4/ipmr.c, line 2101

The call to this function in the ipmr.c file is not relevant in this
case (but is, for example, for IGMP).
So the only call to the ip_call_ra_chain in the flow that the RSVP
Path message goes via, is within the ip_forward.c file, within the
ip_forward function.

5. Linux kernel networking subsystem design:
As of my understanding of how the networking stack of Linux kernel
works, the ip_forward function is called AFTER the IP_ROUTING logic
takes place. So for every IP packet that arrives at some host, where
the destination IP of the packet is NOT the IP of the host, the
"trigger" that will pass the packet (of the RSVP path message) to the
relevant application is the call to the ip_call_ra_chain within the
ip_forward function (i.e. - will pass the packet to the RSVP
application in this case).
However, if the host that receives the IP packet does not have a route
to the destination IP address of the packet, it will drop the packet
EARLIER in the routing phase (net/ipv4/route.c line 2310)
i.e. - in this case, the RSVP path message that has destination IP
address of 4.4.4.4 arrives at 2.2.2.2 WHILE 2.2.2.2 does not have
route to 4.4.4.4 --> so the IP router alert is not being
taken into account, thus causing the kernel to drop the packet and not
pass it to the RSVP application.

6. Proposed solution:
As I see it, the call to the ip_call_ra_chain needs "somehow" to be
used "earlier" in the flow of packet traversal in the Linux kernel.
What I am thinking to suggest is that RIGHT after the fib_lookup check
in the above mentioned location in the code (i.e. - in
net/ipv4/route.c line 2311), if indeed the lookup was unsuccessful
(i.e. - err != 0) --> then the call to the ip_call_ra_chain will be
used.
Then, if the  ip_call_ra_chain function returns false, the code
continues as is, while if it returns true (i.e. - the packet was
successfully passed to all relevant sockets), then the err = 0 and the
code will "goto out".

Does that seem like a valid fix for this issue? Please let me know if
anything else in this fix is problematic and/or anything I have not
taken into account.

Please let me know if any kind of information is needed or if anything
is not clear in this query.

Appreciate your reply!

Thanks,
Guy.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ