提交 3e37ba2b 编写于 作者: O Oliver Hartkopp 提交者: Zheng Zengkai

can: raw: return -ERANGE when filterset does not fit into user space buffer

mainline inclusion
from mainline-5.12-rc1
commit 0de70e28
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4QAGM?from=project-issue

-------------------------------------------------

Multiple filters (struct can_filter) can be set with the setsockopt()
function, which was originally intended as a write-only operation.

As getsockopt() also provides a CAN_RAW_FILTER option to read back the
given filters, the caller has to provide an appropriate user space buffer.
In the case this buffer is too small the getsockopt() silently truncates
the filter information and gives no information about the needed space.
This is safe but not convenient for the programmer.

In net/core/sock.c the SO_PEERGROUPS sockopt had a similar requirement
and solved it by returning -ERANGE in the case that the provided data
does not fit into the given user space buffer and fills the required size
into optlen, so that the caller can retry with a matching buffer length.

This patch adopts this approach for CAN_RAW_FILTER getsockopt().
Reported-by: NPhillip Schichtel <phillip@schich.tel>
Signed-off-by: NOliver Hartkopp <socketcan@hartkopp.net>
Tested-By: NPhillip Schichtel <phillip@schich.tel>
Link: https://lore.kernel.org/r/20201216174928.21663-1-socketcan@hartkopp.netSigned-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: NZiyang Xuan <william.xuanziyang@huawei.com>
Reviewed-by: NYue Haibing <yuehaibing@huawei.com>
Reviewed-by: NWei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 50d5bf1b
......@@ -710,10 +710,18 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
if (ro->count > 0) {
int fsize = ro->count * sizeof(struct can_filter);
if (len > fsize)
len = fsize;
if (copy_to_user(optval, ro->filter, len))
err = -EFAULT;
/* user space buffer to small for filter list? */
if (len < fsize) {
/* return -ERANGE and needed space in optlen */
err = -ERANGE;
if (put_user(fsize, optlen))
err = -EFAULT;
} else {
if (len > fsize)
len = fsize;
if (copy_to_user(optval, ro->filter, len))
err = -EFAULT;
}
} else {
len = 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册