socket: limit memory allocation when reading from socket
the write limit of libnfs has been 1M since a long time. Restrict rtmax and wrmax to 1M and error out otherwise. Limit the PDU size when reading from socket to rule out malicious servers forcing us to allocate a lot of memory. Signed-off-by: Peter Lieven <pl@kamp.de>libnfs-4.0.0-vitalif
parent
dc70b92dc6
commit
82aec93f12
|
@ -74,6 +74,7 @@ struct rpc_queue {
|
|||
|
||||
#define HASHES 1024
|
||||
#define NFS_RA_TIMEOUT 5
|
||||
#define NFS_MAX_XFER_SIZE (1024 * 1024)
|
||||
|
||||
struct rpc_context {
|
||||
uint32_t magic;
|
||||
|
|
|
@ -62,8 +62,8 @@ struct rpc_context *rpc_init_context(void)
|
|||
|
||||
rpc->magic = RPC_CONTEXT_MAGIC;
|
||||
|
||||
/* Allow 1M of data (for writes) and some */
|
||||
rpc->encodebuflen = 1024 * 1024 + 4096;
|
||||
/* Allow NFS_MAX_XFER_SIZE of data (for writes) and some */
|
||||
rpc->encodebuflen = NFS_MAX_XFER_SIZE + 4096;
|
||||
rpc->encodebuf = malloc(rpc->encodebuflen);
|
||||
if (rpc->encodebuf == NULL) {
|
||||
free(rpc);
|
||||
|
|
16
lib/libnfs.c
16
lib/libnfs.c
|
@ -870,6 +870,22 @@ static void nfs_mount_10_cb(struct rpc_context *rpc, int status, void *command_d
|
|||
nfs->readmax = res->FSINFO3res_u.resok.rtmax;
|
||||
nfs->writemax = res->FSINFO3res_u.resok.wtmax;
|
||||
|
||||
if (nfs->readmax > NFS_MAX_XFER_SIZE) {
|
||||
rpc_set_error(rpc, "server max rsize of %lu is greater than libnfs supported %d bytes",
|
||||
nfs->readmax, NFS_MAX_XFER_SIZE);
|
||||
data->cb(-EINVAL, nfs, command_data, data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nfs->writemax > NFS_MAX_XFER_SIZE) {
|
||||
rpc_set_error(rpc, "server max wsize of %lu is greater than libnfs supported %d bytes",
|
||||
nfs->writemax, NFS_MAX_XFER_SIZE);
|
||||
data->cb(-EINVAL, nfs, command_data, data->private_data);
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&args, 0, sizeof(GETATTR3args));
|
||||
args.object = nfs->rootfh;
|
||||
|
||||
|
|
|
@ -269,6 +269,12 @@ static int rpc_read_from_socket(struct rpc_context *rpc)
|
|||
}
|
||||
|
||||
pdu_size = rpc_get_pdu_size(rpc->inbuf);
|
||||
|
||||
if (pdu_size > NFS_MAX_XFER_SIZE + 4096) {
|
||||
rpc_set_error(rpc, "Incoming PDU exceeds limit of %d bytes.", NFS_MAX_XFER_SIZE + 4096);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rpc->insize < pdu_size) {
|
||||
rpc->inbuf = realloc(rpc->inbuf, pdu_size);
|
||||
if (rpc->inbuf == NULL) {
|
||||
|
|
Loading…
Reference in New Issue