(RCE) Remote Code Execution bug/exploit in TCP/IP and work arounds.

IPv4 Source Routing requests bug in all versions of windows:

formatting link

IPv6 re-assembly bug in all versions of windows that have IPv6:

formatting link

Work around, run these two commands in ms-dos prompt with admin rights, (this will make system more secure): netsh int ipv4 set global sourceroutingbehavior=drop Netsh int ipv6 set global reassemblylimit=0

To re-enable later or never, (this will make system insecure): netsh int ipv4 set global sourceroutingbehavior=dontforward Netsh int ipv6 set global reassemblylimit=267748640

Skybuck's take on this:

To me it seems these are some kind of ipv4 and ipv6 fragment/re-assembly bugs in combination with these features/source request.

In default state windows systems might be protected, though this is unsure to me at this moment. Therefore it seems very wise to run these two commands to protect older systems. This also include the still popular and valuable windows 7 operating system !

Bye for now, Skybuck.

Reply to
skybuck2000
Loading thread data ...

Here is some more information about the nature of these exploits, especiall y the IPv4 exploit/bug:

formatting link

Most interesting and dangerous part:

" CVE-2021-24074 Overview

An attacker can leverage this vulnerability by sending maliciously crafted IPv4 packets to a victim, potentially causing a RCE on the system.

This vulnerability occurs due to confusing IPv4 options fields between two fragments. The scenario pointed out by Microsoft shows two IPv4 fragments, the first of which has the Security Options (Type 130) field, followed by a second fragment with either the Loose Source and Record Route (LSRR) optio n (Type 131) or the "Strict Source and Record Route (SSRR) option (Type 137 ). The fragment offsets, confusing the options and the header data together , cause an out-of-bound read and write during reassembly of the IP fragment s, which introduces the potential for RCE on a Windows machine. "

Links to:

formatting link

Most interesting parts from this rfc:

"
  1. IP Options

IP options allow for the extension of the Internet Protocol. As specified in [RFC0791], there are two cases for the format of an option:

o Case 1: A single byte of option-type.

o Case 2: An option-type byte, an option-length byte, and the actual option-data bytes.

IP options of Case 1 have the following syntax:

+-+-+-+-+-+-+-+-+- - - - - - - - - | option-type | option-data +-+-+-+-+-+-+-+-+- - - - - - - - -

The length of IP options of Case 1 is implicitly specified by the option-type byte.

IP options of Case 2 have the following syntax:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - - | option-type | option-length | option-data +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -

In this case, the option-length byte counts the option-type byte and the option-length byte, as well as the actual option-data bytes.

Gont, et al. Best Current Practice [Page 4]

RFC 7126 Filtering of IP-Optioned Packets February 2014

All current and future options, except "End of Option List" (Type = 0) and "No Operation" (Type = 1), are of Class 2.

The option-type has three fields:

o 1 bit: copied flag.

o 2 bits: option class.

o 5 bits: option number.

The copied flag indicates whether this option should be copied to all fragments in the event the packet carrying it needs to be fragmented:

o 0 = not copied.

o 1 = copied.

The values for the option class are:

o 0 = control.

o 1 = reserved for future use.

o 2 = debugging and measurement.

o 3 = reserved for future use.

This format allows for the creation of new options for the extension of the Internet Protocol (IP).

Finally, the option number identifies the syntax of the rest of the option.

The "IP OPTION NUMBERS" registry [IANA-IP] contains the list of the currently assigned IP option numbers. "

"

4.3. Loose Source and Record Route (LSRR) (Type = 131)

RFC 791 states that this option should appear at most once in a given packet. Thus, if a packet contains more than one LSRR option, it should be dropped, and this event should be logged (e.g., a counter could be incremented to reflect the packet drop). Additionally, packets containing a combination of LSRR and SSRR options should be dropped, and this event should be logged (e.g., a counter could be incremented to reflect the packet drop).

4.3.1. Uses

This option lets the originating system specify a number of intermediate systems a packet must pass through to get to the destination host. Additionally, the route followed by the packet is recorded in the option. The receiving host (end-system) must use the reverse of the path contained in the received LSRR option.

The LSSR option can be of help in debugging some network problems. Some Internet Service Provider (ISP) peering agreements require support for this option in the routers within the peer of the ISP.

4.3.2. Option Specification

Specified in RFC 791 [RFC0791].

Gont, et al. Best Current Practice [Page 8]

RFC 7126 Filtering of IP-Optioned Packets February 2014

4.3.3. Threats

The LSRR option has well-known security implications [RFC6274]. Among other things, the option can be used to:

o Bypass firewall rules.

o Reach otherwise unreachable internet systems.

o Establish TCP connections in a stealthy way.

