uint32_t len, const char *data,
Error **errp)
{
+ ERRP_GUARD();
NBDOption req;
QEMU_BUILD_BUG_ON(sizeof(req) != 16);
static int nbd_handle_reply_err(QIOChannel *ioc, NBDOptionReply *reply,
bool strict, Error **errp)
{
+ ERRP_GUARD();
g_autofree char *msg = NULL;
if (!(reply->type & (1 << 31))) {
return -1;
}
len -= sizeof(namelen);
- if (len < namelen) {
- error_setg(errp, "incorrect option name length");
+ if (len < namelen || namelen > NBD_MAX_STRING_SIZE) {
+ error_setg(errp, "incorrect name length in server's list response");
nbd_send_opt_abort(ioc);
return -1;
}
local_name[namelen] = '\0';
len -= namelen;
if (len) {
+ if (len > NBD_MAX_STRING_SIZE) {
+ error_setg(errp, "incorrect description length in server's "
+ "list response");
+ nbd_send_opt_abort(ioc);
+ return -1;
+ }
local_desc = g_malloc(len + 1);
if (nbd_read(ioc, local_desc, len, "export description", errp) < 0) {
nbd_send_opt_abort(ioc);
static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt,
NBDExportInfo *info, Error **errp)
{
+ ERRP_GUARD();
NBDOptionReply reply;
uint32_t len = strlen(info->name);
uint16_t type;
break;
default:
+ /*
+ * Not worth the bother to check if NBD_INFO_NAME or
+ * NBD_INFO_DESCRIPTION exceed NBD_MAX_STRING_SIZE.
+ */
trace_nbd_opt_info_unknown(type, nbd_info_lookup(type));
if (nbd_drop(ioc, len, errp) < 0) {
error_prepend(errp, "Failed to read info payload: ");
char *p;
data_len = sizeof(export_len) + export_len + sizeof(queries);
+ assert(export_len <= NBD_MAX_STRING_SIZE);
if (query) {
query_len = strlen(query);
data_len += sizeof(query_len) + query_len;
+ assert(query_len <= NBD_MAX_STRING_SIZE);
} else {
assert(opt == NBD_OPT_LIST_META_CONTEXT);
}
bool structured_reply, bool *zeroes,
Error **errp)
{
+ ERRP_GUARD();
uint64_t magic;
trace_nbd_start_negotiate(tlscreds, hostname ? hostname : "<null>");
const char *hostname, QIOChannel **outioc,
NBDExportInfo *info, Error **errp)
{
+ ERRP_GUARD();
int result;
bool zeroes;
bool base_allocation = info->base_allocation;
- assert(info->name);
+ assert(info->name && strlen(info->name) <= NBD_MAX_STRING_SIZE);
trace_nbd_receive_negotiate_name(info->name);
result = nbd_start_negotiate(aio_context, ioc, tlscreds, hostname, outioc,
len = qio_channel_readv(ioc, &iov, 1, errp);
if (len == QIO_CHANNEL_ERR_BLOCK) {
- bdrv_dec_in_flight(bs);
qio_channel_yield(ioc, G_IO_IN);
- bdrv_inc_in_flight(bs);
continue;
} else if (len < 0) {
return -EIO;