Skip to content

Commit 0da26aa

Browse files
committed
libflux: add flux_msg_is_local()
Problem: although the rexec service uses a private broker mechanism to prevent remote use on rank 0, the sdbus service resides in a broker module and doesn't have access to this mechanism and thus cannot differentiate local vs remote clients. Define a new RFC 12 role: FLUX_ROLE_LOCAL. Set FLUX_ROLE_LOCAL in message credentials when a message is received by the local connector or sent by the broker or one of its modules. Clear FLUX_ROLE_LOCAL when a message is received by the broker overlay network. Add an accessor flux_msg_is_local() that can be used to test whether a message was sent locally or has transited brokers. Fix two tests in t0017-security.t that expect a specific rolemask output from ping, that now must include FLUX_ROLE_LOCAL. Fixes #5136
1 parent 1997544 commit 0da26aa

File tree

7 files changed

+44
-4
lines changed

7 files changed

+44
-4
lines changed

src/broker/broker.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ int main (int argc, char *argv[])
217217
ctx.cred.userid = getuid ();
218218
/* Set default rolemask for messages sent with flux_send()
219219
* on the broker's internal handle. */
220-
ctx.cred.rolemask = FLUX_ROLE_OWNER;
220+
ctx.cred.rolemask = FLUX_ROLE_OWNER | FLUX_ROLE_LOCAL;
221221

222222
init_attrs (ctx.attrs, getpid (), &ctx.cred);
223223

src/broker/module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ module_t *module_add (modhash_t *mh,
658658
* credentials are always those of the instance owner.
659659
*/
660660
p->cred.userid = getuid ();
661-
p->cred.rolemask = FLUX_ROLE_OWNER;
661+
p->cred.rolemask = FLUX_ROLE_OWNER | FLUX_ROLE_LOCAL;
662662

663663
/* Update the modhash.
664664
*/

src/broker/overlay.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,18 @@ static void logdrop (struct overlay *ov,
869869
reason);
870870
}
871871

872+
static int clear_msg_role (flux_msg_t *msg, uint32_t role)
873+
{
874+
uint32_t rolemask;
875+
876+
if (flux_msg_get_rolemask (msg, &rolemask) < 0)
877+
return -1;
878+
rolemask &= ~role;
879+
if (flux_msg_set_rolemask (msg, rolemask) < 0)
880+
return -1;
881+
return 0;
882+
}
883+
872884
/* Handle a message received from TBON child (downstream).
873885
*/
874886
static void child_cb (flux_reactor_t *r, flux_watcher_t *w,
@@ -883,6 +895,10 @@ static void child_cb (flux_reactor_t *r, flux_watcher_t *w,
883895

884896
if (!(msg = zmqutil_msg_recv (ov->bind_zsock)))
885897
return;
898+
if (clear_msg_role (msg, FLUX_ROLE_LOCAL) < 0) {
899+
logdrop (ov, OVERLAY_DOWNSTREAM, msg, "failed to clear local role");
900+
goto done;
901+
}
886902
/* Flag this message as remotely received. This allows efficient
887903
* operation of the overlay_msg_is_local() function.
888904
*/
@@ -992,6 +1008,10 @@ static void parent_cb (flux_reactor_t *r, flux_watcher_t *w,
9921008

9931009
if (!(msg = zmqutil_msg_recv (ov->parent.zsock)))
9941010
return;
1011+
if (clear_msg_role (msg, FLUX_ROLE_LOCAL) < 0) {
1012+
logdrop (ov, OVERLAY_UPSTREAM, msg, "failed to clear local role");
1013+
goto done;
1014+
}
9951015
/* Flag this message as remotely received. This allows efficient
9961016
* operation of the overlay_msg_is_local() function.
9971017
*/

src/common/libflux/message.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,15 @@ int flux_msg_authorize (const flux_msg_t *msg, uint32_t userid)
507507
return 0;
508508
}
509509

510+
bool flux_msg_is_local (const flux_msg_t *msg)
511+
{
512+
uint32_t rolemask;
513+
if (flux_msg_get_rolemask (msg, &rolemask) == 0
514+
&& (rolemask & FLUX_ROLE_LOCAL))
515+
return true;
516+
return false;
517+
}
518+
510519
int flux_msg_set_nodeid (flux_msg_t *msg, uint32_t nodeid)
511520
{
512521
if (msg_validate (msg) < 0)

src/common/libflux/message.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ enum {
233233
FLUX_ROLE_NONE = 0,
234234
FLUX_ROLE_OWNER = 1,
235235
FLUX_ROLE_USER = 2,
236+
FLUX_ROLE_LOCAL = 4,
236237
FLUX_ROLE_ALL = 0xFFFFFFFF,
237238
};
238239
int flux_msg_set_rolemask (flux_msg_t *msg, uint32_t rolemask);
@@ -260,6 +261,11 @@ int flux_msg_cred_authorize (struct flux_msg_cred cred, uint32_t userid);
260261
*/
261262
int flux_msg_authorize (const flux_msg_t *msg, uint32_t userid);
262263

264+
/* Return true if 'msg' credential carries FLUX_ROLE_LOCAL, indicating
265+
* that the message has not traversed brokers.
266+
*/
267+
bool flux_msg_is_local (const flux_msg_t *msg);
268+
263269
/* Get/set errnum (response only)
264270
*/
265271
int flux_msg_set_errnum (flux_msg_t *msg, int errnum);

src/modules/connector-local/local.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ static int client_authenticate (struct connector_local *ctx,
9090
errno = EPERM;
9191
goto error;
9292
}
93+
/* Tack on FLUX_ROLE_LOCAL to indicate that this message was
94+
* accepted by the local connector. This role is cleared when
95+
* the message is received by another broker.
96+
*/
97+
rolemask |= FLUX_ROLE_LOCAL;
9398
/* Test hook: drop owner cred for one connection.
9499
*/
95100
if (flux_module_debug_test (ctx->h, DEBUG_OWNERDROP_ONESHOT, true)) {

t/t0017-security.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ test_expect_success 'simulated local connector auth failure returns EPERM' '
9595

9696
test_expect_success 'flux ping --userid displays userid' '
9797
flux ping --count=1 --userid broker >ping.out &&
98-
grep -q "userid=$(id -u) rolemask=0x1" ping.out
98+
grep -q "userid=$(id -u) rolemask=0x5" ping.out
9999
'
100100

101101
test_expect_success 'FLUX_HANDLE_USERID can spoof userid in message' '
102102
FLUX_HANDLE_USERID=9999 flux ping --count=1 --userid broker >ping2.out &&
103-
grep -q "userid=9999 rolemask=0x1" ping2.out
103+
grep -q "userid=9999 rolemask=0x5" ping2.out
104104
'
105105

106106
test_expect_success 'FLUX_HANDLE_ROLEMASK can spoof rolemask in message' '

0 commit comments

Comments
 (0)