diff options
| author | Ashish Pandey <aspandey@redhat.com> | 2019-07-11 16:52:49 +0530 | 
|---|---|---|
| committer | Pranith Kumar K <pkarampu@redhat.com> | 2020-02-25 12:34:17 +0530 | 
| commit | 64c9628da16cf0722d809e6c9adb7bc8d6fd7f1e (patch) | |
| tree | 592ff2abf33eb2534af9973f42b533dfb186ba28 | |
| parent | 9013328774c87d8a32ff80e78f6478e22c5157b9 (diff) | |
cluster/ec: Change handling of heal failure to avoid crash
Problem:
ec_getxattr_heal_cbk was called with NULL as second argument
in case heal was failing.
This function was dereferencing "cookie" argument which caused crash.
Solution:
Cookie is changed to carry the value that was supposed to be
stored in fop->data, so even in the case when fop is NULL in error
case, there won't be any NULL dereference.
Thanks to Xavi for the suggestion about the fix.
Change-Id: I0798000d5cadb17c3c2fbfa1baf77033ffc2bb8c
fixes: bz#1805057
| -rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 23 | ||||
| -rw-r--r-- | xlators/cluster/ec/src/ec-inode-read.c | 3 | 
2 files changed, 13 insertions, 13 deletions
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index 201f9c9c611..0c8c963c944 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -1909,7 +1909,7 @@ ec_manager_heal_block(ec_fop_data_t *fop, int32_t state)          case EC_STATE_REPORT:              if (fop->cbks.heal) { -                fop->cbks.heal(fop->req_frame, fop, fop->xl, 0, 0, +                fop->cbks.heal(fop->req_frame, fop->data, fop->xl, 0, 0,                                 (heal->good | heal->bad), heal->good, heal->bad,                                 NULL);              } @@ -1917,8 +1917,8 @@ ec_manager_heal_block(ec_fop_data_t *fop, int32_t state)              return EC_STATE_END;          case -EC_STATE_REPORT:              if (fop->cbks.heal) { -                fop->cbks.heal(fop->req_frame, fop, fop->xl, -1, fop->error, 0, -                               0, 0, NULL); +                fop->cbks.heal(fop->req_frame, fop->data, fop->xl, -1, +                               fop->error, 0, 0, 0, NULL);              }              return EC_STATE_END; @@ -1955,7 +1955,7 @@ out:      if (fop != NULL) {          ec_manager(fop, error);      } else { -        func(frame, NULL, this, -1, error, 0, 0, 0, NULL); +        func(frame, heal, this, -1, error, 0, 0, 0, NULL);      }  } @@ -1964,10 +1964,11 @@ ec_heal_block_done(call_frame_t *frame, void *cookie, xlator_t *this,                     int32_t op_ret, int32_t op_errno, uintptr_t mask,                     uintptr_t good, uintptr_t bad, dict_t *xdata)  { -    ec_fop_data_t *fop = cookie; -    ec_heal_t *heal = fop->data; +    ec_heal_t *heal = cookie; -    fop->heal = NULL; +    if (heal->fop) { +        heal->fop->heal = NULL; +    }      heal->fop = NULL;      heal->error = op_ret < 0 ? op_errno : 0;      syncbarrier_wake(heal->data); @@ -2541,7 +2542,7 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)  out:      if (fop->cbks.heal) { -        fop->cbks.heal(fop->req_frame, fop, fop->xl, op_ret, op_errno, +        fop->cbks.heal(fop->req_frame, fop->data, fop->xl, op_ret, op_errno,                         ec_char_array_to_mask(participants, ec->nodes),                         mgood & good, mbad & bad, NULL);      } @@ -2593,8 +2594,8 @@ void  ec_heal_fail(ec_t *ec, ec_fop_data_t *fop)  {      if (fop->cbks.heal) { -        fop->cbks.heal(fop->req_frame, NULL, ec->xl, -1, fop->error, 0, 0, 0, -                       NULL); +        fop->cbks.heal(fop->req_frame, fop->data, ec->xl, -1, fop->error, 0, 0, +                       0, NULL);      }      ec_fop_data_release(fop);  } @@ -2729,7 +2730,7 @@ fail:      if (fop)          ec_fop_data_release(fop);      if (func) -        func(frame, NULL, this, -1, err, 0, 0, 0, NULL); +        func(frame, data, this, -1, err, 0, 0, 0, NULL);  }  int diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index d13955e4497..db368a6fe5b 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -395,8 +395,7 @@ ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,                       int32_t op_ret, int32_t op_errno, uintptr_t mask,                       uintptr_t good, uintptr_t bad, dict_t *xdata)  { -    ec_fop_data_t *fop = cookie; -    fop_getxattr_cbk_t func = fop->data; +    fop_getxattr_cbk_t func = cookie;      ec_t *ec = xl->private;      dict_t *dict = NULL;      char *str;  | 