o Learn about the topology of a network.

o Perform bandwidth-exhaustion attacks.

Of these attack vectors, the one that has probably received least attention is the use of the LSRR option to perform bandwidth exhaustion attacks. The LSRR option can be used as an amplification method for performing bandwidth-exhaustion attacks, as an attacker could make a packet bounce multiple times between a number of systems by carefully crafting an LSRR option.

This is the IPv4 version of the IPv6 amplification attack that was widely publicized in 2007 [Biondi2007]. The only difference is that the maximum length of the IPv4 header (and hence the LSRR option) limits the amplification factor when compared to the IPv6 counterpart.

Additionally, some implementations have been found to fail to include proper sanity checks on the LSRR option, thus leading to security issues. These specific issues are believed to be solved in all modern implementations.

[Microsoft1999] is a security advisory about a vulnerability arising from improper validation of the Pointer field of the LSRR option.

Finally, we note that some systems were known for providing a system- wide toggle to enable support for this option for those scenarios in which this option is required. However, improper implementation of such a system-wide toggle caused those systems to support the LSRR option even when explicitly configured not to do so.

[OpenBSD1998] is a security advisory about an improper implementation of such a system-wide toggle in 4.4BSD kernels. This issue was resolved in later versions of the corresponding operating system.

Gont, et al. Best Current Practice [Page 9]

RFC 7126 Filtering of IP-Optioned Packets February 2014

4.3.4. Operational and Interoperability Impact if Blocked

Network troubleshooting techniques that may employ the LSRR option (such as ping or traceroute with the appropriate arguments) would break when using the LSRR option. (Ping and traceroute without IPv4 options are not impacted.) Nevertheless, it should be noted that it is virtually impossible to use the LSRR option for troubleshooting, due to widespread dropping of packets that contain the option.

4.3.5. Advice

Routers, security gateways, and firewalls SHOULD implement an option- specific configuration knob to select whether packets with this option are dropped, packets with this IP option are forwarded as if they did not contain this IP option, or packets with this option are processed and forwarded as per [RFC0791]. The default setting for this knob SHOULD be "drop", and the default setting MUST be documented.

Please note that treating packets with LSRR as if they did not contain this option can result in such packets being sent to a different device than the initially intended destination. With appropriate ingress filtering, this should not open an attack vector into the infrastructure. Nonetheless, it could result in traffic that would never reach the initially intended destination. Dropping these packets prevents unnecessary network traffic and does not make end-to-end communication any worse.

4.4. Strict Source and Record Route (SSRR) (Type = 137)

4.4.1. Uses

This option allows the originating system to specify a number of intermediate systems a packet must pass through to get to the destination host. Additionally, the route followed by the packet is recorded in the option, and the destination host (end-system) must use the reverse of the path contained in the received SSRR option.

This option is similar to the Loose Source and Record Route (LSRR) option, with the only difference that in the case of SSRR, the route specified in the option is the exact route the packet must take (i.e., no other intervening routers are allowed to be in the route).

The SSRR option can be of help in debugging some network problems. Some ISP peering agreements require support for this option in the routers within the peer of the ISP.

Gont, et al. Best Current Practice [Page 10]

RFC 7126 Filtering of IP-Optioned Packets February 2014

4.4.2. Option Specification

Specified in RFC 791 [RFC0791].

4.4.3. Threats

The SSRR option has the same security implications as the LSRR option. Please refer to Section 4.3 for a discussion of such security implications.

4.4.4. Operational and Interoperability Impact if Blocked

Network troubleshooting techniques that may employ the SSRR option (such as ping or traceroute with the appropriate arguments) would break when using the SSRR option. (Ping and traceroute without IPv4 options are not impacted.) Nevertheless, it should be noted that it is virtually impossible to use the SSRR option for trouble-shooting, due to widespread dropping of packets that contain such option.

4.4.5. Advice

Routers, security gateways, and firewalls SHOULD implement an option- specific configuration knob to select whether packets with this option are dropped, packets with this IP option are forwarded as if they did not contain this IP option, or packets with this option are processed and forwarded as per [RFC0791]. The default setting for this knob SHOULD be "drop", and the default setting MUST be documented.

Please note that treating packets with SSRR as if they did not contain this option can result in such packets being sent to a different device that the initially intended destination. With appropriate ingress filtering this should not open an attack vector into the infrastructure. Nonetheless, it could result in traffic that would never reach the initially intended destination. Dropping these packets prevents unnecessary network traffic, and does not make end-to-end communication any worse. " "

4.12. DoD Basic Security Option (Type = 130)

4.12.1. Uses

This option [RFC1108] is used by Multi-Level Secure (MLS) end-systems and intermediate systems in specific environments to:

o transmit from source to destination in a network standard representation the common security labels required by computer security models [Landwehr81],

o validate the datagram as appropriate for transmission from the source and delivery to the destination, and,

o ensure that the route taken by the datagram is protected to the level required by all protection authorities indicated on the datagram.

The DoD Basic Security Option (BSO) was implemented in IRIX [IRIX2008] and is currently implemented in a number of operating systems (e.g., Security-Enhanced Linux [SELinux2008], Solaris [Solaris2008], and Cisco IOS [Cisco-IPSO]). It is also currently deployed in a number of high-security networks. These networks are typically either in physically secure locations, protected by military/governmental communications security equipment, or both.

Gont, et al. Best Current Practice [Page 17]

RFC 7126 Filtering of IP-Optioned Packets February 2014

Such networks are typically built using commercial off-the-shelf (COTS) IP routers and Ethernet switches, but they are not normally interconnected with the global public Internet. MLS systems are much more widely deployed now than they were at the time the then-IESG decided to remove IPSO (IP Security Options) from the IETF Standards Track. Since nearly all MLS systems also support IPSO BSO and IPSO ESO, this option is believed to have more deployment now than when the IESG removed this option from the IETF Standards Track. [RFC5570] describes a similar option recently defined for IPv6 and has much more detailed explanations of how sensitivity label options are used in real-world deployments.

4.12.2. Option Specification

It is specified by RFC 1108 [RFC1108], which obsoleted RFC 1038 [RFC1038] (which in turn obsoleted the Security Option defined in RFC 791 [RFC0791]).

RFC 791 [RFC0791] defined the "Security Option" (Type = 130), which used the same option type as the DoD Basic Security option discussed in this section. Later, RFC 1038 [RFC1038] revised the IP security options, and in turn was obsoleted by RFC 1108 [RFC1108]. The "Security Option" specified in RFC 791 is considered obsolete by Section 3.2.1.8 of RFC 1122 [RFC1122] and Section 4.2.2.1 of RFC 1812 [RFC1812], and therefore the discussion in this section is focused on the DoD Basic Security option specified by RFC 1108 [RFC1108].

Section 4.2.2.1 of RFC 1812 states that routers "SHOULD implement [this option]".

Some private IP networks consider IP router-based per-interface selective filtering of packets based on (a) the presence of an IPSO option (including BSO and ESO) and (b) the contents of that IPSO option to be important for operational security reasons. The recent IPv6 Common Architecture Label IPv6 Security Option (CALIPSO) specification discusses this in additional detail, albeit in an IPv6 context [RFC5570].

Such private IP networks commonly are built using both commercial and open-source products -- for hosts, guards, firewalls, switches, routers, etc. Some commercial IP routers support this option, as do some IP routers that are built on top of MLS operating systems (e.g., on top of Trusted Solaris [Solaris2008] or Security-Enhanced Linux [SELinux2008]).

Gont, et al. Best Current Practice [Page 18]

RFC 7126 Filtering of IP-Optioned Packets February 2014

For example, many Cisco routers that run Cisco IOS include support for selectively filtering packets that contain the IP Security Options (IPSO) with per-interface granularity. This capability has been present in many Cisco routers since the early 1990s [Cisco-IPSO-Cmds]. Some government-sector products reportedly also support the IP Security Options (IPSO), for example, CANEWARE [RFC4949].

Support for the IPSO Basic Security Option also is included in the "IPsec Configuration Policy Information Model" [RFC3585] and in the "IPsec Security Policy Database Configuration MIB" [RFC4807]. Section 4.6.1 of the IP Security Domain of Interpretation [RFC2407] includes support for labeled IPsec security associations compatible with the IP Security Options. (Note: RFC 2407 was obsoleted by [RFC4306], which was obsoleted by [RFC5996].)

4.12.3. Threats

Presence of this option in a packet does not by itself create any specific new threat. Packets with this option ought not normally be seen on the global public Internet.

4.12.4. Operational and Interoperability Impact if Blocked

If packets with this option are blocked or if the option is stripped from the packet during transmission from source to destination, then the packet itself is likely to be dropped by the receiver because it is not properly labeled. In some cases, the receiver might receive the packet but associate an incorrect sensitivity label with the received data from the packet whose BSO was stripped by an intermediate router or firewall. Associating an incorrect sensitivity label can cause the received information either to be handled as more sensitive than it really is ("upgrading") or as less sensitive than it really is ("downgrading"), either of which is problematic.

4.12.5. Advice

A given IP router, security gateway, or firewall has no way to know a priori what environment it has been deployed into. Even closed IP deployments generally use exactly the same commercial routers, security gateways, and firewalls that are used in the public Internet.

Gont, et al. Best Current Practice [Page 19]

RFC 7126 Filtering of IP-Optioned Packets February 2014

Since operational problems result in environments where this option is needed if either the option is dropped or IP packets containing this option are dropped, but no harm results if the option is carried in environments where it is not needed, the default configuration SHOULD NOT (a) modify or remove this IP option or (b) drop an IP packet because the IP packet contains this option.

A given IP router, security gateway, or firewall MAY be configured to drop this option or to drop IP packets containing this option in an environment known to not use this option.

For auditing reasons, routers, security gateways, and firewalls SHOULD be capable of logging the numbers of packets containing the BSO on a per-interface basis. Also, routers, security gateways, and firewalls SHOULD be capable of dropping packets based on the BSO presence as well as the BSO values.

4.13. DoD Extended Security Option (Type = 133)

4.13.1. Uses

This option permits additional security labeling information, beyond that present in the Basic Security Option (Section 4.12), to be supplied in an IP datagram to meet the needs of registered authorities.

4.13.2. Option Specification

The DoD Extended Security Option (ESO) is specified by RFC 1108 [RFC1108]. "

Perhaps option 133 might also create some insecurity and this could be ongo ing research. Seems also related to defense/military kind of thing, maybe e ven offense ;) :)

I wasn't sure about the 130, it's a bit fuzzy, but it's confirmed to exist in this doc:

formatting link

(Open with special reader).

These seem like new options. I wonder if these options and vunerabilities w ould be present in windows nt 4 source code which has leaked onto the inter net.

I would guess the ip options implementation might be there cause it looks q uite old, however these specific options are newer, 2008 and so, and probab ly are not in windows nt. However maybe it is still possible to fool window s nt with strange option parameters in fragments.

The original options "framework/implementation/rfc" is from 1981:

formatting link

I just took a closer look at it, surprisingly these options already existed in 1981. So it's most likely it may have ended up in windows nt and then t ruely all windows versions are vunerable ! QUITE WOW THERE.

That means examining leaked windows nt 4 source code can shed more light on how to exactly re-create this exact vunerability for testing purpose ! ;) =D

Bye, Skybuck =D

P.S.: Special addition for you electronic geeks that might be less familiar with software, it won't take long for hackers and attackers to figure out how this all works ! =D PANTS UP ! =D

Reply to
skybuck2000

From the work around it can be determined that it has something to do with "forwarding" and "routing".

Taking a look at windows nt 3.5 source code, iproute.c is my main suspect containing the bug.

Most likely the bug is in this piece of source code:

" //** IPForward - Forward a packet. // // The routine called when we need to forward a packet. We check if we're supposed // to act as a gateway, and if we are and the incoming packet is a bcast we check // and see if we're supposed to forward broadcasts. Assuming we're supposed to // forward it, we will process any options. If we find some, we do some validation // to make sure everything is good. After that, we look up the next hop. If we can't // find one, we'll issue an error. Then we get a packet and buffers, and send it. // // Input: SrcNTE - NTE for net on which we received this. // Header - Pointer to received IPheader. // HeaderLength - Length of header. // Data - Pointer to data to be forwarded. // BufferLength - Length in bytes available in the buffer. // DestType - Type of destination. // // Returns: Nothing. // void IPForward(NetTableEntry *SrcNTE, IPHeader UNALIGNED *Header, uint HeaderLength, void *Data, uint BufferLength, NDIS_HANDLE LContext1, uint LContext2, uchar DestType) { uchar *Options; uchar OptLength; OptIndex Index; IPAddr DestAddr; // IP address we're routing towards. uchar SendOnSource = FALSE; IPAddr NextHop; // Next hop IP address. PNDIS_PACKET Packet; FWContext *FWC; IPHeader *NewHeader; // New header. NDIS_STATUS Status; uint DataLength; CTELockHandle TableHandle; uchar ErrIndex; IPAddr OutAddr; // Address of interface we're send out on. Interface *IF; // Interface we're sending out on. uint MTU;

