From 87a6bd0766dab72423dbbcc86326ff9bfa6cf598 Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Mon, 30 Dec 2019 10:54:09 -0500 Subject: [PATCH] LU-12678 lnet: prepare to make lnet_lnd const. Preferred practice is for structs containing function pointers to be 'const'. Such structs are generally tempting attack vectors, and making them const allows linux to place them in read-only memory, thus reducing the attack surface. 'struct lnet_lnd' is mostly function pointers, but contains one writable field - a list_head. Rather than keeping registered lnds in a linked-list, we can place them in an array indexed by type - type numbers are at most 15 so this is not a burden. With these changes, no part of an lnet_lnd is ever modified. Test-Parameters: trivial Test-Parameters: testlist=sanity-lnet Signed-off-by: Mr NeilBrown Change-Id: I08c7df551109e05ca4a3cef866e8df737d1a1ad4 Reviewed-on: https://review.whamcloud.com/36830 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Serguei Smirnov Reviewed-by: Oleg Drokin --- lnet/include/lnet/lib-types.h | 6 ++---- lnet/include/uapi/linux/lnet/nidstr.h | 2 ++ lnet/lnet/api-ni.c | 29 +++++++++++++++-------------- lnet/lnet/lo.c | 4 ---- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index d17929d..703251e 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -49,6 +49,7 @@ #include #include +#include /* Max payload size */ #define LNET_MAX_PAYLOAD LNET_MTU @@ -248,9 +249,6 @@ struct lnet_ni; /* forward ref */ struct socket; struct lnet_lnd { - /* fields managed by portals */ - struct list_head lnd_list; /* stash in the LND table */ - /* fields initialized by the LND */ __u32 lnd_type; @@ -1112,7 +1110,7 @@ struct lnet { /* uniquely identifies this ni in this epoch */ __u64 ln_interface_cookie; /* registered LNDs */ - struct list_head ln_lnds; + struct lnet_lnd *ln_lnds[NUM_LNDS]; /* test protocol compatibility flags */ int ln_testprotocompat; diff --git a/lnet/include/uapi/linux/lnet/nidstr.h b/lnet/include/uapi/linux/lnet/nidstr.h index 6e3f4ca..c4a297f 100644 --- a/lnet/include/uapi/linux/lnet/nidstr.h +++ b/lnet/include/uapi/linux/lnet/nidstr.h @@ -60,6 +60,8 @@ enum { GNILND = 13, GNIIPLND = 14, PTL4LND = 15, + + NUM_LNDS }; struct list_head; diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index d6e5e3d..a593597 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -800,16 +800,14 @@ static void lnet_assert_wire_constants(void) static struct lnet_lnd *lnet_find_lnd_by_type(__u32 type) { struct lnet_lnd *lnd; - struct list_head *tmp; /* holding lnd mutex */ - list_for_each(tmp, &the_lnet.ln_lnds) { - lnd = list_entry(tmp, struct lnet_lnd, lnd_list); + if (type >= NUM_LNDS) + return NULL; + lnd = the_lnet.ln_lnds[type]; + LASSERT(!lnd || lnd->lnd_type == type); - if (lnd->lnd_type == type) - return lnd; - } - return NULL; + return lnd; } unsigned int @@ -827,7 +825,7 @@ lnet_register_lnd(struct lnet_lnd *lnd) LASSERT(libcfs_isknown_lnd(lnd->lnd_type)); LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == NULL); - list_add_tail(&lnd->lnd_list, &the_lnet.ln_lnds); + the_lnet.ln_lnds[lnd->lnd_type] = lnd; CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type)); @@ -842,7 +840,7 @@ lnet_unregister_lnd(struct lnet_lnd *lnd) LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd); - list_del(&lnd->lnd_list); + the_lnet.ln_lnds[lnd->lnd_type] = NULL; CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type)); mutex_unlock(&the_lnet.ln_lnd_mutex); @@ -2517,7 +2515,6 @@ int lnet_lib_init(void) } the_lnet.ln_refcount = 0; - INIT_LIST_HEAD(&the_lnet.ln_lnds); INIT_LIST_HEAD(&the_lnet.ln_net_zombie); INIT_LIST_HEAD(&the_lnet.ln_msg_resend); @@ -2543,14 +2540,18 @@ int lnet_lib_init(void) * * \pre lnet_lib_init() called with success. * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls. + * + * As this happens at module-unload, all lnds must already be unloaded, + * so they must already be unregistered. */ void lnet_lib_exit(void) { - LASSERT(the_lnet.ln_refcount == 0); + int i; - while (!list_empty(&the_lnet.ln_lnds)) - lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next, - struct lnet_lnd, lnd_list)); + LASSERT(the_lnet.ln_refcount == 0); + lnet_unregister_lnd(&the_lolnd); + for (i = 0; i < NUM_LNDS; i++) + LASSERT(!the_lnet.ln_lnds[i]); lnet_destroy_locks(); } diff --git a/lnet/lnet/lo.c b/lnet/lnet/lo.c index a11ecdd..4f0ec8b 100644 --- a/lnet/lnet/lo.c +++ b/lnet/lnet/lo.c @@ -104,10 +104,6 @@ lolnd_startup(struct lnet_ni *ni) } struct lnet_lnd the_lolnd = { - .lnd_list = { - .next = &the_lolnd.lnd_list, - .prev = &the_lolnd.lnd_list - }, .lnd_type = LOLND, .lnd_startup = lolnd_startup, .lnd_shutdown = lolnd_shutdown, -- 1.8.3.1