ggerganov slaren commited on
Commit
87d58fe
·
unverified ·
1 Parent(s): 94baae9

rpc : sanitize tensor data + warnings (llama/0)

Browse files

Co-authored-by: slaren <[email protected]>

Files changed (2) hide show
  1. ggml/src/ggml-rpc.cpp +35 -1
  2. ggml/src/ggml.c +2 -1
ggml/src/ggml-rpc.cpp CHANGED
@@ -197,6 +197,10 @@ static std::shared_ptr<socket_t> create_server_socket(const char * host, int por
197
  fprintf(stderr, "Failed to set SO_REUSEADDR\n");
198
  return nullptr;
199
  }
 
 
 
 
200
  struct sockaddr_in serv_addr;
201
  serv_addr.sin_family = AF_INET;
202
  serv_addr.sin_addr.s_addr = inet_addr(host);
@@ -879,6 +883,14 @@ ggml_tensor * rpc_server::deserialize_tensor(struct ggml_context * ctx, const rp
879
  if (result->buffer && buffers.find(result->buffer) == buffers.end()) {
880
  return nullptr;
881
  }
 
 
 
 
 
 
 
 
882
  result->op = (ggml_op) tensor->op;
883
  for (uint32_t i = 0; i < GGML_MAX_OP_PARAMS / sizeof(int32_t); i++) {
884
  result->op_params[i] = tensor->op_params[i];
@@ -898,7 +910,7 @@ bool rpc_server::set_tensor(const std::vector<uint8_t> & input) {
898
  const rpc_tensor * in_tensor = (const rpc_tensor *)input.data();
899
  uint64_t offset;
900
  memcpy(&offset, input.data() + sizeof(rpc_tensor), sizeof(offset));
901
- size_t size = input.size() - sizeof(rpc_tensor) - sizeof(offset);
902
 
903
  struct ggml_init_params params {
904
  /*.mem_size =*/ ggml_tensor_overhead(),
@@ -913,6 +925,17 @@ bool rpc_server::set_tensor(const std::vector<uint8_t> & input) {
913
  return false;
914
  }
915
  GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %zu\n", __func__, (void*)tensor->buffer, tensor->data, offset, size);
 
 
 
 
 
 
 
 
 
 
 
916
  const void * data = input.data() + sizeof(rpc_tensor) + sizeof(offset);
917
  ggml_backend_tensor_set(tensor, data, offset, size);
918
  ggml_free(ctx);
@@ -943,6 +966,17 @@ bool rpc_server::get_tensor(const std::vector<uint8_t> & input, std::vector<uint
943
  return false;
944
  }
945
  GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %" PRIu64 "\n", __func__, (void*)tensor->buffer, tensor->data, offset, size);
 
 
 
 
 
 
 
 
 
 
 
946
  // output serialization format: | data (size bytes) |
947
  output.resize(size, 0);
948
  ggml_backend_tensor_get(tensor, output.data(), offset, size);
 
197
  fprintf(stderr, "Failed to set SO_REUSEADDR\n");
198
  return nullptr;
199
  }
200
+ if (inet_addr(host) == INADDR_NONE) {
201
+ fprintf(stderr, "Invalid host address: %s\n", host);
202
+ return nullptr;
203
+ }
204
  struct sockaddr_in serv_addr;
205
  serv_addr.sin_family = AF_INET;
206
  serv_addr.sin_addr.s_addr = inet_addr(host);
 
883
  if (result->buffer && buffers.find(result->buffer) == buffers.end()) {
884
  return nullptr;
885
  }
886
+
887
+ // require that the tensor data does not go beyond the buffer end
888
+ uint64_t tensor_size = (uint64_t) ggml_nbytes(result);
889
+ uint64_t buffer_start = (uint64_t) ggml_backend_buffer_get_base(result->buffer);
890
+ uint64_t buffer_size = (uint64_t) ggml_backend_buffer_get_size(result->buffer);
891
+ GGML_ASSERT(tensor->data + tensor_size >= tensor->data); // check for overflow
892
+ GGML_ASSERT(tensor->data >= buffer_start && tensor->data + tensor_size <= buffer_start + buffer_size);
893
+
894
  result->op = (ggml_op) tensor->op;
895
  for (uint32_t i = 0; i < GGML_MAX_OP_PARAMS / sizeof(int32_t); i++) {
896
  result->op_params[i] = tensor->op_params[i];
 
910
  const rpc_tensor * in_tensor = (const rpc_tensor *)input.data();
911
  uint64_t offset;
912
  memcpy(&offset, input.data() + sizeof(rpc_tensor), sizeof(offset));
913
+ const size_t size = input.size() - sizeof(rpc_tensor) - sizeof(offset);
914
 
915
  struct ggml_init_params params {
916
  /*.mem_size =*/ ggml_tensor_overhead(),
 
925
  return false;
926
  }
927
  GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %zu\n", __func__, (void*)tensor->buffer, tensor->data, offset, size);
928
+
929
+ // sanitize tensor->data
930
+ {
931
+ const size_t p0 = (size_t) ggml_backend_buffer_get_base(tensor->buffer);
932
+ const size_t p1 = p0 + ggml_backend_buffer_get_size(tensor->buffer);
933
+
934
+ if (in_tensor->data + offset < p0 || in_tensor->data + offset >= p1 || size > (p1 - in_tensor->data - offset)) {
935
+ GGML_ABORT("[%s] tensor->data out of bounds\n", __func__);
936
+ }
937
+ }
938
+
939
  const void * data = input.data() + sizeof(rpc_tensor) + sizeof(offset);
940
  ggml_backend_tensor_set(tensor, data, offset, size);
941
  ggml_free(ctx);
 
966
  return false;
967
  }
968
  GGML_PRINT_DEBUG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %" PRIu64 "\n", __func__, (void*)tensor->buffer, tensor->data, offset, size);
969
+
970
+ // sanitize tensor->data
971
+ {
972
+ const size_t p0 = (size_t) ggml_backend_buffer_get_base(tensor->buffer);
973
+ const size_t p1 = p0 + ggml_backend_buffer_get_size(tensor->buffer);
974
+
975
+ if (in_tensor->data + offset < p0 || in_tensor->data + offset >= p1 || size > (p1 - in_tensor->data - offset)) {
976
+ GGML_ABORT("[%s] tensor->data out of bounds\n", __func__);
977
+ }
978
+ }
979
+
980
  // output serialization format: | data (size bytes) |
981
  output.resize(size, 0);
982
  ggml_backend_tensor_get(tensor, output.data(), offset, size);
ggml/src/ggml.c CHANGED
@@ -3724,7 +3724,8 @@ static struct ggml_tensor * ggml_new_tensor_impl(
3724
  struct ggml_tensor * view_src,
3725
  size_t view_offs) {
3726
 
3727
- assert(n_dims >= 1 && n_dims <= GGML_MAX_DIMS);
 
3728
 
3729
  // find the base tensor and absolute offset
3730
  if (view_src != NULL && view_src->view_src != NULL) {
 
3724
  struct ggml_tensor * view_src,
3725
  size_t view_offs) {
3726
 
3727
+ GGML_ASSERT(type >= 0 && type < GGML_TYPE_COUNT);
3728
+ GGML_ASSERT(n_dims >= 1 && n_dims <= GGML_MAX_DIMS);
3729
 
3730
  // find the base tensor and absolute offset
3731
  if (view_src != NULL && view_src->view_src != NULL) {