mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-03 21:14:40 +08:00
Compare commits
16 Commits
STABLE-2_2
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4599f551de | ||
![]() |
41a36098b3 | ||
![]() |
e7ab7e0773 | ||
![]() |
b1edb7780f | ||
![]() |
56b29f8bcf | ||
![]() |
92522e4538 | ||
![]() |
571c46253f | ||
![]() |
ca0395c5ae | ||
![]() |
31d8988f89 | ||
![]() |
f877b457a1 | ||
![]() |
6c8874bf5d | ||
![]() |
8459488006 | ||
![]() |
ffce5ab1c7 | ||
![]() |
e55896319b | ||
![]() |
ba306bcdaa | ||
![]() |
554e104095 |
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-20.04' }}
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
actions: read
|
||||
|
@ -6,6 +6,11 @@ HISTORY
|
||||
|
||||
* [Enter new changes just after this line - do not remove this line]
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2025-06-03: Simon Goldschmidt
|
||||
* ip4_frag/ip6_frag: fix potential NULL-pointer access on memory errors
|
||||
|
||||
(STABLE-2.2.1):
|
||||
|
||||
++ New features:
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "lwIP"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "2.2.1"
|
||||
PROJECT_NUMBER = "2.2.2.dev"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
@ -14,11 +14,11 @@ endif()
|
||||
|
||||
set(LWIP_VERSION_MAJOR "2")
|
||||
set(LWIP_VERSION_MINOR "2")
|
||||
set(LWIP_VERSION_REVISION "1")
|
||||
set(LWIP_VERSION_REVISION "2")
|
||||
# LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases
|
||||
# LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions
|
||||
# Numbers 1..31 are reserved for release candidates
|
||||
set(LWIP_VERSION_RC "LWIP_RC_RELEASE")
|
||||
set(LWIP_VERSION_RC "LWIP_RC_DEVELOPMENT")
|
||||
|
||||
if ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE")
|
||||
set(LWIP_VERSION_STRING
|
||||
|
@ -576,6 +576,10 @@ const struct altcp_functions altcp_proxyconnect_functions = {
|
||||
altcp_default_get_tcp_addrinfo,
|
||||
altcp_default_get_ip,
|
||||
altcp_default_get_port
|
||||
#if LWIP_TCP_KEEPALIVE
|
||||
, altcp_default_keepalive_disable
|
||||
, altcp_default_keepalive_enable
|
||||
#endif
|
||||
#ifdef LWIP_DEBUG
|
||||
, altcp_default_dbg_get_tcp_state
|
||||
#endif
|
||||
|
@ -120,7 +120,6 @@
|
||||
#define CRLF "\r\n"
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
#define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive"
|
||||
#define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive"
|
||||
#endif
|
||||
|
||||
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||
@ -2100,8 +2099,7 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct altcp_pcb *pc
|
||||
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
|
||||
/* This is HTTP/1.0 compatible: for strict 1.1, a connection
|
||||
would always be persistent unless "close" was specified. */
|
||||
if (!is_09 && (lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) ||
|
||||
lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) {
|
||||
if (!is_09 && lwip_strnistr(data, HTTP11_CONNECTIONKEEPALIVE, data_len)) {
|
||||
hs->keepalive = 1;
|
||||
} else {
|
||||
hs->keepalive = 0;
|
||||
|
@ -463,14 +463,8 @@ snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value
|
||||
if ((len > 0) && (len < 5)) {
|
||||
PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data));
|
||||
|
||||
if (data & 0x80) {
|
||||
/* negative, start from -1 */
|
||||
*value = -1;
|
||||
*value = (*value << 8) | data;
|
||||
} else {
|
||||
/* positive, start from 0 */
|
||||
*value = data;
|
||||
}
|
||||
/* sign extension */
|
||||
*value = (s8_t)data;
|
||||
len--;
|
||||
/* shift in the remaining value */
|
||||
while (len > 0) {
|
||||
|
@ -454,10 +454,12 @@ tftp_init_common(u8_t mode, const struct tftp_context *ctx)
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT);
|
||||
if (ret != ERR_OK) {
|
||||
udp_remove(pcb);
|
||||
return ret;
|
||||
if (mode & LWIP_TFTP_MODE_SERVER) {
|
||||
ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT);
|
||||
if (ret != ERR_OK) {
|
||||
udp_remove(pcb);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
tftp_state.handle = NULL;
|
||||
|
@ -223,9 +223,10 @@ autoip_conflict_callback(struct netif *netif, acd_callback_enum_t state)
|
||||
autoip_restart(netif);
|
||||
break;
|
||||
case ACD_DECLINE:
|
||||
/* "delete" conflicting address so a new one will be selected in
|
||||
* autoip_start() */
|
||||
/* "delete" conflicting address and increment tried addr so a new one
|
||||
* will be selected in autoip_start() */
|
||||
ip4_addr_set_any(&autoip->llipaddr);
|
||||
autoip->tried_llipaddr++;
|
||||
autoip_stop(netif);
|
||||
break;
|
||||
default:
|
||||
|
@ -773,9 +773,6 @@ dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
|
||||
* @ingroup dhcp4
|
||||
* Removes a struct dhcp from a netif.
|
||||
*
|
||||
* ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
|
||||
* struct dhcp since the memory is passed back to the heap.
|
||||
*
|
||||
* @param netif the netif from which to remove the struct dhcp
|
||||
*/
|
||||
void dhcp_cleanup(struct netif *netif)
|
||||
@ -811,6 +808,7 @@ dhcp_start(struct netif *netif)
|
||||
{
|
||||
struct dhcp *dhcp;
|
||||
err_t result;
|
||||
u8_t saved_flags;
|
||||
|
||||
LWIP_ASSERT_CORE_LOCKED();
|
||||
LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;);
|
||||
@ -833,6 +831,8 @@ dhcp_start(struct netif *netif)
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
/* clear the flags, the rest is cleared below */
|
||||
dhcp->flags = 0;
|
||||
/* store this dhcp client in the netif */
|
||||
netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp\n"));
|
||||
@ -846,9 +846,10 @@ dhcp_start(struct netif *netif)
|
||||
/* dhcp is cleared below, no need to reset flag*/
|
||||
}
|
||||
|
||||
/* clear data structure */
|
||||
/* clear data structure but preserve DHCP_FLAG_EXTERNAL_MEM for dhcp_cleanup() */
|
||||
saved_flags = dhcp->flags;
|
||||
memset(dhcp, 0, sizeof(struct dhcp));
|
||||
/* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */
|
||||
dhcp->flags = saved_flags & DHCP_FLAG_EXTERNAL_MEM;
|
||||
|
||||
|
||||
#if LWIP_DHCP_DOES_ACD_CHECK
|
||||
|
@ -940,9 +940,9 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
|
||||
netif_addr_idx_t i;
|
||||
|
||||
/* non-unicast address? */
|
||||
if (ip4_addr_isbroadcast(ipaddr, netif) ||
|
||||
ip4_addr_ismulticast(ipaddr) ||
|
||||
ip4_addr_isany(ipaddr)) {
|
||||
if (ip4_addr_isany(ipaddr) ||
|
||||
ip4_addr_isbroadcast(ipaddr, netif) ||
|
||||
ip4_addr_ismulticast(ipaddr)) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
@ -175,19 +175,21 @@ ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *p
|
||||
|
||||
MIB2_STATS_INC(mib2.ipreasmfails);
|
||||
#if LWIP_ICMP
|
||||
iprh = (struct ip_reass_helper *)ipr->p->payload;
|
||||
if (iprh->start == 0) {
|
||||
/* The first fragment was received, send ICMP time exceeded. */
|
||||
/* First, de-queue the first pbuf from r->p. */
|
||||
p = ipr->p;
|
||||
ipr->p = iprh->next_pbuf;
|
||||
/* Then, copy the original header into it. */
|
||||
SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
|
||||
icmp_time_exceeded(p, ICMP_TE_FRAG);
|
||||
clen = pbuf_clen(p);
|
||||
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
|
||||
pbufs_freed = (u16_t)(pbufs_freed + clen);
|
||||
pbuf_free(p);
|
||||
if (ipr->p != NULL) {
|
||||
iprh = (struct ip_reass_helper *)ipr->p->payload;
|
||||
if (iprh->start == 0) {
|
||||
/* The first fragment was received, send ICMP time exceeded. */
|
||||
/* First, de-queue the first pbuf from r->p. */
|
||||
p = ipr->p;
|
||||
ipr->p = iprh->next_pbuf;
|
||||
/* Then, copy the original header into it. */
|
||||
SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
|
||||
icmp_time_exceeded(p, ICMP_TE_FRAG);
|
||||
clen = pbuf_clen(p);
|
||||
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
|
||||
pbufs_freed = (u16_t)(pbufs_freed + clen);
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_ICMP */
|
||||
|
||||
|
@ -154,35 +154,37 @@ ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr)
|
||||
struct ip6_reass_helper *iprh;
|
||||
|
||||
#if LWIP_ICMP6
|
||||
iprh = (struct ip6_reass_helper *)ipr->p->payload;
|
||||
if (iprh->start == 0) {
|
||||
/* The first fragment was received, send ICMP time exceeded. */
|
||||
/* First, de-queue the first pbuf from r->p. */
|
||||
p = ipr->p;
|
||||
ipr->p = iprh->next_pbuf;
|
||||
/* Restore the part that we've overwritten with our helper structure, or we
|
||||
* might send garbage (and disclose a pointer) in the ICMPv6 reply. */
|
||||
MEMCPY(p->payload, ipr->orig_hdr, sizeof(*iprh));
|
||||
/* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
|
||||
This cannot fail since we already checked when receiving this fragment. */
|
||||
if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) {
|
||||
LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed", 0);
|
||||
if (ipr->p != NULL) {
|
||||
iprh = (struct ip6_reass_helper *)ipr->p->payload;
|
||||
if (iprh->start == 0) {
|
||||
/* The first fragment was received, send ICMP time exceeded. */
|
||||
/* First, de-queue the first pbuf from r->p. */
|
||||
p = ipr->p;
|
||||
ipr->p = iprh->next_pbuf;
|
||||
/* Restore the part that we've overwritten with our helper structure, or we
|
||||
* might send garbage (and disclose a pointer) in the ICMPv6 reply. */
|
||||
MEMCPY(p->payload, ipr->orig_hdr, sizeof(*iprh));
|
||||
/* Then, move back to the original ipv6 header (we are now pointing to Fragment header).
|
||||
This cannot fail since we already checked when receiving this fragment. */
|
||||
if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)ipr->iphdr))) {
|
||||
LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed", 0);
|
||||
}
|
||||
else {
|
||||
/* Reconstruct the zoned source and destination addresses, so that we do
|
||||
* not end up sending the ICMP response over the wrong link. */
|
||||
ip6_addr_t src_addr, dest_addr;
|
||||
ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr));
|
||||
ip6_addr_set_zone(&src_addr, ipr->src_zone);
|
||||
ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr));
|
||||
ip6_addr_set_zone(&dest_addr, ipr->dest_zone);
|
||||
/* Send the actual ICMP response. */
|
||||
icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr);
|
||||
}
|
||||
clen = pbuf_clen(p);
|
||||
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
|
||||
pbufs_freed = (u16_t)(pbufs_freed + clen);
|
||||
pbuf_free(p);
|
||||
}
|
||||
else {
|
||||
/* Reconstruct the zoned source and destination addresses, so that we do
|
||||
* not end up sending the ICMP response over the wrong link. */
|
||||
ip6_addr_t src_addr, dest_addr;
|
||||
ip6_addr_copy_from_packed(src_addr, IPV6_FRAG_SRC(ipr));
|
||||
ip6_addr_set_zone(&src_addr, ipr->src_zone);
|
||||
ip6_addr_copy_from_packed(dest_addr, IPV6_FRAG_DEST(ipr));
|
||||
ip6_addr_set_zone(&dest_addr, ipr->dest_zone);
|
||||
/* Send the actual ICMP response. */
|
||||
icmp6_time_exceeded_with_addrs(p, ICMP6_TE_FRAG, &src_addr, &dest_addr);
|
||||
}
|
||||
clen = pbuf_clen(p);
|
||||
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
|
||||
pbufs_freed = (u16_t)(pbufs_freed + clen);
|
||||
pbuf_free(p);
|
||||
}
|
||||
#endif /* LWIP_ICMP6 */
|
||||
|
||||
|
@ -1993,17 +1993,17 @@ tcp_parseopt(struct tcp_pcb *pcb)
|
||||
return;
|
||||
}
|
||||
/* TCP timestamp option with valid length */
|
||||
tsval = tcp_get_next_optbyte();
|
||||
tsval |= (tcp_get_next_optbyte() << 8);
|
||||
tsval = (tcp_get_next_optbyte() << 24);
|
||||
tsval |= (tcp_get_next_optbyte() << 16);
|
||||
tsval |= (tcp_get_next_optbyte() << 24);
|
||||
tsval |= (tcp_get_next_optbyte() << 8);
|
||||
tsval |= tcp_get_next_optbyte();
|
||||
if (flags & TCP_SYN) {
|
||||
pcb->ts_recent = lwip_ntohl(tsval);
|
||||
pcb->ts_recent = tsval;
|
||||
/* Enable sending timestamps in every segment now that we know
|
||||
the remote host supports it. */
|
||||
tcp_set_flags(pcb, TF_TIMESTAMP);
|
||||
} else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) {
|
||||
pcb->ts_recent = lwip_ntohl(tsval);
|
||||
pcb->ts_recent = tsval;
|
||||
}
|
||||
/* Advance to next option (6 bytes already read) */
|
||||
tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
|
||||
|
@ -54,11 +54,11 @@ extern "C" {
|
||||
/** x.X.x: Minor version of the stack */
|
||||
#define LWIP_VERSION_MINOR 2
|
||||
/** x.x.X: Revision of the stack */
|
||||
#define LWIP_VERSION_REVISION 1
|
||||
#define LWIP_VERSION_REVISION 2
|
||||
/** For release candidates, this is set to 1..254
|
||||
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
|
||||
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
|
||||
#define LWIP_VERSION_RC LWIP_RC_RELEASE
|
||||
#define LWIP_VERSION_RC LWIP_RC_DEVELOPMENT
|
||||
|
||||
/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
|
||||
#define LWIP_RC_RELEASE 255
|
||||
|
@ -519,6 +519,7 @@ START_TEST(test_ip6_reass)
|
||||
test_ip6_reass_helper(130, t3, NUM_SEGS, 8);
|
||||
test_ip6_reass_helper(130, t4, NUM_SEGS, 1448);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/** Create the suite including all tests for this module */
|
||||
Suite *
|
||||
|
@ -534,15 +534,13 @@ START_TEST(test_tcp_fast_retx_recover)
|
||||
EXPECT_RET(txcounters.num_tx_calls == 0);
|
||||
EXPECT_RET(txcounters.num_tx_bytes == 0);
|
||||
memset(&txcounters, 0, sizeof(txcounters));
|
||||
|
||||
do
|
||||
{
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
|
||||
i++;
|
||||
}while(err == ERR_OK);
|
||||
EXPECT_RET(err != ERR_OK);
|
||||
}
|
||||
err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY);
|
||||
}while(err == ERR_OK);
|
||||
EXPECT_RET(err != ERR_OK);
|
||||
|
||||
err = tcp_output(pcb);
|
||||
EXPECT_RET(err == ERR_OK);
|
||||
/*EXPECT_RET(txcounters.num_tx_calls == 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user