Skip to content

Commit 2bab4a5

Browse files
committed
libct/nsenter: fix logging race in nsexec
As reported in issue 3119, there is a race in nsexec logging that can lead to garbled json received by log forwarder, which complains about it with a "failed to decode" error. This happens because dprintf (used since the very beginning of nsexec logging introduced in commit ba3cabf) relies on multiple write(2) calls, and with additional logging added by 64bb59f a race is possible between runc init parent and its children. The fix is to prepare a string and write it using a single call to write(2). [v2: NULLify json on error from asprintf] Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 16027b8 commit 2bab4a5

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

libcontainer/nsenter/nsexec.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ int setns(int fd, int nstype)
136136

137137
static void write_log(const char *level, const char *format, ...)
138138
{
139-
char *message = NULL, *stage = NULL;
139+
char *message = NULL, *stage = NULL, *json = NULL;
140140
va_list args;
141141
int ret;
142142

@@ -158,11 +158,18 @@ static void write_log(const char *level, const char *format, ...)
158158
if (ret < 0)
159159
goto out;
160160

161-
dprintf(logfd, "{\"level\":\"%s\", \"msg\": \"%s[%d]: %s\"}\n", level, stage, getpid(), message);
161+
ret = asprintf(&json, "{\"level\":\"%s\", \"msg\": \"%s[%d]: %s\"}\n", level, stage, getpid(), message);
162+
if (ret < 0) {
163+
json = NULL;
164+
goto out;
165+
}
166+
167+
write(logfd, json, ret);
162168

163169
out:
164170
free(message);
165171
free(stage);
172+
free(json);
166173
}
167174

168175
/* XXX: This is ugly. */

0 commit comments

Comments
 (0)