Atomically update the global gMsgId in libnetgraph.

Otherwise concurrently running threads may inadvertently use the same
token for different messages.

Preserve the behaviour of disallowing negative message tokens, but allow
a message token value of zero since this simplifies the code a bit and
tokens are documented to be non-negative.

PR:		234442
Reported and tested by:	eugen
MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Mark Johnston 2019-05-10 16:43:47 +00:00
parent 0f78871d44
commit 7f75bbd066

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <stdatomic.h>
#include <netgraph/ng_message.h>
#include <netgraph/ng_socket.h>
@ -51,7 +52,7 @@ __FBSDID("$FreeBSD$");
#include "internal.h"
/* Next message token value */
static int gMsgId;
static _Atomic(unsigned int) gMsgId;
/* For delivering both messages and replies */
static int NgDeliverMsg(int cs, const char *path,
@ -72,9 +73,7 @@ NgSendMsg(int cs, const char *path,
memset(&msg, 0, sizeof(msg));
msg.header.version = NG_VERSION;
msg.header.typecookie = cookie;
if (++gMsgId < 0)
gMsgId = 1;
msg.header.token = gMsgId;
msg.header.token = atomic_fetch_add(&gMsgId, 1) & INT_MAX;
msg.header.flags = NGF_ORIG;
msg.header.cmd = cmd;
snprintf((char *)msg.header.cmdstr, NG_CMDSTRSIZ, "cmd%d", cmd);
@ -143,9 +142,7 @@ NgSendAsciiMsg(int cs, const char *path, const char *fmt, ...)
/* Now send binary version */
binary = (struct ng_mesg *)reply->data;
if (++gMsgId < 0)
gMsgId = 1;
binary->header.token = gMsgId;
binary->header.token = atomic_fetch_add(&gMsgId, 1) & INT_MAX;
binary->header.version = NG_VERSION;
if (NgDeliverMsg(cs,
path, binary, binary->data, binary->header.arglen) < 0) {