Spaces:
Running
Running
rpc: fix known RCE in rpc-server (ggml/1103)
Browse filesAdd bounds checking in `rpc_server::copy_tensor` to prevent out-of-bounds writes
+ Check if `(uint8_t *)dst->data + ggml_nbytes(src)` remains within the destination buffer’s allocated region.
ggml/src/ggml-rpc/ggml-rpc.cpp
CHANGED
|
@@ -1045,7 +1045,28 @@ bool rpc_server::copy_tensor(const rpc_msg_copy_tensor_req & request, rpc_msg_co
|
|
| 1045 |
ggml_free(ctx);
|
| 1046 |
return false;
|
| 1047 |
}
|
| 1048 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1049 |
response.result = ggml_backend_buffer_copy_tensor(src, dst);
|
| 1050 |
ggml_free(ctx);
|
| 1051 |
return true;
|
|
|
|
| 1045 |
ggml_free(ctx);
|
| 1046 |
return false;
|
| 1047 |
}
|
| 1048 |
+
|
| 1049 |
+
uint64_t src_size = (uint64_t) ggml_nbytes(src);
|
| 1050 |
+
uint64_t dst_data = (uint64_t) dst->data;
|
| 1051 |
+
uint64_t dst_base = (uint64_t) ggml_backend_buffer_get_base(dst->buffer);
|
| 1052 |
+
uint64_t dst_buf_sz = (uint64_t) ggml_backend_buffer_get_size(dst->buffer);
|
| 1053 |
+
|
| 1054 |
+
if (dst_data + src_size > dst_base + dst_buf_sz) {
|
| 1055 |
+
GGML_PRINT_DEBUG("[%s] out-of-bounds write in rpc_server::copy_tensor:\n"
|
| 1056 |
+
" write range : [0x%" PRIx64 ", 0x%" PRIx64 "]\n"
|
| 1057 |
+
" buffer base: [0x%" PRIx64 ", 0x%" PRIx64 "]\n",
|
| 1058 |
+
__func__,
|
| 1059 |
+
dst_data,
|
| 1060 |
+
dst_data + src_size,
|
| 1061 |
+
dst_base,
|
| 1062 |
+
dst_base + dst_buf_sz);
|
| 1063 |
+
ggml_free(ctx);
|
| 1064 |
+
return false;
|
| 1065 |
+
}
|
| 1066 |
+
|
| 1067 |
+
GGML_PRINT_DEBUG("[%s] src->buffer: %p, dst->buffer: %p\n",
|
| 1068 |
+
__func__, (void*) src->buffer, (void*) dst->buffer);
|
| 1069 |
+
|
| 1070 |
response.result = ggml_backend_buffer_copy_tensor(src, dst);
|
| 1071 |
ggml_free(ctx);
|
| 1072 |
return true;
|