From nobody Mon Jun 8 16:28:54 2026 Received: from mail-vk1-f171.google.com (mail-vk1-f171.google.com [209.85.221.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 669DC34E774 for ; Wed, 27 May 2026 21:14:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779916479; cv=none; b=MyZ3w8zIKAoSUNkrgJP+HXLjEIoac619TI79/7SM2RfGXpw2MzZ0Yf2agGw7Ysmxzbevr0QNITSVNwyFNBaiCqOYxSRQ0mM++28lPNMrfYPIgmrh8CnIW2skqkNIqVEuXdFlHYYTbes8Ajm/7vS8VN4UAeaEnXv0bkrijonC8dY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779916479; c=relaxed/simple; bh=MVFXmjQsFKUFFqrx1qrfysx+EGOFN57ApxSniif0aAU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Pv2mG3cbo+Nbo1I/kPqp5elo0uHRbKDugy9ACX0L8i578Y6xv+p425N5Uwg1MUYwcO0NQv7g6vIE1LaZDyDDQUJh99xvhI7J5gUkHEZSbHoQ825j2AH6pzGiF89bOtc2oFcRC4UzOjOGBTMxWpA+lIQS9lV+YgJq4nZMaaiYrgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=AEyVumzj; arc=none smtp.client-ip=209.85.221.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AEyVumzj" Received: by mail-vk1-f171.google.com with SMTP id 71dfb90a1353d-5873983d19eso5399302e0c.2 for ; Wed, 27 May 2026 14:14:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779916477; x=1780521277; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=9Dju1WH+MAUl5DfrttmQ/rdSD2W+/yKAwSuBJTV89aM=; b=AEyVumzjTYAAGSlDEFwZBArk3sVM9heHdLHMajCUN6E8jpelZN5sfUTv42eotJ2A0I 8ZM5AheqK0o4H9RK0+qjSRuKd3yFTmbZYlEQZjBSm/kaFw6xeNcorcpFW5t09X3/PZUx juLiI8x1NeiXODQraRRND4tSDk0Gq9W/JAnAx/v20eQIFnYIgm0RFZcJ1jZk+1Fs5/jz 8CFb1fowkg3p0ebxSN8k4VX8+kYGN1XHmpJfSsKV6FvadN+Mf7MhaWBaCPJe8pWinAVZ uNX8m7TXwdBm04nv06zzLLDwftozl9dtb2EwJOZpg2GGlshB82viePfzrkhTRWwHn1A7 PqPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779916477; x=1780521277; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=9Dju1WH+MAUl5DfrttmQ/rdSD2W+/yKAwSuBJTV89aM=; b=Jmy6uF/rLPZKGjrJ3caN6NaeEujrH5X4PW/P2Hj2ML+31JsYzrgyW6roDv5vOMaq3P MJ4ALPZ/xUrSM7Yor+G+fUdODDvULH+Aqf5Aubqb2wHgbqln9S20/OCSKJxA6YlQifLl crm0pKJFeXTZyiM8DAbnbs8WH0u/PZoiGS6BX19eDi+o+qRphXy8JBjUqGIbBFt2tU/K JydqY4g+vp9N5nBVNHnH5V0tCSfcViFqU1tDnBK7cjRf82q8T+vecyE9/AjItniObGby zUaQhrIv5FD6VrGOPaxGENcSVKYzQQrMm0qMEL4Zy0Td9XXt+8kdpp+UYBZzUPczJ62U U8SQ== X-Gm-Message-State: AOJu0YzgoukqEslCoGNCDMfaIn9zXSDAMYYgmsCE5nj26PAxE+dd+SnW QmdSU4PlZgfXzKVf2mcdLzTRMO3U8Qz1G2DNXuQ7pOVXH4ll2dIQWhMz X-Gm-Gg: Acq92OGxI0j/s08M+2Dm5eVT0UkwNlOmRy/yVDx0Kp0tsHJy4uxSQCY9encfcDC6+Fb HJecOrriyEARid00nKI8MQW3BA4awhzIg9jpRQ+UYx3QlvQDZjrWDq56ZvG9Hz+nqERPVbB2JTe gk1O/b50q3L+/vXbG+uWyFfTjRzYjv8RYyik0GjoHmw4imMmuryVXsjwrnMQfk+TYJdsD93vTnj clxssZzIXOaeWPL81dfAAogv3WjEaCNi+QvInsaF7vjRmrrzr0QemfUWuwqSJijAVXQAGc9c8e1 mDAavr91UR0KV4VMdclZkvGpJ/uhNhUa6/NXSKFhj1QZaCctlh3gCrW19UOdJhrHuhMc0vAqEtZ A0f5psNxI9YPwJOTRiyGMQSALJYC4+hq19AxGk8Iiuzm7WMRFGTEEpbX14Pbi0NvC6rlKA4NhND E4THrNHK1beiyaQDs8NCIVf8tYBFF+bsH5488nFnxhOskPQmR7itFPD9ktF0VFP4ZCTvBQJ+Oki kLZvsQLe/FQOaK1x+uO8WU= X-Received: by 2002:a05:6122:320f:b0:575:352f:ead0 with SMTP id 71dfb90a1353d-5865fcf8663mr14015375e0c.6.1779916477301; Wed, 27 May 2026 14:14:37 -0700 (PDT) Received: from VitalNet.localdomain (186.232.16.162.vitalnetprovedor.com.br. [186.232.16.162]) by smtp.gmail.com with ESMTPSA id a1e0cc1a2514c-9638fe279aesm763183241.6.2026.05.27.14.14.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 May 2026 14:14:36 -0700 (PDT) From: Lucas Faria Mendes To: gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, linux-staging@lists.linux.dev, Lucas Faria Mendes Subject: [PATCH] vme_user: tighten slave window bounds and validate offsets Date: Wed, 27 May 2026 18:14:24 -0300 Message-ID: <20260527211425.569038-1-lucas.fariamo08@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Limit slave read/write operations to the allocated buffer size to prevent out-of-bounds access when a slave window is configured larger than its buffer. Treat zero-sized windows and invalid file positions as errors, and reject VME_SET_SLAVE requests that exceed the slave buffer. This makes the user access driver more robust and avoids silent EOF on invalid offsets. Signed-off-by: Lucas Faria Mendes diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user= /vme_user.c index 11e25c2f6..ca65cb57c 100644 --- a/drivers/staging/vme_user/vme_user.c +++ b/drivers/staging/vme_user/vme_user.c @@ -181,6 +181,7 @@ static ssize_t vme_user_read(struct file *file, char __= user *buf, size_t count, unsigned int minor =3D iminor(file_inode(file)); ssize_t retval; size_t image_size; + size_t max_size; if (minor =3D=3D CONTROL_MINOR) return 0; @@ -189,16 +190,24 @@ static ssize_t vme_user_read(struct file *file, char = __user *buf, size_t count, /* XXX Do we *really* want this helper - we can use vme_*_get ? */ image_size =3D vme_get_size(image[minor].resource); + if (!image_size) { + mutex_unlock(&image[minor].mutex); + return -EINVAL; + } + + max_size =3D image_size; + if (type[minor] =3D=3D SLAVE_MINOR && max_size > image[minor].size_buf) + max_size =3D image[minor].size_buf; /* Ensure we are starting at a valid location */ - if ((*ppos < 0) || (*ppos > (image_size - 1))) { + if ((*ppos < 0) || (*ppos >=3D max_size)) { mutex_unlock(&image[minor].mutex); - return 0; + return -EINVAL; } /* Ensure not reading past end of the image */ - if (*ppos + count > image_size) - count =3D image_size - *ppos; + if (*ppos + count > max_size) + count =3D max_size - *ppos; switch (type[minor]) { case MASTER_MINOR: @@ -224,6 +233,7 @@ static ssize_t vme_user_write(struct file *file, const = char __user *buf, unsigned int minor =3D iminor(file_inode(file)); ssize_t retval; size_t image_size; + size_t max_size; if (minor =3D=3D CONTROL_MINOR) return 0; @@ -231,16 +241,24 @@ static ssize_t vme_user_write(struct file *file, cons= t char __user *buf, mutex_lock(&image[minor].mutex); image_size =3D vme_get_size(image[minor].resource); + if (!image_size) { + mutex_unlock(&image[minor].mutex); + return -EINVAL; + } + + max_size =3D image_size; + if (type[minor] =3D=3D SLAVE_MINOR && max_size > image[minor].size_buf) + max_size =3D image[minor].size_buf; /* Ensure we are starting at a valid location */ - if ((*ppos < 0) || (*ppos > (image_size - 1))) { + if ((*ppos < 0) || (*ppos >=3D max_size)) { mutex_unlock(&image[minor].mutex); - return 0; + return -EINVAL; } /* Ensure not reading past end of the image */ - if (*ppos + count > image_size) - count =3D image_size - *ppos; + if (*ppos + count > max_size) + count =3D max_size - *ppos; switch (type[minor]) { case MASTER_MINOR: @@ -394,6 +412,9 @@ static int vme_user_ioctl(struct inode *inode, struct f= ile *file, return -EFAULT; } + if (slave.size > image[minor].size_buf) + return -EINVAL; + /* XXX We do not want to push aspace, cycle and width * to userspace as they are */ --- drivers/staging/vme_user/vme_user.c | 37 ++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user= /vme_user.c index 11e25c2f6..ca65cb57c 100644 --- a/drivers/staging/vme_user/vme_user.c +++ b/drivers/staging/vme_user/vme_user.c @@ -181,6 +181,7 @@ static ssize_t vme_user_read(struct file *file, char __= user *buf, size_t count, unsigned int minor =3D iminor(file_inode(file)); ssize_t retval; size_t image_size; + size_t max_size; =20 if (minor =3D=3D CONTROL_MINOR) return 0; @@ -189,16 +190,24 @@ static ssize_t vme_user_read(struct file *file, char = __user *buf, size_t count, =20 /* XXX Do we *really* want this helper - we can use vme_*_get ? */ image_size =3D vme_get_size(image[minor].resource); + if (!image_size) { + mutex_unlock(&image[minor].mutex); + return -EINVAL; + } + + max_size =3D image_size; + if (type[minor] =3D=3D SLAVE_MINOR && max_size > image[minor].size_buf) + max_size =3D image[minor].size_buf; =20 /* Ensure we are starting at a valid location */ - if ((*ppos < 0) || (*ppos > (image_size - 1))) { + if ((*ppos < 0) || (*ppos >=3D max_size)) { mutex_unlock(&image[minor].mutex); - return 0; + return -EINVAL; } =20 /* Ensure not reading past end of the image */ - if (*ppos + count > image_size) - count =3D image_size - *ppos; + if (*ppos + count > max_size) + count =3D max_size - *ppos; =20 switch (type[minor]) { case MASTER_MINOR: @@ -224,6 +233,7 @@ static ssize_t vme_user_write(struct file *file, const = char __user *buf, unsigned int minor =3D iminor(file_inode(file)); ssize_t retval; size_t image_size; + size_t max_size; =20 if (minor =3D=3D CONTROL_MINOR) return 0; @@ -231,16 +241,24 @@ static ssize_t vme_user_write(struct file *file, cons= t char __user *buf, mutex_lock(&image[minor].mutex); =20 image_size =3D vme_get_size(image[minor].resource); + if (!image_size) { + mutex_unlock(&image[minor].mutex); + return -EINVAL; + } + + max_size =3D image_size; + if (type[minor] =3D=3D SLAVE_MINOR && max_size > image[minor].size_buf) + max_size =3D image[minor].size_buf; =20 /* Ensure we are starting at a valid location */ - if ((*ppos < 0) || (*ppos > (image_size - 1))) { + if ((*ppos < 0) || (*ppos >=3D max_size)) { mutex_unlock(&image[minor].mutex); - return 0; + return -EINVAL; } =20 /* Ensure not reading past end of the image */ - if (*ppos + count > image_size) - count =3D image_size - *ppos; + if (*ppos + count > max_size) + count =3D max_size - *ppos; =20 switch (type[minor]) { case MASTER_MINOR: @@ -394,6 +412,9 @@ static int vme_user_ioctl(struct inode *inode, struct f= ile *file, return -EFAULT; } =20 + if (slave.size > image[minor].size_buf) + return -EINVAL; + /* XXX We do not want to push aspace, cycle and width * to userspace as they are */ --=20 2.53.0