Skip to content

Commit 72b8e88

Browse files
ejohnstownpadelsbach
authored andcommitted
Share one ID counter for SFTP handles
- Merge fileIdCount and dirIdCount into a single handleIdCount. - File and directory handle IDs now share one namespace. - A close or other handle op cannot match the wrong resource type.
1 parent dc4df8d commit 72b8e88

2 files changed

Lines changed: 47 additions & 38 deletions

File tree

src/wolfsftp.c

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,6 +2276,34 @@ int ff_pread(int fd, byte *buffer, int sz)
22762276

22772277
#endif /* WOLFSSH_FATFS */
22782278

2279+
#ifndef NO_WOLFSSH_SERVER
2280+
2281+
/* SFTP handle IDs are an opaque WOLFSSH_HANDLE_ID_SZ byte session value made
2282+
* up of two big-endian word32s. */
2283+
static void SFTP_HandleIdDecode(const byte* in, word32 id[2])
2284+
{
2285+
ato32(in, &id[0]);
2286+
ato32(in + UINT32_SZ, &id[1]);
2287+
}
2288+
2289+
2290+
static void SFTP_HandleIdEncode(const word32 id[2], byte* out)
2291+
{
2292+
c32toa(id[0], out);
2293+
c32toa(id[1], out + UINT32_SZ);
2294+
}
2295+
2296+
2297+
/* Take the next session handle ID and advance the shared counter. */
2298+
static void SFTP_HandleIdNext(WOLFSSH* ssh, word32 id[2])
2299+
{
2300+
id[0] = ssh->handleIdCount[0];
2301+
id[1] = ssh->handleIdCount[1];
2302+
AddAssign64(ssh->handleIdCount, 1);
2303+
}
2304+
2305+
#endif /* !NO_WOLFSSH_SERVER */
2306+
22792307
/* Handles packet to open a file
22802308
*
22812309
* returns WS_SUCCESS on success
@@ -2442,9 +2470,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
24422470

24432471
if (ret == WS_SUCCESS) {
24442472
/* Generate unique file handle ID and add to tracking list */
2445-
id[0] = ssh->fileIdCount[0];
2446-
id[1] = ssh->fileIdCount[1];
2447-
AddAssign64(ssh->fileIdCount, 1);
2473+
SFTP_HandleIdNext(ssh, id);
24482474

24492475
if ((ret = SFTP_AddFileHandle(ssh, fd, dir, id)) != WS_SUCCESS) {
24502476
WLOG(WS_LOG_SFTP, "Unable to store handle");
@@ -2469,8 +2495,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
24692495
}
24702496

