staging: lustre: fix buffer overflow of string buffer
authorDmitry Eremin <dmitry.eremin@intel.com>
Wed, 4 Nov 2015 18:40:00 +0000 (13:40 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Nov 2015 04:02:47 +0000 (20:02 -0800)
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 <dmitry.eremin@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4629
Reviewed-on: http://review.whamcloud.com/9389
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 files changed:
drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
drivers/staging/lustre/lnet/lnet/config.c
drivers/staging/lustre/lnet/selftest/conrpc.c
drivers/staging/lustre/lnet/selftest/console.c
drivers/staging/lustre/lustre/include/lustre_disk.h
drivers/staging/lustre/lustre/libcfs/debug.c
drivers/staging/lustre/lustre/libcfs/hash.c
drivers/staging/lustre/lustre/libcfs/workitem.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/lustre/lustre/lov/lov_pool.c
drivers/staging/lustre/lustre/obdclass/obd_mount.c
drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
drivers/staging/lustre/lustre/ptlrpc/sec_config.c

index ecfe7330235031468234c9d040b979067697e1d5..46a24b4ead097744f41547034edb0aedb682d0c6 100644 (file)
@@ -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;
        }
index 4e8b54b86c7d1de2d7ec8664d11d45573f9f5514..5390ee9963ab4e8b6637e8e381dc35837d2aa3df 100644 (file)
@@ -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);
index 64a0335934f3d25cf38313a83468a2f1b1fb618f..1066c70434b11af4c23556a78e3d7f7d2e346ba3 100644 (file)
@@ -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:
index 6862c9a15556e1bcd9e5851bee4bc0e899577e67..5619fc430e8d2cceea7f86ac3c8398561853bb3a 100644 (file)
@@ -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;
 
index 5e1ac129a681e28f4620e81abff337bb3ca70cce..7c6933ffc9c177db1ba5c452a0eda47680df5412 100644 (file)
@@ -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 {
index 4272a7c959d78216ebdc8bacb55e22b11cd2fb2b..e56785a482425e8119572c3f2031bc65da1e3d22 100644 (file)
@@ -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
index f23a11ddc9794bf36817164c263f1acb01e10f0f..d285117af3adaa21cd327b0889a53bf96b0e623a 100644 (file)
@@ -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);
index 268dd6851af4baa6a276efd3d263f1d9bdb17850..6d988084dbb658404f317532f0036b1d6e1d981e 100644 (file)
@@ -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;
 
index 5c9502b5b3582ab98633dd88c480b2030b2f795c..951259a98323351ff2c939bc43d011070e620c7b 100644 (file)
@@ -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)
index b03827ef65145bfddb7cf49801fc5b24f4176058..b43ce6cd64c2aaef4934a40aa6db2912d3ada5a5 100644 (file)
@@ -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
index 48003d5325e3206a833ab1f37bdcba0fb9b14b82..7617c57d16e0c459060ca3598e7ecdbc6342504b 100644 (file)
@@ -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);
index ce036a1ac4663fdea1e2b3d9145b0d30d60fd895..ac87aa12bd7e727bff03b8e3d8fabd1ea4544f69 100644 (file)
@@ -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
index 7ff948fe1424721e3f2dd8590efef8f7c3b7496e..7a206705865b76dc190ea54cf489713b3fd95041 100644 (file)
@@ -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)