Skip to content

Commit a5bcb63

Browse files
committed
Fix a problem where filesystem writes could overwrite the firmware.
Fix a bug where connections can be leaked on connection failures.
1 parent 59521b7 commit a5bcb63

File tree

5 files changed

+53
-16
lines changed

5 files changed

+53
-16
lines changed

parallax/cgiprop.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,16 +146,19 @@ int ICACHE_FLASH_ATTR cgiPropInit()
146146
// GPIO_OUTPUT_SET(flashConfig.reset_pin, 1);
147147
GPIO_DIS_OUTPUT(flashConfig.reset_pin);
148148

149+
uint32_t fs_base, fs_size;
150+
fs_base = roffs_base_address(&fs_size);
151+
149152
int ret;
150-
if ((ret = roffs_mount(roffs_base_address())) != 0) {
153+
if ((ret = roffs_mount(fs_base, fs_size)) != 0) {
151154
os_printf("Mounting flash filesystem failed: %d\n", ret);
152155
os_printf("Attempting to format...");
153-
if ((ret = roffs_format(roffs_base_address())) != 0) {
156+
if ((ret = roffs_format(fs_base)) != 0) {
154157
os_printf("Error formatting filesystem: %d\n", ret);
155158
return -1;
156159
}
157160
os_printf("Flash filesystem formatted.\n");
158-
if ((ret = roffs_mount(roffs_base_address())) != 0) {
161+
if ((ret = roffs_mount(fs_base, fs_size)) != 0) {
159162
os_printf("Mounting newly formatted flash filesystem failed: %d\n", ret);
160163
return -1;
161164
}

parallax/httpdroffs.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,15 @@ int ICACHE_FLASH_ATTR cgiRoffsFormat(HttpdConnData *connData)
117117
#endif
118118
if (connData->conn == NULL)
119119
return HTTPD_CGI_DONE;
120-
if (roffs_format(roffs_base_address()) != 0) {
120+
121+
uint32_t fs_base, fs_size;
122+
fs_base = roffs_base_address(&fs_size);
123+
124+
if (roffs_format(fs_base) != 0) {
121125
httpdSendResponse(connData, 400, "Error formatting filesystem\r\n", -1);
122126
return HTTPD_CGI_DONE;
123127
}
124-
if (roffs_mount(roffs_base_address()) != 0) {
128+
if (roffs_mount(fs_base, fs_size) != 0) {
125129
httpdSendResponse(connData, 400, "Error mounting newly formatted flash filesystem\r\n", -1);
126130
return HTTPD_CGI_DONE;
127131
}

parallax/roffs.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ Connector to let httpd use the espfs filesystem to serve the files in it.
3030

3131
#include "roffsformat.h"
3232

33+
// default filesystem size in flash
34+
#define FLASH_FILESYSTEM_SIZE_1M (128*1024)
35+
#define FLASH_FILESYSTEM_SIZE_2M (1*1024*1024)
36+
#define FLASH_FILESYSTEM_SIZE_4M (3*1024*1024)
37+
3338
// default filesystem base address in flash
34-
#define FLASH_FILESYSTEM_BASE_1M (512*1024 - 128*1024)
35-
#define FLASH_FILESYSTEM_BASE_2M (1024*1024)
39+
#define FLASH_FILESYSTEM_BASE_1M (512*1024-FLASH_FILESYSTEM_SIZE_1M)
40+
#define FLASH_FILESYSTEM_BASE_2M_4M (1024*1024)
3641

3742
// open file structure
3843
struct ROFFS_FILE_STRUCT {
@@ -48,30 +53,41 @@ struct ROFFS_FILE_STRUCT {
4853

4954
// initialize to an invalid address to indicate that no filesystem is mounted
5055
static uint32_t fsData = BAD_FILESYSTEM_BASE;
56+
static uint32_t fsSize = 0;
57+
static uint32_t fsTop = 0;
5158

5259
static int readFlash(uint32_t addr, void *buf, int size);
5360
static int writeFlash(uint32_t addr, void *buf, int size);
5461
static int updateFlash(uint32_t addr, void *buf, int size);
5562

56-
uint32_t roffs_base_address(void)
63+
uint32_t roffs_base_address(uint32_t *pSize)
5764
{
5865
uint32_t base;
5966
switch (system_get_flash_size_map()) {
60-
case FLASH_SIZE_8M_MAP_512_512:
67+
case FLASH_SIZE_8M_MAP_512_512: // 1MB
6168
base = FLASH_FILESYSTEM_BASE_1M;
69+
*pSize = FLASH_FILESYSTEM_SIZE_1M;
70+
os_printf("1MB flash: base %08x, size %d\n", base, *pSize);
71+
break;
72+
case FLASH_SIZE_16M_MAP_512_512: // 2MB
73+
base = FLASH_FILESYSTEM_BASE_2M_4M;
74+
*pSize = FLASH_FILESYSTEM_SIZE_2M;
75+
os_printf("2MB flash: base %08x, size %d\n", base, *pSize);
6276
break;
63-
case FLASH_SIZE_16M_MAP_512_512:
64-
case FLASH_SIZE_32M_MAP_512_512:
65-
base = FLASH_FILESYSTEM_BASE_2M;
77+
case FLASH_SIZE_32M_MAP_512_512: // 4MB
78+
base = FLASH_FILESYSTEM_BASE_2M_4M;
79+
*pSize = FLASH_FILESYSTEM_SIZE_4M;
80+
os_printf("4MB flash: base %08x, size %d\n", base, *pSize);
6681
break;
6782
default:
6883
base = 0;
84+
os_printf("Unknown flash size\n");
6985
break;
7086
}
7187
return base;
7288
}
7389

74-
int ICACHE_FLASH_ATTR roffs_mount(uint32_t flashAddress)
90+
int ICACHE_FLASH_ATTR roffs_mount(uint32_t flashAddress, uint32_t flashSize)
7591
{
7692
RoFsHeader testHeader;
7793

@@ -91,8 +107,11 @@ int ICACHE_FLASH_ATTR roffs_mount(uint32_t flashAddress)
91107
return -3;
92108

93109
// filesystem is mounted successfully
94-
DBG("mount: flash filesystem mounted at %08x\n", flashAddress);
110+
DBG("mount: flash filesystem mounted at %08x, size %d\n", flashAddress, flashSize);
95111
fsData = flashAddress;
112+
fsSize = flashSize;
113+
fsTop = fsData + fsSize;
114+
96115
return 0;
97116
}
98117

@@ -509,6 +528,11 @@ DBG("create: can't find insertion point\n");
509528
return NULL;
510529
}
511530

531+
if (insertionOffset + 2 * sizeof(RoFsHeader) > fsTop) {
532+
DBG("write: insufficient space\n");
533+
return NULL;
534+
}
535+
512536
if (!(file = (ROFFS_FILE *)os_malloc(sizeof(ROFFS_FILE)))) {
513537
DBG("create: insufficient memory\n");
514538
return NULL;
@@ -559,6 +583,10 @@ DBG("create: error reading new file name\n");
559583
int ICACHE_FLASH_ATTR roffs_write(ROFFS_FILE *file, char *buf, int len)
560584
{
561585
int roundedLen = (len + 3) & ~3;
586+
if (file->start + file->size + roundedLen > fsTop) {
587+
DBG("write: insufficient space\n");
588+
return -1;
589+
}
562590
if (writeFlash(file->start + file->size, (uint32 *)buf, roundedLen) != SPI_FLASH_RESULT_OK) {
563591
DBG("write: error writing to file\n");
564592
return -1;

parallax/roffs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ Connector to let httpd use the espfs filesystem to serve the files in it.
2828
#include "roffsformat.h"
2929
typedef struct ROFFS_FILE_STRUCT ROFFS_FILE;
3030

31-
uint32_t roffs_base_address(void);
32-
int roffs_mount(uint32_t flashAddress);
31+
uint32_t roffs_base_address(uint32_t *pSize);
32+
int roffs_mount(uint32_t flashAddress, uint32_t flashSize);
3333
int roffs_format(uint32_t flashAddress);
3434
int roffs_filecount(int *pCount);
3535
int roffs_fileinfo(int index, char *fileName, int *pFileSize);

parallax/sscp-tcp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void ICACHE_FLASH_ATTR tcp_do_connect(int argc, char *argv[])
7272
sscp_log("TCP: looking up '%s'", argv[1]);
7373
return;
7474
default:
75+
sscp_close_connection(c);
7576
sscp_sendResponse("E,%d", SSCP_ERROR_LOOKUP_FAILED);
7677
return;
7778
}
@@ -80,6 +81,7 @@ void ICACHE_FLASH_ATTR tcp_do_connect(int argc, char *argv[])
8081
memcpy(conn->proto.tcp->remote_ip, &ipAddr.addr, 4);
8182

8283
if (espconn_connect(conn) != ESPCONN_OK) {
84+
sscp_close_connection(c);
8385
sscp_sendResponse("E,%d", SSCP_ERROR_CONNECT_FAILED);
8486
return;
8587
}

0 commit comments

Comments
 (0)