24712497
if (ret == WS_SUCCESS) {
2472-
c32toa(id[0], idFlat);
2473-
c32toa(id[1], idFlat + UINT32_SZ);
2498+
SFTP_HandleIdEncode(id, idFlat);
24742499
if (SFTP_CreatePacket(ssh, WOLFSSH_FTP_HANDLE, out, outSz,
24752500
idFlat, sizeof(idFlat)) != WS_SUCCESS) {
24762501
ret = WS_FATAL_ERROR;
@@ -2626,9 +2651,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
26262651

26272652
if (ret == WS_SUCCESS) {
26282653
/* Generate unique file handle ID and add to tracking list */
2629-
id[0] = ssh->fileIdCount[0];
2630-
id[1] = ssh->fileIdCount[1];
2631-
AddAssign64(ssh->fileIdCount, 1);
2654+
SFTP_HandleIdNext(ssh, id);
26322655

26332656
if (SFTP_AddFileHandle(ssh, fileHandle, dir, id) != WS_SUCCESS) {
26342657
WLOG(WS_LOG_SFTP, "Unable to store handle");
@@ -2653,8 +2676,7 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
26532676
}
26542677

26552678
if (ret == WS_SUCCESS) {
2656-
c32toa(id[0], idFlat);
2657-
c32toa(id[1], idFlat + UINT32_SZ);
2679+
SFTP_HandleIdEncode(id, idFlat);
26582680
if (SFTP_CreatePacket(ssh, WOLFSSH_FTP_HANDLE, out, outSz,
26592681
idFlat, sizeof(idFlat)) != WS_SUCCESS) {
26602682
ret = WS_FATAL_ERROR;
@@ -2731,7 +2753,6 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
27312753

27322754
word32 outSz = WOLFSSH_HANDLE_ID_SZ + WOLFSSH_SFTP_HEADER + UINT32_SZ;
27332755
byte* out = NULL;
2734-
word32 id[2];
27352756
byte idFlat[WOLFSSH_HANDLE_ID_SZ];
27362757
char per[] = "Permission denied";
27372758

@@ -2798,11 +2819,8 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
27982819
#else
27992820
cur->dir = ctx;
28002821
#endif
2801-
cur->id[0] = id[0] = ssh->dirIdCount[0];
2802-
cur->id[1] = id[1] = ssh->dirIdCount[1];
2803-
c32toa(id[0], idFlat);
2804-
c32toa(id[1], idFlat + UINT32_SZ);
2805-
AddAssign64(ssh->dirIdCount, 1);
2822+
SFTP_HandleIdNext(ssh, cur->id);
2823+
SFTP_HandleIdEncode(cur->id, idFlat);
28062824
cur->isEof = 0;
28072825
cur->next = ssh->dirList;
28082826
ssh->dirList = cur;
@@ -2846,7 +2864,6 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
28462864

28472865
word32 outSz = WOLFSSH_HANDLE_ID_SZ + WOLFSSH_SFTP_HEADER + UINT32_SZ;
28482866
byte* out = NULL;
2849-
word32 id[2];
28502867
byte idFlat[WOLFSSH_HANDLE_ID_SZ];
28512868
char name[MAX_PATH];
28522869
char clean[WOLFSSH_MAX_FILENAME];
@@ -2957,11 +2974,8 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
29572974
return WS_MEMORY_E;
29582975
}
29592976
cur->dir = INVALID_HANDLE_VALUE;
2960-
cur->id[0] = id[0] = ssh->dirIdCount[0];
2961-
cur->id[1] = id[1] = ssh->dirIdCount[1];
2962-
c32toa(id[0], idFlat);
2963-
c32toa(id[1], idFlat + UINT32_SZ);
2964-
AddAssign64(ssh->dirIdCount, 1);
2977+
SFTP_HandleIdNext(ssh, cur->id);
2978+
SFTP_HandleIdEncode(cur->id, idFlat);
29652979
cur->isEof = 0;
29662980
cur->dirName = dirName; /* take over ownership of buffer */
29672981
cur->next = ssh->dirList;
@@ -3925,8 +3939,7 @@ int wolfSSH_SFTP_RecvCloseDir(WOLFSSH* ssh, byte* handle, word32 handleSz)
39253939

39263940
/* find DIR given handle */
39273941
cur = ssh->dirList;
3928-
ato32(handle, &h[0]);
3929-
ato32(handle + UINT32_SZ, &h[1]);
3942+
SFTP_HandleIdDecode(handle, h);
39303943
while (cur != NULL) {
39313944
if (cur->id[0] == h[0] && cur->id[1] == h[1]) {
39323945
break;
@@ -4152,8 +4165,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
41524165
word32 handle[2] = {0, 0};
41534166
WS_FILE_LIST* fileEntry = NULL;
41544167

4155-
ato32(str, &handle[0]);
4156-
ato32(str + UINT32_SZ, &handle[1]);
4168+
SFTP_HandleIdDecode(str, handle);
41574169

41584170
fileEntry = SFTP_FindFileHandle(ssh, handle);
41594171
if (fileEntry == NULL) {
@@ -4274,8 +4286,7 @@ int wolfSSH_SFTP_RecvWrite(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
42744286
word32 handle[2] = {0, 0};
42754287
WS_FILE_LIST* fileEntry = NULL;
42764288

4277-
ato32(str, &handle[0]);
4278-
ato32(str + UINT32_SZ, &handle[1]);
4289+
SFTP_HandleIdDecode(str, handle);
42794290

42804291
fileEntry = SFTP_FindFileHandle(ssh, handle);
42814292
if (fileEntry == NULL) {
@@ -4375,8 +4386,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
43754386
word32 handle[2] = {0, 0};
43764387
WS_FILE_LIST* fileEntry = NULL;
43774388

4378-
ato32(str, &handle[0]);
4379-
ato32(str + UINT32_SZ, &handle[1]);
4389+
SFTP_HandleIdDecode(str, handle);
43804390

43814391
/* Find the file handle in our tracking list */
43824392
fileEntry = SFTP_FindFileHandle(ssh, handle);
@@ -4504,8 +4514,7 @@ int wolfSSH_SFTP_RecvRead(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
45044514
word32 handle[2] = {0, 0};
45054515
WS_FILE_LIST* fileEntry = NULL;
45064516

4507-
ato32(str, &handle[0]);
4508-
ato32(str + UINT32_SZ, &handle[1]);
4517+
SFTP_HandleIdDecode(str, handle);
45094518

45104519
/* Find the file handle in our tracking list */
45114520
fileEntry = SFTP_FindFileHandle(ssh, handle);
@@ -5696,8 +5705,7 @@ int wolfSSH_SFTP_RecvFSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
56965705
WS_FILE_LIST* cur;
56975706
word32 handleId[2] = {0, 0};
56985707

5699-
ato32(handle, &handleId[0]);
5700-
ato32(handle + UINT32_SZ, &handleId[1]);
5708+
SFTP_HandleIdDecode(handle, handleId);
57015709

57025710
cur = SFTP_FindFileHandle(ssh, handleId);
57035711
if (cur == NULL) {
@@ -6176,8 +6184,7 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
61766184
word32 handle[2] = {0, 0};
61776185
WS_FILE_LIST* fileEntry = NULL;
61786186

6179-
ato32(str, &handle[0]);
6180-
ato32(str + UINT32_SZ, &handle[1]);
6187+
SFTP_HandleIdDecode(str, handle);
61816188

61826189
/* Find the file handle in our tracking list */
61836190
fileEntry = SFTP_FindFileHandle(ssh, handle);

wolfssh/internal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,9 +927,11 @@ struct WOLFSSH {
927927
char* sftpDefaultPath;
928928
#ifndef NO_WOLFSSH_DIR
929929
WS_DIR_LIST* dirList;
930-
word32 dirIdCount[2];
931930
#endif
932-
word32 fileIdCount[2];
931+
/* Shared counter for both file and directory handle IDs. A single
932+
* namespace guarantees IDs are unique across files and directories so a
933+
* close request cannot match the wrong resource type. */
934+
word32 handleIdCount[2];
933935
WS_FILE_LIST* fileList;
934936
struct WS_SFTP_RECV_INIT_STATE* recvInitState;
935937
struct WS_SFTP_RECV_STATE* recvState;

0 commit comments

Comments
 (0)