diff options
-rw-r--r-- | cli/src/cli-cmd-parser.c | 10 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 2 | ||||
-rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 2 | ||||
-rwxr-xr-x | tests/bugs/bug-1085330.t | 80 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 44 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 2 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 3 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 13 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 19 |
10 files changed, 152 insertions, 24 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index e7f41fa7203..a41c0800ac1 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -236,8 +236,11 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options if (strchr (volname, '/')) goto out; - if (strlen (volname) > 512) + if (strlen (volname) > GD_VOLUME_NAME_MAX) { + cli_err("Volume name exceeds %d characters.", + GD_VOLUME_NAME_MAX); goto out; + } for (i = 0; i < strlen (volname); i++) if (!isalnum (volname[i]) && (volname[i] != '_') && @@ -561,8 +564,11 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options) if (strchr (volname, '/')) goto out; - if (strlen (volname) > 512) + if (strlen (volname) > GD_VOLUME_NAME_MAX) { + cli_err("Volname can not exceed %d characters.", + GD_VOLUME_NAME_MAX); goto out; + } for (i = 0; i < strlen (volname); i++) if (!isalnum (volname[i]) && (volname[i] != '_') && diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 83b923e360a..6072fcc5193 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -65,7 +65,7 @@ cli_cmd_volume_info_cbk (struct cli_state *state, struct cli_cmd_word *word, } else if (wordcount == 3) { ctx.flags = GF_CLI_GET_VOLUME; ctx.volname = (char *)words[2]; - if (strlen (ctx.volname) > 1024) { + if (strlen (ctx.volname) > GD_VOLUME_NAME_MAX) { cli_out ("Invalid volume name"); goto out; } diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index 634fff8f760..02e0d244a4f 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -292,4 +292,6 @@ typedef struct gf_gsync_detailed_status_ gf_gsync_status_t; #define GD_MGMT_HNDSK_PROGRAM 1239873 /* Completely random */ #define GD_MGMT_HNDSK_VERSION 1 +#define GD_VOLUME_NAME_MAX 256 /* Maximum size of volume name */ + #endif /* !_PROTOCOL_COMMON_H */ diff --git a/tests/bugs/bug-1085330.t b/tests/bugs/bug-1085330.t new file mode 100755 index 00000000000..dafba215540 --- /dev/null +++ b/tests/bugs/bug-1085330.t @@ -0,0 +1,80 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +STR="1234567890" +volname="Vol" + +cleanup; +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + + +# Construct volname string such that its more than 256 characters +for i in {1..30} +do + volname+=$STR +done +# Now $volname is more than 256 chars + +TEST ! $CLI volume create $volname $H0:$B0/${volname}{1,2}; + +TEST $CLI volume info; + +# Construct brick string such that its more than 256 characters +volname="Vol1234" +brick="brick" +for i in {1..30} +do + brick+=$STR +done +# Now $brick1 is more than 256 chars + +TEST ! $CLI volume create $volname $H0:$B0/$brick; + +TEST $CLI volume info; + +# Now try to create a volume with couple of bricks (strlen(volname) = 128 & +# strlen(brick1) = 128 +# Command should still fail as strlen(volp path) > 256 + +volname="Volume-0" +brick="brick-00" +STR="12345678" + +for i in {1..15} +do + volname+=$STR + brick+=$STR +done +TEST ! $CLI volume create $volname $H0:$B0/$brick; + +TEST $CLI volume info; + +# test case with brick path as 255 and a trailing "/" +brick="" +STR1="12345678" +volname="vol" + +for i in {1..31} +do + brick+=$STR1 +done +brick+="123456/" + +echo $brick | wc -c +# Now $brick is exactly 255 chars, but at end a trailing space +# This will still fail as volfpath exceeds more than _POSIX_MAX chars + +TEST ! $CLI volume create $volname $H0:$B0/$brick; + +TEST $CLI volume info; + +# Positive test case +TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2}; + +TEST $CLI volume info; + +cleanup; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index cb673192d0c..229ee469598 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -31,7 +31,6 @@ #include "glusterd.h" #include "protocol-common.h" -#define GD_VOLUME_NAME_MAX 256 #define GD_OP_PROTECTED (0x02) #define GD_OP_UNPROTECTED (0x04) diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c index 0404e110cb5..26de774e3f5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.c +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -134,12 +134,16 @@ glusterd_store_brickinfopath_set (glusterd_volinfo_t *volinfo, gf_boolean_t glusterd_store_is_valid_brickpath (char *volname, char *brick) { - char brickpath[PATH_MAX] = {0}; glusterd_brickinfo_t *brickinfo = NULL; glusterd_volinfo_t *volinfo = NULL; int32_t ret = 0; size_t volname_len = strlen (volname); xlator_t *this = NULL; + int bpath_len = 0; + const char delim[2] = "/"; + char *sub_dir = NULL; + char *saveptr = NULL; + char *brickpath_ptr = NULL; this = THIS; GF_ASSERT (this); @@ -163,10 +167,40 @@ glusterd_store_is_valid_brickpath (char *volname, char *brick) goto out; } memcpy (volinfo->volname, volname, volname_len+1); - glusterd_store_brickinfopath_set (volinfo, brickinfo, brickpath, - sizeof (brickpath)); - ret = (strlen (brickpath) < _POSIX_PATH_MAX); + /* Check whether brickpath is less than PATH_MAX */ + ret = 1; + bpath_len = strlen (brickinfo->path); + + if (brickinfo->path[bpath_len - 1] != '/') { + if (strlen (brickinfo->path) >= PATH_MAX) { + ret = 0; + goto out; + } + } else { + /* Path has a trailing "/" which should not be considered in + * length check validation + */ + if (strlen (brickinfo->path) >= PATH_MAX + 1) { + ret = 0; + goto out; + } + } + + /* The following validation checks whether each sub directories in the + * brick path meets the POSIX max length validation + */ + + brickpath_ptr = brickinfo->path; + sub_dir = strtok_r (brickpath_ptr, delim, &saveptr); + + while (sub_dir != NULL) { + if (strlen(sub_dir) >= _POSIX_PATH_MAX) { + ret = 0; + goto out; + } + sub_dir = strtok_r (NULL, delim, &saveptr); + } out: if (brickinfo) @@ -2564,7 +2598,7 @@ glusterd_store_retrieve_volume (char *volname, glusterd_snap_t *snap) if (ret) goto out; - strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); + strncpy (volinfo->volname, volname, GD_VOLUME_NAME_MAX); volinfo->snapshot = snap; if (snap) volinfo->is_snap_volume = _gf_true; diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index b7f81bf83e5..7fd7eaeec5c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -511,7 +511,7 @@ glusterd_volinfo_new (glusterd_volinfo_t **volinfo) goto out; } - snprintf (new_volinfo->parent_volname, GLUSTERD_MAX_VOLUME_NAME, "N/A"); + snprintf (new_volinfo->parent_volname, GD_VOLUME_NAME_MAX, "N/A"); new_volinfo->snap_max_hard_limit = GLUSTERD_SNAPS_MAX_HARD_LIMIT; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 82ff8826843..a8aa577be80 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3479,7 +3479,8 @@ glusterd_is_valid_volfpath (char *volname, char *brick) strncpy (volinfo->volname, volname, sizeof (volinfo->volname)); get_brick_filepath (volfpath, volinfo, brickinfo); - ret = (strlen (volfpath) < _POSIX_PATH_MAX); + ret = ((strlen(volfpath) < PATH_MAX) && + strlen (strrchr(volfpath, '/')) < _POSIX_PATH_MAX); out: if (brickinfo) diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index 083c7a036ad..8d126c5cc1a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -800,14 +800,21 @@ glusterd_op_stage_create_volume (dict_t *dict, char **op_errstr) brick= strtok_r (brick_list, " \n", &tmpptr); brick_list = tmpptr; - if (!glusterd_store_is_valid_brickpath (volname, brick) || - !glusterd_is_valid_volfpath (volname, brick)) { + if (!glusterd_store_is_valid_brickpath (volname, brick)) { snprintf (msg, sizeof (msg), "brick path %s is too " "long.", brick); ret = -1; goto out; } + if (!glusterd_is_valid_volfpath (volname, brick)) { + snprintf (msg, sizeof (msg), "Volume file path for " + "volume %s and brick path %s is too long.", + volname, brick); + ret = -1; + goto out; + } + ret = glusterd_brickinfo_new_from_brick (brick, &brick_info); if (ret) goto out; @@ -1522,7 +1529,7 @@ glusterd_op_create_volume (dict_t *dict, char **op_errstr) goto out; } - strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); + strncpy (volinfo->volname, volname, sizeof(volinfo->volname)); GF_ASSERT (volinfo->volname); ret = dict_get_int32 (dict, "type", &volinfo->type); diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index b7c0aeafb1e..2f63d07aac4 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -39,7 +39,6 @@ #include "syncop.h" #include "store.h" -#define GLUSTERD_MAX_VOLUME_NAME 1000 #define GLUSTERD_TR_LOG_SIZE 50 #define GLUSTERD_NAME "glusterd" #define GLUSTERD_SOCKET_LISTEN_BACKLOG 128 @@ -297,17 +296,17 @@ typedef struct glusterd_replace_brick_ glusterd_replace_brick_t; struct glusterd_volinfo_ { gf_lock_t lock; - char volname[GLUSTERD_MAX_VOLUME_NAME]; gf_boolean_t is_snap_volume; glusterd_snap_t *snapshot; uuid_t restored_from_snap; - char parent_volname[GLUSTERD_MAX_VOLUME_NAME]; + char parent_volname[GD_VOLUME_NAME_MAX]; /* In case of a snap volume i.e (is_snap_volume == TRUE) this field will contain the name of the volume which is snapped. In case of a non-snap volume, this field will be initialized as N/A */ + char volname[GD_VOLUME_NAME_MAX]; int type; int brick_count; uint64_t snap_count; @@ -521,13 +520,13 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); snprintf (abspath, sizeof (abspath)-1, \ DEFAULT_VAR_RUN_DIRECTORY"/%s%s", volname, path); -#define GLUSTERD_REMOVE_SLASH_FROM_PATH(path,string) do { \ - int i = 0; \ - for (i = 1; i < strlen (path); i++) { \ - string[i-1] = path[i]; \ - if (string[i-1] == '/') \ - string[i-1] = '-'; \ - } \ +#define GLUSTERD_REMOVE_SLASH_FROM_PATH(path,string) do { \ + int i = 0; \ + for (i = 1; i < strlen (path); i++) { \ + string[i-1] = path[i]; \ + if (string[i-1] == '/' && (i != strlen(path) - 1)) \ + string[i-1] = '-'; \ + } \ } while (0) #define GLUSTERD_GET_BRICK_PIDFILE(pidfile,volinfo,brickinfo, priv) do { \ |