From 9563fe8a2de9db5eb087fe0e48ec335ee66f8f41 Mon Sep 17 00:00:00 2001 From: Dmitry Eremin Date: Wed, 4 Nov 2015 13:40:00 -0500 Subject: [PATCH] staging: lustre: fix buffer overflow of string buffer Buffer overflow of string buffer due to non null terminated string. Use strlcpy() when it's justifiable. Use sizeof(var) instead of constants. Signed-off-by: Dmitry Eremin Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4629 Reviewed-on: http://review.whamcloud.com/9389 Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lnet/klnds/socklnd/socklnd.c | 9 +++++---- drivers/staging/lustre/lnet/lnet/config.c | 14 ++++++++------ drivers/staging/lustre/lnet/selftest/conrpc.c | 4 ++-- drivers/staging/lustre/lnet/selftest/console.c | 6 ++++-- .../staging/lustre/lustre/include/lustre_disk.h | 1 + drivers/staging/lustre/lustre/libcfs/debug.c | 6 +++--- drivers/staging/lustre/lustre/libcfs/hash.c | 3 +-- drivers/staging/lustre/lustre/libcfs/workitem.c | 4 ++-- drivers/staging/lustre/lustre/llite/dir.c | 2 +- drivers/staging/lustre/lustre/lov/lov_pool.c | 3 +-- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 10 +++++++--- drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c | 1 + drivers/staging/lustre/lustre/ptlrpc/sec_config.c | 3 +-- 13 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index ecfe73302350..46a24b4ead09 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -2621,8 +2621,8 @@ ksocknal_enumerate_interfaces(ksock_net_t *net) net->ksnn_interfaces[j].ksni_ipaddr = ip; net->ksnn_interfaces[j].ksni_netmask = mask; - strncpy(&net->ksnn_interfaces[j].ksni_name[0], - names[i], IFNAMSIZ); + strlcpy(net->ksnn_interfaces[j].ksni_name, + names[i], sizeof(net->ksnn_interfaces[j].ksni_name)); j++; } @@ -2805,8 +2805,9 @@ ksocknal_startup(lnet_ni_t *ni) goto fail_1; } - strncpy(&net->ksnn_interfaces[i].ksni_name[0], - ni->ni_interfaces[i], IFNAMSIZ); + strlcpy(net->ksnn_interfaces[i].ksni_name, + ni->ni_interfaces[i], + sizeof(net->ksnn_interfaces[i].ksni_name)); } net->ksnn_ninterfaces = i; } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 4e8b54b86c7d..5390ee9963ab 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -650,8 +650,8 @@ lnet_parse_route(char *str, int *im_a_router) INIT_LIST_HEAD(&nets); /* save a copy of the string for error messages */ - strncpy(cmd, str, sizeof(cmd) - 1); - cmd[sizeof(cmd) - 1] = 0; + strncpy(cmd, str, sizeof(cmd)); + cmd[sizeof(cmd) - 1] = '\0'; sep = str; for (;;) { @@ -972,11 +972,13 @@ lnet_splitnets(char *source, struct list_head *nets) return 0; offset += (int)(sep - tb->ltb_text); - tb2 = lnet_new_text_buf(strlen(sep)); + len = strlen(sep); + tb2 = lnet_new_text_buf(len); if (tb2 == NULL) return -ENOMEM; - strcpy(tb2->ltb_text, sep); + strncpy(tb2->ltb_text, sep, len); + tb2->ltb_text[len] = '\0'; list_add_tail(&tb2->ltb_list, nets); tb = tb2; @@ -1021,8 +1023,8 @@ lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) tb = list_entry(raw_entries.next, struct lnet_text_buf_t, ltb_list); - strncpy(source, tb->ltb_text, sizeof(source)-1); - source[sizeof(source)-1] = 0; + strncpy(source, tb->ltb_text, sizeof(source)); + source[sizeof(source)-1] = '\0'; /* replace ltb_text with the network(s) add on match */ rc = lnet_match_network_tokens(tb->ltb_text, ipaddrs, nip); diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 64a0335934f3..1066c70434b1 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -612,8 +612,8 @@ lstcon_sesrpc_prep(lstcon_node_t *nd, int transop, msrq = &(*crpc)->crp_rpc->crpc_reqstmsg.msg_body.mksn_reqst; msrq->mksn_sid = console_session.ses_id; msrq->mksn_force = console_session.ses_force; - strncpy(msrq->mksn_name, console_session.ses_name, - strlen(console_session.ses_name)); + strlcpy(msrq->mksn_name, console_session.ses_name, + sizeof(msrq->mksn_name)); break; case LST_TRANS_SESEND: diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index 6862c9a15556..5619fc430e8d 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -1731,7 +1731,8 @@ lstcon_session_new(char *name, int key, unsigned feats, console_session.ses_feats_updated = 0; console_session.ses_timeout = (timeout <= 0) ? LST_CONSOLE_TIMEOUT : timeout; - strcpy(console_session.ses_name, name); + strlcpy(console_session.ses_name, name, + sizeof(console_session.ses_name)); rc = lstcon_batch_add(LST_DEFAULT_BATCH); if (rc != 0) @@ -1951,7 +1952,8 @@ lstcon_acceptor_handle(struct srpc_server_rpc *rpc) if (grp->grp_userland == 0) grp->grp_userland = 1; - strcpy(jrep->join_session, console_session.ses_name); + strlcpy(jrep->join_session, console_session.ses_name, + sizeof(jrep->join_session)); jrep->join_timeout = console_session.ses_timeout; jrep->join_status = 0; diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 5e1ac129a681..7c6933ffc9c1 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -68,6 +68,7 @@ everything as string options */ #define LMD_MAGIC 0xbdacbd03 +#define LMD_PARAMS_MAXLEN 4096 /* gleaned from the mount command - no persistent info here */ struct lustre_mount_data { diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 4272a7c959d7..e56785a48242 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -504,9 +504,9 @@ int libcfs_debug_init(unsigned long bufsize) } if (libcfs_debug_file_path != NULL) { - strncpy(libcfs_debug_file_path_arr, - libcfs_debug_file_path, PATH_MAX-1); - libcfs_debug_file_path_arr[PATH_MAX - 1] = '\0'; + strlcpy(libcfs_debug_file_path_arr, + libcfs_debug_file_path, + sizeof(libcfs_debug_file_path_arr)); } /* If libcfs_debug_mb is set to an invalid value or uninitialized diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c index f23a11ddc979..d285117af3ad 100644 --- a/drivers/staging/lustre/lustre/libcfs/hash.c +++ b/drivers/staging/lustre/lustre/libcfs/hash.c @@ -1037,8 +1037,7 @@ cfs_hash_create(char *name, unsigned cur_bits, unsigned max_bits, if (hs == NULL) return NULL; - strncpy(hs->hs_name, name, len); - hs->hs_name[len - 1] = '\0'; + strlcpy(hs->hs_name, name, len); hs->hs_flags = flags; atomic_set(&hs->hs_refcount, 1); diff --git a/drivers/staging/lustre/lustre/libcfs/workitem.c b/drivers/staging/lustre/lustre/libcfs/workitem.c index 268dd6851af4..6d988084dbb6 100644 --- a/drivers/staging/lustre/lustre/libcfs/workitem.c +++ b/drivers/staging/lustre/lustre/libcfs/workitem.c @@ -360,8 +360,8 @@ cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, if (sched == NULL) return -ENOMEM; - strncpy(sched->ws_name, name, CFS_WS_NAME_LEN); - sched->ws_name[CFS_WS_NAME_LEN - 1] = '\0'; + strlcpy(sched->ws_name, name, CFS_WS_NAME_LEN); + sched->ws_cptab = cptab; sched->ws_cpt = cpt; diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 5c9502b5b358..951259a98323 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -641,7 +641,7 @@ static int ll_send_mgc_param(struct obd_export *mgc, char *string) if (!msp) return -ENOMEM; - strncpy(msp->mgs_param, string, MGS_PARAM_MAXLEN); + strlcpy(msp->mgs_param, string, sizeof(msp->mgs_param)); rc = obd_set_info_async(NULL, mgc, sizeof(KEY_SET_INFO), KEY_SET_INFO, sizeof(struct mgs_send_param), msp, NULL); if (rc) diff --git a/drivers/staging/lustre/lustre/lov/lov_pool.c b/drivers/staging/lustre/lustre/lov/lov_pool.c index b03827ef6514..b43ce6cd64c2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pool.c +++ b/drivers/staging/lustre/lustre/lov/lov_pool.c @@ -412,8 +412,7 @@ int lov_pool_new(struct obd_device *obd, char *poolname) if (!new_pool) return -ENOMEM; - strncpy(new_pool->pool_name, poolname, LOV_MAXPOOLNAME); - new_pool->pool_name[LOV_MAXPOOLNAME] = '\0'; + strlcpy(new_pool->pool_name, poolname, sizeof(new_pool->pool_name)); new_pool->pool_lobd = obd; /* ref count init to 1 because when created a pool is always used * up to deletion diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 48003d5325e3..7617c57d16e0 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -892,7 +892,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) } lmd->lmd_magic = LMD_MAGIC; - lmd->lmd_params = kzalloc(4096, GFP_NOFS); + lmd->lmd_params = kzalloc(LMD_PARAMS_MAXLEN, GFP_NOFS); if (!lmd->lmd_params) return -ENOMEM; lmd->lmd_params[0] = '\0'; @@ -978,7 +978,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) goto invalid; clear++; } else if (strncmp(s1, "param=", 6) == 0) { - int length; + size_t length, params_length; char *tail = strchr(s1 + 6, ','); if (tail == NULL) @@ -986,8 +986,12 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) else length = tail - s1; length -= 6; + params_length = strlen(lmd->lmd_params); + if (params_length + length + 1 >= LMD_PARAMS_MAXLEN) + return -E2BIG; strncat(lmd->lmd_params, s1 + 6, length); - strcat(lmd->lmd_params, " "); + lmd->lmd_params[params_length + length] = '\0'; + strlcat(lmd->lmd_params, " ", LMD_PARAMS_MAXLEN); clear++; } else if (strncmp(s1, "osd=", 4) == 0) { rc = lmd_parse_string(&lmd->lmd_osd_type, s1 + 4); diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c index ce036a1ac466..ac87aa12bd7e 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c +++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c @@ -422,6 +422,7 @@ static int ptlrpcd(void *arg) complete(&pc->pc_starting); /* + * This mainloop strongly resembles ptlrpc_set_wait() except that our * set never completes. ptlrpcd_check() calls ptlrpc_check_set() when * there are requests in the set. New requests come in on the set's diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c index 7ff948fe1424..7a206705865b 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_config.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_config.c @@ -83,8 +83,7 @@ int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr) return 0; } - strncpy(buf, str, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; + strlcpy(buf, str, sizeof(buf)); bulk = strchr(buf, '-'); if (bulk) -- 2.20.1