summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2018-07-11 18:35:46 +1000
committerKarolin Seeger <kseeger@samba.org>2019-03-26 07:49:18 +0000
commitcd5f1904032e9fcb62ad8094addc841a6b9cb73a (patch)
tree64085415d944ece33d743beaf115f3ed49148fc0
parent2c89c38851874637e1a7c92ce913427279b1cbe6 (diff)
downloadsamba-cd5f1904032e9fcb62ad8094addc841a6b9cb73a.tar.gz
ctdb-protocol: Avoid fgets in ctdb_connection_list_read
C library buffering API can behave in unexpected fashion if underlying fd for stdin, stdout or stderr is closed and re-opened. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13520 Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net> (cherry picked from commit c9b42d27e6cf9e6ae36f44970f0a388edc737a7a)
-rw-r--r--ctdb/protocol/protocol_util.c86
-rw-r--r--ctdb/wscript4
2 files changed, 51 insertions, 39 deletions
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c
index c75555fa734..45c639d747f 100644
--- a/ctdb/protocol/protocol_util.c
+++ b/ctdb/protocol/protocol_util.c
@@ -22,6 +22,8 @@
#include <talloc.h>
+#include "common/line.h"
+
#include "protocol.h"
#include "protocol_util.h"
@@ -603,56 +605,66 @@ const char *ctdb_connection_list_to_string(
return out;
}
-int ctdb_connection_list_read(TALLOC_CTX *mem_ctx, bool client_first,
- struct ctdb_connection_list **conn_list)
-{
+struct ctdb_connection_list_read_state {
struct ctdb_connection_list *list;
- char line[128]; /* long enough for IPv6 */
+ bool client_first;
+};
+
+static int ctdb_connection_list_read_line(char *line, void *private_data)
+{
+ struct ctdb_connection_list_read_state *state =
+ (struct ctdb_connection_list_read_state *)private_data;
+ struct ctdb_connection conn;
int ret;
- if (conn_list == NULL) {
- return EINVAL;
+ /* Skip empty lines */
+ if (line[0] == '\0') {
+ return 0;
}
- list = talloc_zero(mem_ctx, struct ctdb_connection_list);
- if (list == NULL) {
- return ENOMEM;
+ /* Comment */
+ if (line[0] == '#') {
+ return 0;
}
- while (fgets(line, sizeof(line), stdin) != NULL) {
- char *t;
- struct ctdb_connection conn;
+ ret = ctdb_connection_from_string(line, state->client_first, &conn);
+ if (ret != 0) {
+ return ret;
+ }
- /* Skip empty lines */
- if (line[0] == '\n') {
- continue;
- }
+ ret = ctdb_connection_list_add(state->list, &conn);
+ if (ret != 0) {
+ return ret;
+ }
- /* Comment */
- if (line[0] == '#') {
- continue;
- }
+ return 0;
+}
- t = strtok(line, "\n");
- if (t == NULL) {
- goto fail;
- }
+int ctdb_connection_list_read(TALLOC_CTX *mem_ctx, bool client_first,
+ struct ctdb_connection_list **conn_list)
+{
+ struct ctdb_connection_list_read_state state;
+ int ret;
- ret = ctdb_connection_from_string(t, client_first, &conn);
- if (ret != 0) {
- goto fail;
- }
+ if (conn_list == NULL) {
+ return EINVAL;
+ }
- ret = ctdb_connection_list_add(list, &conn);
- if (ret != 0) {
- goto fail;
- }
+ state.list = talloc_zero(mem_ctx, struct ctdb_connection_list);
+ if (state.list == NULL) {
+ return ENOMEM;
}
- *conn_list = list;
- return 0;
+ state.client_first = client_first;
+
+ ret = line_read(0,
+ 128,
+ mem_ctx,
+ ctdb_connection_list_read_line,
+ &state,
+ NULL);
-fail:
- talloc_free(list);
- return EINVAL;
+ *conn_list = state.list;
+
+ return ret;
}
diff --git a/ctdb/wscript b/ctdb/wscript
index e3bcdf7e962..8727fd8aefa 100644
--- a/ctdb/wscript
+++ b/ctdb/wscript
@@ -433,7 +433,7 @@ def build(bld):
bld.SAMBA_SUBSYSTEM('ctdb-protocol-util',
source='protocol/protocol_util.c',
- deps='replace talloc tdb')
+ deps='ctdb-util replace talloc tdb')
bld.SAMBA_SUBSYSTEM('ctdb-client',
source=bld.SUBDIR('client', 'ctdb_client.c'),
@@ -824,7 +824,7 @@ def build(bld):
bld.SAMBA_BINARY(target,
source=src,
deps='''protocol-tests-common
- samba-util talloc tdb''',
+ samba-util ctdb-util talloc tdb''',
install_path='${CTDB_TEST_LIBEXECDIR}')
bld.SAMBA_SUBSYSTEM('ctdb-tests-common',