if (ForwardPackets) {

DestAddr = Header->iph_dest;

// If it's a broadcast, see if we can forward it. We won't forward it if broadcast // forwarding is turned off, or the destination if the local (all one's) broadcast, // or it's a multicast (Class D address). We'll pass through subnet broadcasts in // case there's a source route. This would be odd - maybe we should disable this? if (IS_BCAST_DEST(DestType)) { if (!ForwardBCast) { if (DestType > DEST_REMOTE) IPSInfo.ipsi_inaddrerrors++; return; } if ((DestAddr == IP_LOCAL_BCST) || (DestAddr == IP_ZERO_BCST) || (DestType == DEST_SN_BCAST) || CLASSD_ADDR(DestAddr)) { return; } } else if (DestType == DEST_REMOTE) { SrcNTE = BestNTEForIF(Header->iph_src, SrcNTE->nte_if); if (SrcNTE == NULL) { // Something bad happened. CTEAssert(FALSE); return; } }

// If the TTL would expire, send a message. if (Header->iph_ttl nte_addr, Header, ICMP_TIME_EXCEED, TTL_IN_TRANSIT,0); return; }

DataLength = net_short(Header->iph_length) - HeaderLength;

Index.oi_srtype = NO_SR; // So we know we don't have a source route. Index.oi_srindex = MAX_OPT_SIZE; Index.oi_rrindex = MAX_OPT_SIZE; Index.oi_tsindex = MAX_OPT_SIZE;

// Now check for options, and process any we find. if (HeaderLength != sizeof(IPHeader)) { IPOptInfo OptInfo;

OptInfo.ioi_options = (uchar *)(Header + 1); OptInfo.ioi_optlength = HeaderLength - sizeof(IPHeader); // Validate options, and set up indices. if ((ErrIndex = ParseRcvdOptions(&OptInfo, &Index)) < MAX_OPT_SIZE) { IPSInfo.ipsi_inhdrerrors++; SendICMPErr(SrcNTE->nte_addr, Header, ICMP_PARAM_PROBLEM, PTR_VALID, net_long((ulong)ErrIndex + sizeof(IPHeader))); return; }

Options = CTEAllocMem(OptInfo.ioi_optlength); if (!Options) { IPSInfo.ipsi_outdiscards++; return; // Couldn't get an } // option buffer, return;

// Now copy into our buffer. CTEMemCopy(Options, OptInfo.ioi_options, OptLength = OptInfo.ioi_optlength);

// See if we have a source routing option, and if so we may need to process it. If // we have one, and the destination in the header is us, we need to update the // route and the header. if (Index.oi_srindex != MAX_OPT_SIZE) { if (DestType >= DEST_REMOTE) { // Not for us. if (Index.oi_srtype == IP_OPT_SSRR) { // This packet is strict source routed, but we're not the destination! // We can't continue from here - perhaps we should send an ICMP, but // I'm not sure which one it would be. CTEFreeMem(Options); IPSInfo.ipsi_inaddrerrors++; return; } Index.oi_srindex = MAX_OPT_SIZE; // Don't need to update this.

} else { // This came here, we need to update the destination address. uchar *SROpt = Options + Index.oi_srindex; uchar Pointer;

Pointer = SROpt[IP_OPT_PTR] - 1; // Index starts from one.

// Get the next hop address, and see if it's a broadcast. DestAddr = *(IPAddr UNALIGNED *)&SROpt[Pointer]; DestType = GetAddrType(DestAddr); // Find address type. if (DestType == DEST_INVALID) { SendICMPErr(SrcNTE->nte_addr, Header, ICMP_DEST_UNREACH, SR_FAILED, 0); IPSInfo.ipsi_inhdrerrors++; CTEFreeMem(Options); return; }

// If we came through here, any sort of broadcast needs to be sent out // the way it came, so update that flag. SendOnSource = TRUE; } } } else { // No options. Options = (uchar *)NULL; OptLength = 0; }

IPSInfo.ipsi_forwdatagrams++;

// We've processed the options. Now look up the next hop. If we can't // find one, send back an error. IF = LookupNextHop(DestAddr, SrcNTE->nte_addr, &NextHop, &MTU);

if (IF == NULL) { // Couldn't find an outgoing route. IPSInfo.ipsi_outnoroutes++; SendICMPErr(SrcNTE->nte_addr, Header, ICMP_DEST_UNREACH, HOST_UNREACH, 0); if (Options) CTEFreeMem(Options); return; }

// If we have a strict source route and the next hop is not the one // specified, send back an error. if (Index.oi_srtype == IP_OPT_SSRR) if (DestAddr != NextHop) { IPSInfo.ipsi_outnoroutes++; SendICMPErr(SrcNTE->nte_addr, Header, ICMP_DEST_UNREACH, SR_FAILED, 0); CTEFreeMem(Options); return; }

// Update the options, if we can and we need to. if ((DestType != DEST_BCAST) && Options != NULL) { NetTableEntry *OutNTE;

// Need to find a valid source address for the outgoing interface. CTEGetLock(&RouteTableLock, &TableHandle); OutNTE = BestNTEForIF(DestAddr, IF); if (OutNTE == NULL) { // No NTE for this IF. Something's wrong, just bail out. CTEFreeLock(&RouteTableLock, TableHandle); CTEFreeMem(Options); return; } else { OutAddr = OutNTE->nte_addr; CTEFreeLock(&RouteTableLock, TableHandle); }

ErrIndex = UpdateOptions(Options, &Index, (IP_LOOPBACK(OutAddr) ? DestAddr : OutAddr)); if (ErrIndex != MAX_OPT_SIZE) { IPSInfo.ipsi_inhdrerrors++; SendICMPErr(OutAddr, Header, ICMP_PARAM_PROBLEM, PTR_VALID, net_long((ulong)ErrIndex + sizeof(IPHeader))); CTEFreeMem(Options); return; } }

// Send a redirect, if we need to. We'll send a redirect if the packet // is going out on the interface it came in on and the next hop address // is on the same subnet as the NTE we received it on, and if there // are no source route options. We also need to make sure that the // source of the datagram is on the I/F we received it on, so we don't // send a redirect to another gateway. // SendICMPErr will check and not send a redirect if this is a broadcast. if ((SrcNTE->nte_if == IF) && IP_ADDR_EQUAL(SrcNTE->nte_addr & SrcNTE->nte_mask, NextHop & SrcNTE->nte_mask) && IP_ADDR_EQUAL(SrcNTE->nte_addr & SrcNTE->nte_mask, Header->iph_src & SrcNTE->nte_mask)) {

if (Index.oi_srindex == MAX_OPT_SIZE) SendICMPErr(SrcNTE->nte_addr, Header, ICMP_REDIRECT, REDIRECT_HOST, NextHop); }

// We have the next hop. Now get a forwarding packet. if ((NewHeader = GetFWPacket(&Packet, IF, DestType)) != (IPHeader *)NULL) {

// Got the header. Fill it in. *NewHeader = *Header; NewHeader->iph_dest = DestAddr; NewHeader->iph_ttl = Header->iph_ttl - 1; NewHeader->iph_xsum = 0;

// Save the packet forwarding context info. FWC = (FWContext *)Packet->ProtocolReserved; FWC->fc_options = Options; FWC->fc_optlength = OptLength; FWC->fc_if = IF; FWC->fc_mtu = MTU; FWC->fc_srcnte = SrcNTE; FWC->fc_nexthop = NextHop; FWC->fc_sos = SendOnSource; FWC->fc_dtype = DestType; FWC->fc_index = Index;

// Now that we have a packet, go ahead and transfer data the // data in if we need to. Status = GetFWBuffer(SrcNTE, Packet, Data, DataLength, BufferLength, HeaderLength, LContext1, LContext2);

// If the status is pending, don't do anything now. Otherwise, // if the status is success send the packet. if (Status != NDIS_STATUS_PENDING) if (Status == NDIS_STATUS_SUCCESS) { SendFWPacket(Packet, Status, DataLength); } else { // Some sort of failure. Free the packet. IPSInfo.ipsi_outdiscards++; FreeFWPacket(Packet); } } else { // Couldn't get a packet, so drop this. IPSInfo.ipsi_outdiscards++; if (Options) CTEFreeMem(Options); } } else { // Forward called, but forwarding // turned off. if (DestType != DEST_BCAST && DestType != DEST_SN_BCAST) { // No need to go through here for strictly broadcast packets, // although we want to bump the counters for remote bcast stuff. IPSInfo.ipsi_inaddrerrors++;

if (!IS_BCAST_DEST(DestType)) { if (DestType == DEST_LOCAL) // Called when local, must be SR. SendICMPErr(SrcNTE->nte_addr, Header, ICMP_DEST_UNREACH, SR_FAILED, 0); else // Not a source route, just HOST_UNREACH SendICMPErr(SrcNTE->nte_addr, Header, ICMP_DEST_UNREACH, HOST_UNREACH, 0); } } }

} "

In case I am wrong I will also post other option related code from this "unit" / c file:

" //** OpenRCE - Open an RCE for a specific route. // // Called by the upper layer to open an RCE. We look up the type of the address // - if it's invalid, we return 'Destination invalid'. If not, we look up the // route, fill in the RCE, and link it on the correct RTE. // // As an added bonus, this routine will return the local address to use // to reach the destination. // // Entry: Address - Address for which we are to open an RCE. // Src - Source address we'll be using. // RCE - Pointer to where to return pointer to RCE. // Type - Pointer to where to return destination type. // MSS - Pointer to where to return MSS for route. // OptInfo - Pointer to option information, such as TOS and // any source routing info. // // Returns: Source IP address to use. This will be NULL_IP_ADDR if the // specified destination is unreachable for any reason. // IPAddr OpenRCE(IPAddr Address, IPAddr Src, RouteCacheEntry **RCE, uchar *Type, ushort *MSS, IPOptInfo *OptInfo) { RouteTableEntry *RTE; // Pointer to RTE to put RCE on. CTELockHandle TableLock; uchar LocalType;

if (!IP_ADDR_EQUAL(OptInfo->ioi_addr, NULL_IP_ADDR)) Address = OptInfo->ioi_addr;

CTEGetLock(&RouteTableLock, &TableLock);

// Make sure we're not in DHCP update. if (DHCPActivityCount != 0) { // We are updating DHCP. Just fail this now, since we're in an // indeterminate state. CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; }

LocalType = GetAddrType(Address);

*Type = LocalType;

// If the specified address isn't invalid, continue. if (LocalType != DEST_INVALID) { RouteCacheEntry *NewRCE;

// If he's specified a source address, loop through the NTE table // now and make sure it's valid. if (!IP_ADDR_EQUAL(Src, NULL_IP_ADDR)) { NetTableEntry *NTE;

for (NTE = NetTableList; NTE != NULL; NTE = NTE->nte_next) if ((NTE->nte_flags & NTE_VALID) && IP_ADDR_EQUAL(Src, NTE->nte_addr)) break;

if (NTE == NULL) { // Didn't find a match. CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; } }

// Find the route for this guy. If we can't find one, return NULL. RTE = LookupRTE(Address, Src, HOST_ROUTE_PRI);

if (RTE != (RouteTableEntry *)NULL) { IPAddr NewSrc; CTELockHandle RCEHandle; RouteCacheEntry *OldRCE; NetTableEntry *SrcNTE;

// We found one. *MSS = (ushort)RTE->rte_mtu; // Return the route MTU. if (IP_LOOPBACK_ADDR(Src) && (RTE->rte_if != &LoopInterface)) { // The upper layer is sending from a loopback address, but the // destination isn't reachable through the loopback interface. // Fail the request. CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; }

// We have the RTE. Fill in the RCE, and link it on the RTE. if (!IP_ADDR_EQUAL(RTE->rte_addr, IPADDR_LOCAL)) *Type |= DEST_OFFNET_BIT; // Tell upper layer it's off // net.

// First, see if an RCE already exists for this. if ((OldRCE = FindRCE(RTE, Address, Src)) == NULL) {

// If the destination is local to this host (i.e. // loopback), we'll use the destination address as the // source. if (LocalType == DEST_LOCAL) NewSrc = Address; else { SrcNTE = BestNTEForIF(Address, RTE->rte_if); if (SrcNTE == NULL) { // Can't find an address! Fail the request. CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; } NewSrc = SrcNTE->nte_addr; }

// Don't have an existing RCE. See if we can get a new one, // and fill it in.

NewRCE = CTEAllocMem(sizeof(RouteCacheEntry)); *RCE = NewRCE;

if (NewRCE != NULL) { CTEMemSet(NewRCE, 0, sizeof(RouteCacheEntry));

// Save the source address for this one. We use the // caller specified address if provided, otherwise we // use the best local address. if (IP_ADDR_EQUAL(Src, NULL_IP_ADDR)) NewRCE->rce_src = NewSrc; else NewRCE->rce_src = Src;

NewRCE->rce_dtype = LocalType; NewRCE->rce_cnt = 1; CTEInitLock(&NewRCE->rce_lock); NewRCE->rce_dest = Address; NewRCE->rce_rte = RTE; NewRCE->rce_valid = TRUE; NewRCE->rce_next = RTE->rte_rcelist; RTE->rte_rcelist = NewRCE; }

CTEFreeLock(&RouteTableLock, TableLock); return NewSrc; } else { // We have an existing RCE. We'll return his source as the // valid source, bump the reference count, free the locks // and return. CTEGetLock(&OldRCE->rce_lock, &RCEHandle); NewSrc = OldRCE->rce_src; OldRCE->rce_cnt++; *RCE = OldRCE; CTEFreeLock(&OldRCE->rce_lock, RCEHandle); CTEFreeLock(&RouteTableLock, TableLock); return NewSrc; } } else { CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; } }

CTEFreeLock(&RouteTableLock, TableLock); return NULL_IP_ADDR; }

//* FreeFWPacket - Free a forwarding packet when we're done with it. // // // Input: Packet - Packet to be freed. // // Returns: Nothing. // void FreeFWPacket(PNDIS_PACKET Packet) { CTELockHandle Handle; FWContext *FWC;

// BUGBUG - Portability issue

#ifdef VXD Packet->Private.Head = (PNDIS_BUFFER)NULL; Packet->Private.Count = 0; Packet->Private.PhysicalCount = 0; Packet->Private.TotalLength = 0; #else // VXD #ifdef NT // // BUGBUG: This is inefficient. Need something better. // NdisReinitializePacket(Packet); #else // NT #error Need portable way to do this. #endif // NT #endif // VXD

FWC = (FWContext *)Packet->ProtocolReserved; if (FWC->fc_options) { CTEFreeMem(FWC->fc_options); FWC->fc_options = (uchar *)NULL; }

if (FWC->fc_buffhead) { CTEGetLock(&FWBufFreeLock, &Handle); FWC->fc_bufftail->Next = FWBufFree; // BUGBUG more portable. FWBufFree = FWC->fc_buffhead; CTEFreeLock(&FWBufFreeLock, Handle); FWC->fc_buffhead = (PNDIS_BUFFER)NULL; }

CTEGetLock(&FWPacketFreeLock, &Handle); FWC->fc_pc.pc_common.pc_link = FWPacketFree; FWPacketFree = Packet; CTEFreeLock(&FWPacketFreeLock, Handle);

}

//* TransmitFWPacket - Transmit a forwarded packet on a link. // // Called when we know we can send a packet. We fix up the header, and send it. // // Input: Packet - Packet to be sent. // DataLength - Length of data. // // Returns: Nothing. // void TransmitFWPacket(PNDIS_PACKET Packet, uint DataLength) { FWContext *FC = (FWContext *)Packet->ProtocolReserved; PNDIS_BUFFER HBuffer, Buffer; IP_STATUS Status; PVOID VirtualAddress; UINT BufLen;

// Fix up the packet. Remove the existing buffer chain, and put our header on // the front.

// BUGBUG - Get NDIS fixed to make this portable. #ifdef VXD Buffer = Packet->Private.Head; HBuffer = FC->fc_hndisbuff; Packet->Private.Head = HBuffer; Packet->Private.Tail = HBuffer; HBuffer->Next = (PNDIS_BUFFER)NULL; Packet->Private.TotalLength = sizeof(IPHeader); Packet->Private.Count = 1;

Packet->Private.PhysicalCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(HBuffer->VirtualAddress, sizeof(IPHeader)); #else // VXD #ifdef NT Buffer = Packet->Private.Head; HBuffer = FC->fc_hndisbuff; Packet->Private.Head = HBuffer; Packet->Private.Tail = HBuffer; NDIS_BUFFER_LINKAGE(HBuffer) = (PNDIS_BUFFER)NULL; Packet->Private.TotalLength = sizeof(IPHeader); Packet->Private.Count = 1;

NdisQueryBuffer(Buffer, &VirtualAddress, &BufLen);

Packet->Private.PhysicalCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES( VirtualAddress, sizeof(IPHeader) ); #else // NT #error HELP! Need to make this code portable. #endif // NT #endif // VXD

// Figure out how to send it. If it's not a broadcast we'll either send it or // have it fragmented. If it is a broadcast we'll let our send broadcast routine // handle it. if (FC->fc_dtype != DEST_BCAST) {

if ((DataLength + (uint)FC->fc_optlength) fc_mtu) Status = SendIPPacket(FC->fc_if, FC->fc_nexthop, Packet, Buffer, FC->fc_hbuff, FC->fc_options, (uint)FC->fc_optlength); else { // Need to fragment this. BufferReference *BR = CTEAllocMem(sizeof(BufferReference));

if (BR == (BufferReference *)NULL) { // Couldn't get a BufferReference FWSendComplete(Packet, Buffer); return; } BR->br_buffer = Buffer; BR->br_refcount = 0; CTEInitLock(&BR->br_lock); FC->fc_pc.pc_br = BR; Status = IPFragment(FC->fc_if, FC->fc_mtu, FC->fc_nexthop, Packet, FC->fc_hbuff, Buffer, DataLength, FC->fc_options, (uint)FC->fc_optlength, (int *)NULL);

if (Status == IP_PACKET_TOO_BIG) // Couldn't fragment. // For MTU discovery pass MTU back here. SendICMPErr(FC->fc_srcnte->nte_addr, FC->fc_hbuff, ICMP_DEST_UNREACH, FRAG_NEEDED, 0);

} } else Status = SendIPBCast(FC->fc_srcnte, FC->fc_nexthop, Packet, FC->fc_hbuff, Buffer, DataLength, FC->fc_options, (uint)FC->fc_optlength, FC->fc_sos, &FC->fc_index);

if (Status != IP_PENDING) FWSendComplete(Packet, Buffer); } "

Unfortunately the comp.lang.c newsgroup is banned on google groups, now I can see another reason why ! ;) =D

If you do manage to find the bug, I would like to know about it ! ;)

Even better would be a "proof of concept" code to exploit/test it.

Bye for now, Skybuck.

Reply to
skybuck2000

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.