From: Drew Kluemke <[email protected]> Multiple NFS reply handlers (rpc_lookup_reply, nfs_mount_reply, nfs_umountall_reply, nfs_lookup_reply, nfs_readlink_reply) copy network data into a stack-allocated struct rpc_t without verifying that the UDP payload length fits within the buffer. A malicious or malformed NFS server response with len > sizeof(rpc_pkt) overwrites the stack frame.
Add a bounds check before each memcpy to drop oversized packets. Signed-off-by: Drew Kluemke <[email protected]> Signed-off-by: Sriram Sriram <[email protected]> --- Changes in v2: - No change, rebased onto current master. net/nfs-common.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/nfs-common.c b/net/nfs-common.c index 637fcfd9bb8..226e3fe5798 100644 --- a/net/nfs-common.c +++ b/net/nfs-common.c @@ -503,6 +503,8 @@ static int rpc_lookup_reply(int prog, uchar *pkt, unsigned int len) { struct rpc_t rpc_pkt; + if (len > sizeof(rpc_pkt.u.data)) + return -NFS_RPC_DROP; memcpy(&rpc_pkt.u.data[0], pkt, len); if (ntohl(rpc_pkt.u.reply.id) > rpc_id) @@ -532,6 +534,8 @@ static int nfs_mount_reply(uchar *pkt, unsigned int len) struct rpc_t rpc_pkt; int ret; + if (len > sizeof(rpc_pkt.u.data)) + return -NFS_RPC_DROP; memcpy(&rpc_pkt.u.data[0], pkt, len); if (ntohl(rpc_pkt.u.reply.id) > rpc_id) @@ -561,6 +565,8 @@ static int nfs_umountall_reply(uchar *pkt, unsigned int len) { struct rpc_t rpc_pkt; + if (len > sizeof(rpc_pkt.u.data)) + return -NFS_RPC_DROP; memcpy(&rpc_pkt.u.data[0], pkt, len); if (ntohl(rpc_pkt.u.reply.id) > rpc_id) @@ -584,6 +590,8 @@ static int nfs_lookup_reply(uchar *pkt, unsigned int len) struct rpc_t rpc_pkt; int ret; + if (len > sizeof(rpc_pkt.u.data)) + return -NFS_RPC_DROP; memcpy(&rpc_pkt.u.data[0], pkt, len); if (ntohl(rpc_pkt.u.reply.id) > rpc_id) @@ -645,6 +653,8 @@ static int nfs_readlink_reply(uchar *pkt, unsigned int len) int rlen; int nfsv3_data_offset = 0; + if (len > sizeof(rpc_pkt)) + return -NFS_RPC_DROP; memcpy((unsigned char *)&rpc_pkt, pkt, len); if (ntohl(rpc_pkt.u.reply.id) > rpc_id) -- 2.49.0
