Uploaded image for project: 'Lustre'
  1. Lustre
  2. LU-8811

mdc_close() may return a freed request in *request

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Minor
    • Lustre 2.10.0
    • Lustre 2.9.0
    • 3
    • 9223372036854775807

    Description

      In mdc_close() if ptlrpc_request_pack() fails then a freed request is returned in *request.

      static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
                           struct md_open_data *mod, struct ptlrpc_request **request)
      {
      ...
              *request = NULL;
              if (OBD_FAIL_CHECK(OBD_FAIL_MDC_CLOSE))
                      req = NULL;
              else
                      req = ptlrpc_request_alloc(class_exp2cliimp(exp), req_fmt);
      ...
              rc = ptlrpc_request_pack(req, LUSTRE_MDS_VERSION, MDS_CLOSE);
              if (rc) {
                      ptlrpc_request_free(req);
                      GOTO(out, rc);
              }
      ...
      out:
              if (mod) {
                      if (rc != 0)
                              mod->mod_close_req = NULL;
                      /* Since now, mod is accessed through open_req only,       
                       * thus close req does not keep a reference on mod anymore. */
                      obd_mod_put(mod);
              }
              *request = req;
      
              RETURN(rc < 0 ? rc : saved_rc);
      }
      

      This will result in a use after free in ll_close_inode_openhandle() or ll_open_cleanup().

      This was introduced by

      commit 62713a8530349a75b7202c9bfc6be121409a0203
      Author: Alexander Boyko <alexander.boyko@seagate.com>
      Date:   Thu Dec 3 09:57:36 2015 +0300
      
          LU-5282 mdc: fix panic at mdc_free_open()
          
          Assertion was happened for open request when rq_replay is set
          to 1.
              ASSERTION(mod->mod_open_req->rq_replay == 0)
          But this situation is not fatal for client, and could happened
          when mdc_close() failed.
          The fix allow to free such requests. If mdc_close fail, MDS doesn`t
          receive close request from client. And in a worst case client would
          be evicted.
          
          The test recreates issue when mdc_close failed and
          client asserts:
             ASSERTION( mod->mod_open_req->rq_replay == 0 ) failed
          
          Signed-off-by: Alexander Boyko <alexander.boyko@seagate.com>
          Seagate-bug-id: MRP-3156
          Change-Id: I5f98901f633355849fc107149eadc9cf171819af
          Reviewed-on: http://review.whamcloud.com/17495
          Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
          Tested-by: Jenkins
          Tested-by: Maloo <hpdd-maloo@intel.com>
          Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
          Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
      

      Attachments

        Issue Links

          Activity

            People

              jhammond John Hammond
              jhammond John Hammond
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: