diff options
| author | Susant Palai <spalai@redhat.com> | 2018-11-21 11:45:23 +0530 | 
|---|---|---|
| committer | Raghavendra G <rgowdapp@redhat.com> | 2018-11-23 04:53:58 +0000 | 
| commit | c0983c3532e2da04c8c8f63df2717c154e0724db (patch) | |
| tree | 8e3f6b24e057be73df355dad2f53fd9cf0f41a6b /xlators | |
| parent | da81c9938ec77401738999cf52ebf2fef695ba4d (diff) | |
dht: fix buffer overflow
CID: 1382461
Change-Id: I25b5edf7fd5fdaa52079d0348ebb7f5de9f11503
updates: bz#789278
Signed-off-by: Susant Palai <spalai@redhat.com>
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 41 | 
1 files changed, 35 insertions, 6 deletions
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index 2e7c7b39a5f..af342bdbe21 100644 --- a/xlators/cluster/dht/src/dht-rename.c +++ b/xlators/cluster/dht/src/dht-rename.c @@ -472,13 +472,14 @@ err:   * dirs are the same.   *   */ -static void +static int  dht_order_rename_lock(call_frame_t *frame, loc_t **loc, xlator_t **subvol)  {      int ret = 0; +    int op_ret = 0;      dht_local_t *local = NULL; -    char src[GF_UUID_BNAME_BUF_SIZE] = {0}; -    char dst[GF_UUID_BNAME_BUF_SIZE] = {0}; +    char *src = NULL; +    char *dst = NULL;      local = frame->local; @@ -491,6 +492,15 @@ dht_order_rename_lock(call_frame_t *frame, loc_t **loc, xlator_t **subvol)      if (ret == 0) {          /* hashed subvols are the same for src and dst */          /* Entrylks need to be ordered*/ + +        src = alloca(GF_UUID_BNAME_BUF_SIZE + strlen(local->loc.name) + 1); +        if (!src) { +            gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, 0, +                   "Insufficient memory for src"); +            op_ret = -1; +            goto out; +        } +          if (!gf_uuid_is_null(local->loc.pargfid))              uuid_utoa_r(local->loc.pargfid, src);          else if (local->loc.parent) @@ -498,6 +508,14 @@ dht_order_rename_lock(call_frame_t *frame, loc_t **loc, xlator_t **subvol)          strcat(src, local->loc.name); +        dst = alloca(GF_UUID_BNAME_BUF_SIZE + strlen(local->loc2.name) + 1); +        if (!dst) { +            gf_msg(frame->this->name, GF_LOG_ERROR, ENOMEM, 0, +                   "Insufficient memory for dst"); +            op_ret = -1; +            goto out; +        } +          if (!gf_uuid_is_null(local->loc2.pargfid))              uuid_utoa_r(local->loc2.pargfid, dst);          else if (local->loc2.parent) @@ -520,7 +538,10 @@ dht_order_rename_lock(call_frame_t *frame, loc_t **loc, xlator_t **subvol)          *subvol = local->dst_hashed;      } -    return; +    op_ret = 0; + +out: +    return op_ret;  }  int @@ -561,7 +582,11 @@ dht_rename_dir(call_frame_t *frame, xlator_t *this)       * deadlocks when rename (src, dst) and rename (dst, src) is done from       * two different clients       */ -    dht_order_rename_lock(frame, &loc, &subvol); +    ret = dht_order_rename_lock(frame, &loc, &subvol); +    if (ret) { +        op_errno = ENOMEM; +        goto err; +    }      /* Rename must take locks on src to avoid lookup selfheal from       * recreating src on those subvols where the rename was successful. @@ -1604,7 +1629,11 @@ dht_rename_file_protect_namespace(call_frame_t *frame, void *cookie,       * deadlocks when rename (src, dst) and rename (dst, src) is done from       * two different clients       */ -    dht_order_rename_lock(frame, &loc, &subvol); +    ret = dht_order_rename_lock(frame, &loc, &subvol); +    if (ret) { +        local->op_errno = ENOMEM; +        goto err; +    }      ret = dht_protect_namespace(frame, loc, subvol, &local->current->ns,                                  dht_rename_file_lock1_cbk);  | 
