Print this page
NEX-16554 alloca() in libscf causes an iSCSI application to crash
Reviewed by: Yuri Pankon <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libscf/common/lowlevel.c
          +++ new/usr/src/lib/libscf/common/lowlevel.c
↓ open down ↓ 30 lines elided ↑ open up ↑
  31   31   * This is the main implementation file for the low-level repository
  32   32   * interface.
  33   33   */
  34   34  
  35   35  #include "lowlevel_impl.h"
  36   36  
  37   37  #include "repcache_protocol.h"
  38   38  #include "scf_type.h"
  39   39  
  40   40  #include <assert.h>
  41      -#include <alloca.h>
  42   41  #include <door.h>
  43   42  #include <errno.h>
  44   43  #include <fcntl.h>
  45   44  #include <fnmatch.h>
  46   45  #include <libuutil.h>
  47   46  #include <poll.h>
  48   47  #include <pthread.h>
  49   48  #include <synch.h>
  50   49  #include <stddef.h>
  51   50  #include <stdio.h>
↓ open down ↓ 4023 lines elided ↑ open up ↑
4075 4074                  size = commit_process(cur, NULL);
4076 4075                  if (size == BAD_SIZE) {
4077 4076                          (void) pthread_mutex_unlock(&h->rh_lock);
4078 4077                          return (scf_set_error(SCF_ERROR_INTERNAL));
4079 4078                  }
4080 4079                  assert(TX_SIZE(size) == size);
4081 4080                  total += size;
4082 4081          }
4083 4082  
4084 4083          request_size = REP_PROTOCOL_TRANSACTION_COMMIT_SIZE(total);
4085      -        request = alloca(request_size);
4086      -        (void) memset(request, '\0', request_size);
     4084 +        request = calloc(1, request_size);
     4085 +        if (request == NULL) {
     4086 +                (void) pthread_mutex_unlock(&h->rh_lock);
     4087 +                return (scf_set_error(SCF_ERROR_NO_MEMORY));
     4088 +        }
     4089 +
4087 4090          request->rpr_request = REP_PROTOCOL_PROPERTYGRP_TX_COMMIT;
4088 4091          request->rpr_entityid = tran->tran_pg.rd_d.rd_entity;
4089 4092          request->rpr_size = request_size;
4090 4093          cmd = (uintptr_t)request->rpr_cmd;
4091 4094  
4092 4095          datael_finish_reset(&tran->tran_pg.rd_d);
4093 4096  
4094 4097          new_total = 0;
4095 4098          for (cur = uu_list_first(tran->tran_props); cur != NULL;
4096 4099              cur = uu_list_next(tran->tran_props, cur)) {
4097 4100                  size = commit_process(cur, (void *)cmd);
4098 4101                  if (size == BAD_SIZE) {
4099 4102                          (void) pthread_mutex_unlock(&h->rh_lock);
4100      -                        return (scf_set_error(SCF_ERROR_INTERNAL));
     4103 +                        r = (scf_set_error(SCF_ERROR_INTERNAL));
     4104 +                        goto out;
4101 4105                  }
4102 4106                  cmd += size;
4103 4107                  new_total += size;
4104 4108          }
4105 4109          assert(new_total == total);
4106 4110  
4107 4111          r = make_door_call(h, request, request_size,
4108 4112              &response, sizeof (response));
4109 4113  
4110 4114          if (r < 0) {
4111 4115                  (void) pthread_mutex_unlock(&h->rh_lock);
4112 4116                  DOOR_ERRORS_BLOCK(r);
4113 4117          }
4114 4118  
4115 4119          if (response.rpr_response != REP_PROTOCOL_SUCCESS &&
4116 4120              response.rpr_response != REP_PROTOCOL_FAIL_NOT_LATEST) {
4117 4121                  (void) pthread_mutex_unlock(&h->rh_lock);
4118      -                return (scf_set_error(proto_error(response.rpr_response)));
     4122 +                r = (scf_set_error(proto_error(response.rpr_response)));
     4123 +                goto out;
4119 4124          }
4120 4125  
4121 4126          tran->tran_state = TRAN_STATE_COMMITTED;
4122 4127          (void) pthread_mutex_unlock(&h->rh_lock);
4123      -        return (response.rpr_response == REP_PROTOCOL_SUCCESS);
     4128 +        r = (response.rpr_response == REP_PROTOCOL_SUCCESS);
     4129 +
     4130 +out:
     4131 +        free(request);
     4132 +        return (r);
4124 4133  }
4125 4134  
4126 4135  static void
4127 4136  transaction_reset(scf_transaction_t *tran)
4128 4137  {
4129 4138          assert(MUTEX_HELD(&tran->tran_pg.rd_d.rd_handle->rh_lock));
4130 4139  
4131 4140          tran->tran_state = TRAN_STATE_NEW;
4132 4141          datael_reset_locked(&tran->tran_pg.rd_d);
4133 4142  }
↓ open down ↓ 3362 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX