w32: Better protect the IO-system's fd_table

* src/w32-io.c (fd_table_lock): New.
(new_fd): Lock allocation of a new slot.
(release_fd): Lock deallocation of a slot.
--

Note that we lock only the allocation but not the sanitiy checks we do
further down in the code.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2016-11-09 08:33:02 +01:00
parent 3509cf2f98
commit 10f2e1c30b
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -84,6 +84,7 @@ static struct
duplicates works just fine. */ duplicates works just fine. */
int dup_from; int dup_from;
} fd_table[MAX_SLAFD]; } fd_table[MAX_SLAFD];
DEFINE_STATIC_LOCK (fd_table_lock);
/* Returns the FD or -1 on resource limit. */ /* Returns the FD or -1 on resource limit. */
@ -92,6 +93,8 @@ new_fd (void)
{ {
int idx; int idx;
LOCK (fd_table_lock);
for (idx = 0; idx < MAX_SLAFD; idx++) for (idx = 0; idx < MAX_SLAFD; idx++)
if (! fd_table[idx].used) if (! fd_table[idx].used)
break; break;
@ -99,14 +102,18 @@ new_fd (void)
if (idx == MAX_SLAFD) if (idx == MAX_SLAFD)
{ {
gpg_err_set_errno (EIO); gpg_err_set_errno (EIO);
return -1; idx = -1;
}
else
{
fd_table[idx].used = 1;
fd_table[idx].handle = INVALID_HANDLE_VALUE;
fd_table[idx].socket = INVALID_SOCKET;
fd_table[idx].rvid = 0;
fd_table[idx].dup_from = -1;
} }
fd_table[idx].used = 1; UNLOCK (fd_table_lock);
fd_table[idx].handle = INVALID_HANDLE_VALUE;
fd_table[idx].socket = INVALID_SOCKET;
fd_table[idx].rvid = 0;
fd_table[idx].dup_from = -1;
return idx; return idx;
} }
@ -115,14 +122,21 @@ new_fd (void)
void void
release_fd (int fd) release_fd (int fd)
{ {
if (fd < 0 || fd >= MAX_SLAFD || !fd_table[fd].used) if (fd < 0 || fd >= MAX_SLAFD)
return; return;
fd_table[fd].used = 0; LOCK (fd_table_lock);
fd_table[fd].handle = INVALID_HANDLE_VALUE;
fd_table[fd].socket = INVALID_SOCKET; if (fd_table[fd].used)
fd_table[fd].rvid = 0; {
fd_table[fd].dup_from = -1; fd_table[fd].used = 0;
fd_table[fd].handle = INVALID_HANDLE_VALUE;
fd_table[fd].socket = INVALID_SOCKET;
fd_table[fd].rvid = 0;
fd_table[fd].dup_from = -1;
}
UNLOCK (fd_table_lock);
} }