mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2025-08-04 21:44:38 +08:00
memp_memory could be unaligned, causing one buffer in the memp pool to
be unaligned, resulting in nasty random data corruption on some CPUs. Also, clean up the code a little and save a few bytes.
This commit is contained in:
parent
313743c833
commit
680afa4229
132
src/core/memp.c
132
src/core/memp.c
@ -49,22 +49,22 @@ struct memp {
|
|||||||
struct memp *next;
|
struct memp *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MEMP_SIZE MEM_ALIGN_SIZE(sizeof(struct memp))
|
||||||
|
|
||||||
static struct memp *memp_tab[MEMP_MAX];
|
static struct memp *memp_tab[MEMP_MAX];
|
||||||
|
|
||||||
static const u16_t memp_sizes[MEMP_MAX] = {
|
static const u16_t memp_sizes[MEMP_MAX] = {
|
||||||
sizeof(struct pbuf),
|
MEM_ALIGN_SIZE(sizeof(struct pbuf)),
|
||||||
sizeof(struct raw_pcb),
|
MEM_ALIGN_SIZE(sizeof(struct raw_pcb)),
|
||||||
sizeof(struct udp_pcb),
|
MEM_ALIGN_SIZE(sizeof(struct udp_pcb)),
|
||||||
sizeof(struct tcp_pcb),
|
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb)),
|
||||||
sizeof(struct tcp_pcb_listen),
|
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)),
|
||||||
sizeof(struct tcp_seg),
|
MEM_ALIGN_SIZE(sizeof(struct tcp_seg)),
|
||||||
sizeof(struct netbuf),
|
MEM_ALIGN_SIZE(sizeof(struct netbuf)),
|
||||||
sizeof(struct netconn),
|
MEM_ALIGN_SIZE(sizeof(struct netconn)),
|
||||||
sizeof(struct api_msg),
|
MEM_ALIGN_SIZE(sizeof(struct api_msg)),
|
||||||
sizeof(struct tcpip_msg),
|
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg)),
|
||||||
sizeof(struct sys_timeout)
|
MEM_ALIGN_SIZE(sizeof(struct sys_timeout))
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16_t memp_num[MEMP_MAX] = {
|
static const u16_t memp_num[MEMP_MAX] = {
|
||||||
@ -81,40 +81,21 @@ static const u16_t memp_num[MEMP_MAX] = {
|
|||||||
MEMP_NUM_SYS_TIMEOUT
|
MEMP_NUM_SYS_TIMEOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
static u8_t memp_memory[(MEMP_NUM_PBUF *
|
#define MEMP_TYPE_SIZE(qty, type) \
|
||||||
MEM_ALIGN_SIZE(sizeof(struct pbuf) +
|
((qty) * (MEMP_SIZE + MEM_ALIGN_SIZE(sizeof(type))))
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_RAW_PCB *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_UDP_PCB *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_TCP_PCB *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_TCP_PCB_LISTEN *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_TCP_SEG *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_NETBUF *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct netbuf) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_NETCONN *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct netconn) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_API_MSG *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct api_msg) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_TCPIP_MSG *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
|
|
||||||
sizeof(struct memp)) +
|
|
||||||
MEMP_NUM_SYS_TIMEOUT *
|
|
||||||
MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
|
|
||||||
sizeof(struct memp)))];
|
|
||||||
|
|
||||||
|
static u8_t memp_memory[MEM_ALIGNMENT - 1 +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_PBUF, struct pbuf) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_RAW_PCB, struct raw_pcb) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_UDP_PCB, struct udp_pcb) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_TCP_PCB, struct tcp_pcb) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_TCP_PCB_LISTEN, struct tcp_pcb_listen) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_TCP_SEG, struct tcp_seg) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_NETBUF, struct netbuf) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_NETCONN, struct netconn) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_API_MSG, struct api_msg) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_TCPIP_MSG, struct tcpip_msg) +
|
||||||
|
MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeout)];
|
||||||
|
|
||||||
#if !SYS_LIGHTWEIGHT_PROT
|
#if !SYS_LIGHTWEIGHT_PROT
|
||||||
static sys_sem_t mutex;
|
static sys_sem_t mutex;
|
||||||
@ -127,14 +108,13 @@ memp_sanity(void)
|
|||||||
s16_t i, c;
|
s16_t i, c;
|
||||||
struct memp *m, *n;
|
struct memp *m, *n;
|
||||||
|
|
||||||
for(i = 0; i < MEMP_MAX; i++) {
|
for (i = 0; i < MEMP_MAX; i++) {
|
||||||
for(m = memp_tab[i]; m != NULL; m = m->next) {
|
for (m = memp_tab[i]; m != NULL; m = m->next) {
|
||||||
c = 1;
|
c = 1;
|
||||||
for(n = memp_tab[i]; n != NULL; n = n->next) {
|
for (n = memp_tab[i]; n != NULL; n = n->next) {
|
||||||
if (n == m) {
|
if (n == m && --c < 0) {
|
||||||
--c;
|
return 0; /* LW was: abort(); */
|
||||||
}
|
}
|
||||||
if (c < 0) return 0; /* LW was: abort(); */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,42 +125,30 @@ memp_sanity(void)
|
|||||||
void
|
void
|
||||||
memp_init(void)
|
memp_init(void)
|
||||||
{
|
{
|
||||||
struct memp *m, *memp;
|
struct memp *memp;
|
||||||
u16_t i, j;
|
u16_t i, j;
|
||||||
u16_t size;
|
|
||||||
|
|
||||||
#if MEMP_STATS
|
#if MEMP_STATS
|
||||||
for(i = 0; i < MEMP_MAX; ++i) {
|
for (i = 0; i < MEMP_MAX; ++i) {
|
||||||
lwip_stats.memp[i].used = lwip_stats.memp[i].max =
|
lwip_stats.memp[i].used = lwip_stats.memp[i].max =
|
||||||
lwip_stats.memp[i].err = 0;
|
lwip_stats.memp[i].err = 0;
|
||||||
lwip_stats.memp[i].avail = memp_num[i];
|
lwip_stats.memp[i].avail = memp_num[i];
|
||||||
}
|
}
|
||||||
#endif /* MEMP_STATS */
|
#endif /* MEMP_STATS */
|
||||||
|
|
||||||
memp = (struct memp *)&memp_memory[0];
|
memp = MEM_ALIGN(memp_memory);
|
||||||
for(i = 0; i < MEMP_MAX; ++i) {
|
for (i = 0; i < MEMP_MAX; ++i) {
|
||||||
size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
|
|
||||||
if (memp_num[i] > 0) {
|
|
||||||
memp_tab[i] = memp;
|
|
||||||
m = memp;
|
|
||||||
|
|
||||||
for(j = 0; j < memp_num[i]; ++j) {
|
|
||||||
m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
|
|
||||||
memp = m;
|
|
||||||
m = m->next;
|
|
||||||
}
|
|
||||||
memp->next = NULL;
|
|
||||||
memp = m;
|
|
||||||
} else {
|
|
||||||
memp_tab[i] = NULL;
|
memp_tab[i] = NULL;
|
||||||
|
for (j = 0; j < memp_num[i]; ++j) {
|
||||||
|
memp->next = memp_tab[i];
|
||||||
|
memp_tab[i] = memp;
|
||||||
|
memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !SYS_LIGHTWEIGHT_PROT
|
#if !SYS_LIGHTWEIGHT_PROT
|
||||||
mutex = sys_sem_new(1);
|
mutex = sys_sem_new(1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
@ -211,28 +179,24 @@ memp_malloc(memp_t type)
|
|||||||
lwip_stats.memp[type].max = lwip_stats.memp[type].used;
|
lwip_stats.memp[type].max = lwip_stats.memp[type].used;
|
||||||
}
|
}
|
||||||
#endif /* MEMP_STATS */
|
#endif /* MEMP_STATS */
|
||||||
#if SYS_LIGHTWEIGHT_PROT
|
mem = (u8_t *)memp + MEMP_SIZE;
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
|
||||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
|
||||||
sys_sem_signal(mutex);
|
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
|
||||||
LWIP_ASSERT("memp_malloc: memp properly aligned",
|
LWIP_ASSERT("memp_malloc: memp properly aligned",
|
||||||
((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
|
||||||
|
|
||||||
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
|
||||||
return mem;
|
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %"S16_F"\n", type));
|
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %"S16_F"\n", type));
|
||||||
#if MEMP_STATS
|
#if MEMP_STATS
|
||||||
++lwip_stats.memp[type].err;
|
++lwip_stats.memp[type].err;
|
||||||
#endif /* MEMP_STATS */
|
#endif /* MEMP_STATS */
|
||||||
|
mem = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#if SYS_LIGHTWEIGHT_PROT
|
#if SYS_LIGHTWEIGHT_PROT
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||||
sys_sem_signal(mutex);
|
sys_sem_signal(mutex);
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||||
return NULL;
|
|
||||||
}
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -246,7 +210,8 @@ memp_free(memp_t type, void *mem)
|
|||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
|
|
||||||
|
memp = (struct memp *)((u8_t *)mem - MEMP_SIZE);
|
||||||
|
|
||||||
#if SYS_LIGHTWEIGHT_PROT
|
#if SYS_LIGHTWEIGHT_PROT
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
@ -271,4 +236,3 @@ memp_free(memp_t type, void *mem)
|
|||||||
sys_sem_signal(mutex);
|
sys_sem_signal(mutex);
|
||||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user