Skip to content

Commit ed4b205

Browse files
authored
Merge 5911559 into 602b957
2 parents 602b957 + 5911559 commit ed4b205

7 files changed

Lines changed: 633 additions & 158 deletions

File tree

NEWS.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ For a complete and more detailed list of changes, please refer to the
1717
ChangeLog file (generated for release archives), or to the Git version
1818
control history for "live" codebase.
1919

20+
Release notes for NUT 2.8.6 - what's new since 2.8.5
21+
----------------------------------------------------
22+
23+
https://github.com/networkupstools/nut/milestone/13
24+
25+
- common code:
26+
* Revised 'dstate' machinery to track socket connections closed mid-way
27+
through a call, to avoid access after `free()`. [#3302]
2028

2129
PLANNED: Release notes for NUT 2.8.6 - what's new since 2.8.5
2230
-------------------------------------------------------------

common/wincompat.c

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ char *getpass(const char *prompt)
6868
{
6969
HANDLE hStdin;
7070
DWORD mode;
71+
size_t len;
7172

7273
hStdin = GetStdHandle(STD_INPUT_HANDLE);
7374
if (hStdin == INVALID_HANDLE_VALUE) {
@@ -86,8 +87,9 @@ char *getpass(const char *prompt)
8687
}
8788

8889
/* deal with that pesky newline */
89-
if (strlen(wincompat_password) > 1) {
90-
wincompat_password[strlen(wincompat_password) - 1] = '\0';
90+
len = strlen(wincompat_password);
91+
if (len > 1) {
92+
wincompat_password[len - 1] = '\0';
9193
}
9294

9395
hStdin = GetStdHandle(STD_INPUT_HANDLE);
@@ -407,6 +409,7 @@ int win_system(const char * command)
407409
si.cb = sizeof(si);
408410
memset(&pi, 0, sizeof(pi));
409411

412+
upsdebugx(4, "%s: calling CreateProcess: %s", __func__, NUT_STRARG(command));
410413
res = CreateProcess(NULL, (char *)command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
411414

412415
if (res != 0) {
@@ -417,20 +420,22 @@ int win_system(const char * command)
417420
}
418421

419422
/* the " character is forbiden in Windows files , so we filter this character
420-
in data file paths to be coherent with command line which require " to
421-
distinguish the command from its parameter. This avoid complicated
422-
explanation in the documentation */
423+
* in data file paths to be coherent with command line which require " to
424+
* distinguish the command from its parameter. This avoid complicated
425+
* explanation in the documentation */
423426
char * filter_path(const char * source)
424427
{
425428
char *res;
426429
unsigned int i, j;
430+
size_t len;
427431

428432
if (source == NULL) {
429433
return NULL;
430434
}
431435

432-
res = xmalloc(strlen(source) + 1);
433-
for (i=0, j=0; i <= strlen(source); i++) {
436+
len = strlen(source);
437+
res = xmalloc(len + 1);
438+
for (i=0, j=0; i <= len; i++) {
434439
if (source[i] != '"') {
435440
res[j] = source[i];
436441
j++;
@@ -474,6 +479,7 @@ void syslog(int priority, const char *fmt, ...)
474479
/* then comes the message */
475480
memcpy(buf1 + sizeof(DWORD), buf2, sizeof(buf2));
476481

482+
upsdebugx(6, "%s: posting to event log NAMED_PIPE: '%s'", __func__, pipe_full_name);
477483
pipe = CreateFile(
478484
pipe_full_name, /* pipe name */
479485
GENERIC_WRITE,
@@ -484,6 +490,10 @@ void syslog(int priority, const char *fmt, ...)
484490
NULL); /* no template file */
485491

486492
if (pipe == INVALID_HANDLE_VALUE) {
493+
upsdebug_with_errno(1,
494+
"%s: SKIP: can't open existing event log NAMED_PIPE: '%s'",
495+
__func__, pipe_full_name);
496+
487497
return;
488498
}
489499

@@ -492,6 +502,7 @@ void syslog(int priority, const char *fmt, ...)
492502
/* testing result is useless. If we have an error and try to report it,
493503
* this will probably lead to a call to this function and an infinite
494504
* loop */
505+
upsdebugx(6, "%s: closing event log NAMED_PIPE", __func__);
495506
CloseHandle(pipe);
496507
}
497508

@@ -526,6 +537,7 @@ void pipe_create(const char * pipe_name)
526537
CloseHandle(pipe_connection_overlapped.hEvent);
527538
}
528539
memset(&pipe_connection_overlapped, 0, sizeof(pipe_connection_overlapped));
540+
upsdebugx(2, "%s: creating NAMED_PIPE (listener): '%s'", __func__, pipe_full_name);
529541
pipe_connection_handle = CreateNamedPipe(
530542
pipe_full_name,
531543
PIPE_ACCESS_INBOUND /* to server only */
@@ -560,7 +572,7 @@ void pipe_create(const char * pipe_name)
560572
/* Wait for a connection */
561573
ret = ConnectNamedPipe(pipe_connection_handle, &pipe_connection_overlapped);
562574
if (ret == 0 && GetLastError() != ERROR_IO_PENDING) {
563-
upslogx(LOG_ERR, "ConnectNamedPipe error");
575+
upslog_with_errno(LOG_ERR, "ConnectNamedPipe error");
564576
}
565577
}
566578

@@ -569,6 +581,12 @@ void pipe_connect()
569581
/* We have detected a connection on the opened pipe. So we start by saving its handle and create a new pipe for future connections */
570582
pipe_conn_t *conn;
571583

584+
/* TOTHINK: Here we seem to have assumptions about a general connection
585+
* via overlapped I/O being the signal to daemon (via named_pipe_name)...
586+
* might this conflict with other I/Os (driver/server sockets, dummy-ups
587+
* files, etc.)?
588+
*/
589+
upsdebugx(3, "%s: handle incoming connection on NAMED PIPE", __func__);
572590
conn = xcalloc(1, sizeof(*conn));
573591
conn->handle = pipe_connection_handle;
574592

@@ -587,7 +605,7 @@ void pipe_connect()
587605
);
588606
if (conn->overlapped.hEvent == NULL) {
589607
/* FIXME: Is this (still) about event log only? */
590-
upslogx(LOG_ERR, "Can't create event for reading event log");
608+
upslog_with_errno(LOG_ERR, "Can't create event for reading event log");
591609
return;
592610
}
593611

@@ -605,17 +623,20 @@ void pipe_connect()
605623

606624
void pipe_disconnect(pipe_conn_t *conn)
607625
{
626+
upsdebugx(3, "%s: starting", __func__);
627+
608628
if (conn->overlapped.hEvent != INVALID_HANDLE_VALUE) {
629+
upsdebugx(4, "%s: calling CloseHandle() for conn->overlapped.hEvent", __func__);
609630
CloseHandle(conn->overlapped.hEvent);
610631
conn->overlapped.hEvent = INVALID_HANDLE_VALUE;
611632
}
612633

613634
if (conn->handle != INVALID_HANDLE_VALUE) {
635+
upsdebugx(4, "%s: calling DisconnectNamedPipe() for not-yet-invalid conn->handle", __func__);
614636
if (DisconnectNamedPipe(conn->handle) == 0) {
615-
upslogx(LOG_ERR,
616-
"DisconnectNamedPipe error : %d",
617-
(int)GetLastError());
637+
upslog_with_errno(LOG_ERR, "DisconnectNamedPipe failed");
618638
}
639+
upsdebugx(4, "%s: calling CloseHandle() for conn->handle", __func__);
619640
CloseHandle(conn->handle);
620641
conn->handle = INVALID_HANDLE_VALUE;
621642
}
@@ -642,7 +663,7 @@ int pipe_ready(pipe_conn_t *conn)
642663

643664
res = GetOverlappedResult(conn->handle, &conn->overlapped, &bytesRead, FALSE);
644665
if (res == 0) {
645-
upslogx(LOG_ERR, "Pipe read error");
666+
upslog_with_errno(LOG_ERR, "Pipe read error");
646667
pipe_disconnect(conn);
647668
return 0;
648669
}
@@ -657,9 +678,11 @@ int send_to_named_pipe(const char * pipe_name, const char * data)
657678
BOOL result = FALSE;
658679
DWORD bytesWritten = 0;
659680
char pipe_full_name[NUT_PATH_MAX + 1];
681+
size_t len;
660682

661683
snprintf(pipe_full_name, sizeof(pipe_full_name), "\\\\.\\pipe\\%s", pipe_name);
662684

685+
upsdebugx(6, "%s: posting to NAMED_PIPE: '%s'", __func__, pipe_full_name);
663686
pipe = CreateFile(
664687
pipe_full_name,
665688
GENERIC_WRITE,
@@ -670,16 +693,23 @@ int send_to_named_pipe(const char * pipe_name, const char * data)
670693
NULL); /* no template file */
671694

672695
if (pipe == INVALID_HANDLE_VALUE) {
696+
upsdebug_with_errno(1,
697+
"%s: SKIP: can't open existing NAMED_PIPE: '%s'",
698+
__func__, pipe_full_name);
699+
673700
return 1;
674701
}
675702

676-
result = WriteFile(pipe, data, strlen(data) + 1, &bytesWritten, NULL);
703+
len = strlen(data);
704+
result = WriteFile(pipe, data, len + 1, &bytesWritten, NULL);
677705

678-
if (result == 0 || bytesWritten != strlen(data) + 1) {
706+
if (result == 0 || bytesWritten != len + 1) {
707+
upsdebug_with_errno(6, "%s: closing event log NAMED_PIPE, did not write as much as expected to", __func__);
679708
CloseHandle(pipe);
680709
return 1;
681710
}
682711

712+
upsdebugx(6, "%s: closing event log NAMED_PIPE", __func__);
683713
CloseHandle(pipe);
684714
return 0;
685715
}
@@ -955,7 +985,7 @@ serial_handler_t * w32_serial_open(const char *name, int flags)
955985
0);
956986

957987
if (sh->handle == INVALID_HANDLE_VALUE) {
958-
upslogx(LOG_ERR, "could not open %s", name);
988+
upslog_with_errno(LOG_ERR, "could not open %s", name);
959989
errno = EPERM;
960990
return NULL;
961991
}
@@ -994,7 +1024,7 @@ serial_handler_t * w32_serial_open(const char *name, int flags)
9941024
state.fAbortOnError = TRUE;
9951025

9961026
if (!SetCommState(sh->handle, &state)) {
997-
upslogx(LOG_ERR,
1027+
upslog_with_errno(LOG_ERR,
9981028
"couldn't set initial state for %s",
9991029
name);
10001030
}
@@ -1125,7 +1155,7 @@ int tcflush(serial_handler_t *sh, int queue)
11251155
if (queue == TCOFLUSH || queue == TCIOFLUSH)
11261156
PurgeComm(sh->handle, PURGE_TXABORT | PURGE_TXCLEAR);
11271157

1128-
if ((queue == TCIFLUSH) | (queue == TCIOFLUSH))
1158+
if ((queue == TCIFLUSH) || (queue == TCIOFLUSH))
11291159
{
11301160
/* Input flushing by polling until nothing turns up
11311161
* (we stop after 1000 chars anyway) */
@@ -1469,7 +1499,7 @@ TCSAFLUSH: flush output and discard input, then change attributes.
14691499
res = SetCommTimeouts(sh->handle, &to);
14701500
if (!res)
14711501
{
1472-
upslogx(LOG_ERR, "SetCommTimeout failed");
1502+
upslog_with_errno(LOG_ERR, "SetCommTimeout failed");
14731503
errno = EIO;
14741504
return -1;
14751505
}

0 commit comments

Comments
 (0)