Skip to content

Commit

Permalink
!12788 slip: make slhc_remember() more robust against malicious packets
Browse files Browse the repository at this point in the history
  • Loading branch information
openeuler-ci-bot authored and gitee-org committed Nov 3, 2024
2 parents 1b17e41 + df94256 commit 1f6ceb3
Showing 1 changed file with 34 additions and 23 deletions.
57 changes: 34 additions & 23 deletions drivers/net/slip/slhc.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,46 +643,57 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize)
int
slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
{
struct cstate *cs;
unsigned ihl;

const struct tcphdr *th;
unsigned char index;
struct iphdr *iph;
struct cstate *cs;
unsigned int ihl;

if(isize < 20) {
/* The packet is shorter than a legal IP header */
/* The packet is shorter than a legal IP header.
* Also make sure isize is positive.
*/
if (isize < (int)sizeof(struct iphdr)) {
runt:
comp->sls_i_runt++;
return slhc_toss( comp );
return slhc_toss(comp);
}
iph = (struct iphdr *)icp;
/* Peek at the IP header's IHL field to find its length */
ihl = icp[0] & 0xf;
if(ihl < 20 / 4){
/* The IP header length field is too small */
comp->sls_i_runt++;
return slhc_toss( comp );
}
index = icp[9];
icp[9] = IPPROTO_TCP;
ihl = iph->ihl;
/* The IP header length field is too small,
* or packet is shorter than the IP header followed
* by minimal tcp header.
*/
if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr))
goto runt;

index = iph->protocol;
iph->protocol = IPPROTO_TCP;

if (ip_fast_csum(icp, ihl)) {
/* Bad IP header checksum; discard */
comp->sls_i_badcheck++;
return slhc_toss( comp );
return slhc_toss(comp);
}
if(index > comp->rslot_limit) {
if (index > comp->rslot_limit) {
comp->sls_i_error++;
return slhc_toss(comp);
}

th = (struct tcphdr *)(icp + ihl * 4);
if (th->doff < sizeof(struct tcphdr) / 4)
goto runt;
if (isize < ihl * 4 + th->doff * 4)
goto runt;
/* Update local state */
cs = &comp->rstate[comp->recv_current = index];
comp->flags &=~ SLF_TOSS;
memcpy(&cs->cs_ip,icp,20);
memcpy(&cs->cs_tcp,icp + ihl*4,20);
memcpy(&cs->cs_ip, iph, sizeof(*iph));
memcpy(&cs->cs_tcp, th, sizeof(*th));
if (ihl > 5)
memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);
if (cs->cs_tcp.doff > 5)
memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4);
if (th->doff > 5)
memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4);
cs->cs_hsize = ihl*2 + th->doff*2;
cs->initialized = true;
/* Put headers back on packet
* Neither header checksum is recalculated
Expand Down

0 comments on commit 1f6ceb3

Please sign in to comment.