From 70aea00ecb39d097677d7852f3676abf088adb0d Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Tue, 16 Aug 2016 21:53:03 +0900 Subject: [PATCH] LU-8955 ptlrpc: manage SELinux policy info at connect time At connect time, compute SELinux policy info on client side, and send it over the wire. On server side, get SELinux policy info from nodemap and compare it with the one received from client. Lustre-change: https://review.whamcloud.com/24422 Lustre-commit: dd200e5530fd841999399f6dcafb5ded46ba3cf1 Signed-off-by: Sebastien Buisson Change-Id: I9b4a206455f2c0b451f6b3ed7e3a85285592758e Reviewed-by: Patrick Farrell Reviewed-by: Li Dongyang Reviewed-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/34641 Tested-by: Jenkins Tested-by: Maloo --- lustre/include/lustre_export.h | 5 +++ lustre/include/lustre_req_layout.h | 2 + lustre/include/uapi/linux/lustre/lustre_idl.h | 3 +- lustre/llite/llite_lib.c | 4 ++ lustre/ptlrpc/import.c | 16 +++++++- lustre/ptlrpc/layout.c | 59 ++++++++++++++++++++++++--- lustre/target/tgt_handler.c | 7 ++++ 7 files changed, 89 insertions(+), 7 deletions(-) diff --git a/lustre/include/lustre_export.h b/lustre/include/lustre_export.h index 58f2764..ac2fd9c 100644 --- a/lustre/include/lustre_export.h +++ b/lustre/include/lustre_export.h @@ -462,6 +462,11 @@ static inline int exp_connect_archive_id_array(struct obd_export *exp) return !!(exp_connect_flags2(exp) & OBD_CONNECT2_ARCHIVE_ID_ARRAY); } +static inline int exp_connect_sepol(struct obd_export *exp) +{ + return !!(exp_connect_flags2(exp) & OBD_CONNECT2_SELINUX_POLICY); +} + enum { /* archive_ids in array format */ KKUC_CT_DATA_ARRAY_MAGIC = 0x092013cea, diff --git a/lustre/include/lustre_req_layout.h b/lustre/include/lustre_req_layout.h index 8895f42..f11efa1 100644 --- a/lustre/include/lustre_req_layout.h +++ b/lustre/include/lustre_req_layout.h @@ -128,6 +128,7 @@ int req_capsule_server_grow(struct req_capsule *pill, __u32 newlen); int req_layout_init(void); void req_layout_fini(void); +int req_check_sepol(struct req_capsule *pill); extern struct req_format RQF_OBD_PING; extern struct req_format RQF_OBD_SET_INFO; @@ -289,6 +290,7 @@ extern struct req_msg_field RMF_HSM_USER_STATE; extern struct req_msg_field RMF_HSM_STATE_SET; extern struct req_msg_field RMF_MDS_HSM_CURRENT_ACTION; extern struct req_msg_field RMF_MDS_HSM_REQUEST; +extern struct req_msg_field RMF_SELINUX_POL; /* seq-mgr fields */ extern struct req_msg_field RMF_SEQ_OPC; diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index f7d9a01..600b9dd 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -888,7 +888,8 @@ struct ptlrpc_body_v2 { OBD_CONNECT2_SUM_STATFS | \ OBD_CONNECT2_LOCK_CONVERT | \ OBD_CONNECT2_DIR_MIGRATE | \ - OBD_CONNECT2_ARCHIVE_ID_ARRAY) + OBD_CONNECT2_ARCHIVE_ID_ARRAY | \ + OBD_CONNECT2_SELINUX_POLICY) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \ OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 34f1627..eefeca4 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -268,6 +268,10 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, obd_connect_set_secctx(data); +#if defined(CONFIG_SECURITY) + data->ocd_connect_flags2 |= OBD_CONNECT2_SELINUX_POLICY; +#endif + data->ocd_brw_size = MD_MAX_BRW_SIZE; err = obd_connect(NULL, &sbi->ll_md_exp, sbi->ll_md_obd, diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index c81ac75..a52dc13 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -658,7 +658,8 @@ int ptlrpc_connect_import(struct obd_import *imp) obd2cli_tgt(imp->imp_obd), obd->obd_uuid.uuid, (char *)&imp->imp_dlm_handle, - (char *)&imp->imp_connect_data }; + (char *)&imp->imp_connect_data, + NULL }; struct ptlrpc_connect_async_args *aa; int rc; ENTRY; @@ -720,6 +721,19 @@ int ptlrpc_connect_import(struct obd_import *imp) if (request == NULL) GOTO(out, rc = -ENOMEM); + /* get SELinux policy info if any */ + rc = sptlrpc_get_sepol(request); + if (rc < 0) { + ptlrpc_request_free(request); + GOTO(out, rc); + } + + bufs[5] = request->rq_sepol; + + req_capsule_set_size(&request->rq_pill, &RMF_SELINUX_POL, RCL_CLIENT, + strlen(request->rq_sepol) ? + strlen(request->rq_sepol) + 1 : 0); + rc = ptlrpc_request_bufs_pack(request, LUSTRE_OBD_VERSION, imp->imp_connect_op, bufs, NULL); if (rc) { diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 281ad9c..ece5b73 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -55,6 +55,7 @@ /* struct ptlrpc_request, lustre_msg* */ #include #include +#include /* * RQFs (see below) refer to two struct req_msg_field arrays describing the @@ -329,11 +330,12 @@ static const struct req_msg_field *mdt_swap_layouts[] = { }; static const struct req_msg_field *obd_connect_client[] = { - &RMF_PTLRPC_BODY, - &RMF_TGTUUID, - &RMF_CLUUID, - &RMF_CONN, - &RMF_CONNECT_DATA + &RMF_PTLRPC_BODY, + &RMF_TGTUUID, + &RMF_CLUUID, + &RMF_CONN, + &RMF_CONNECT_DATA, + &RMF_SELINUX_POL }; static const struct req_msg_field *obd_connect_server[] = { @@ -1099,6 +1101,10 @@ struct req_msg_field RMF_LAYOUT_INTENT = NULL); EXPORT_SYMBOL(RMF_LAYOUT_INTENT); +struct req_msg_field RMF_SELINUX_POL = + DEFINE_MSGF("selinux_pol", RMF_F_STRING, -1, NULL, NULL); +EXPORT_SYMBOL(RMF_SELINUX_POL); + /* * OST request field. */ @@ -2525,3 +2531,46 @@ int req_capsule_server_grow(struct req_capsule *pill, return 0; } EXPORT_SYMBOL(req_capsule_server_grow); + +int req_check_sepol(struct req_capsule *pill) +{ + int rc = 0; +#ifdef HAVE_SERVER_SUPPORT + struct obd_export *export; + struct lu_nodemap *nm = NULL; + const char *sepol = NULL; + const char *nm_sepol = NULL; + + if (!pill->rc_req) + return -EPROTO; + + export = pill->rc_req->rq_export; + if (!export || !exp_connect_sepol(export) || + !req_capsule_has_field(pill, &RMF_SELINUX_POL, RCL_CLIENT)) + goto nm; + + if (req_capsule_get_size(pill, &RMF_SELINUX_POL, RCL_CLIENT) == 0) + goto nm; + + sepol = req_capsule_client_get(pill, &RMF_SELINUX_POL); + CDEBUG(D_SEC, "retrieved sepol %s\n", sepol); + +nm: + if (export) { + nm = nodemap_get_from_exp(export); + if (!IS_ERR_OR_NULL(nm)) { + nm_sepol = nodemap_get_sepol(nm); + if (nm_sepol && nm_sepol[0]) + if (sepol == NULL || + strcmp(sepol, nm_sepol) != 0) + rc = -EACCES; + } + } + + if (!IS_ERR_OR_NULL(nm)) + nodemap_putref(nm); +#endif + + return rc; +} +EXPORT_SYMBOL(req_check_sepol); diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 4b4d74c..cc5352e 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -997,6 +997,13 @@ int tgt_connect(struct tgt_session_info *tsi) tsi->tsi_exp->exp_connect_data.ocd_brw_size = reply->ocd_brw_size; spin_unlock(&tsi->tsi_exp->exp_lock); + if (strcmp(tsi->tsi_exp->exp_obd->obd_type->typ_name, + LUSTRE_MDT_NAME) == 0) { + rc = req_check_sepol(tsi->tsi_pill); + if (rc) + GOTO(out, rc); + } + RETURN(0); out: obd_disconnect(class_export_get(tsi->tsi_exp)); -- 1.8.3.1