can: raw: return -ERANGE when filterset does not fit into user space buffer
Subsystems (2)
Oliver Hartkopp
maintainerRFC PATCH 1/1 can: raw: return -ERANGE when filterset does not fit into user space buffer
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().
--- net/can/raw.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
net/can/raw.c +12 -4
@@ -663,14 +663,22 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,case CAN_RAW_FILTER :lock_sock (sk);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 ; }release_sock (sk);
Signature · 1 line
2.29.2
Quoted 21 lines · Oliver Hartkopp
Multiple filters (struct
can_filter) can be set with thesetsockopt()function, which was originally intended as a write-only operation.As
getsockopt()also provides aCAN_RAW_FILTERoption to read back the
given filters, the caller has to provide an appropriate user space buffer.
In the case this buffer is too small thegetsockopt()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.ctheSO_PEERGROUPSsockopt had a similar requirement
and solved it by returning-ERANGEin 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.
Quoted 4 lines
This patch adopts this approach for
CAN_RAW_FILTERgetsockopt().Reported-by Phillip Schichtel <[email protected]>Signed-off-by Oliver Hartkopp <[email protected]>
Successfully tested this in my Java bindings.
~ Phillip
Quoted 40 lines
---
net/can/raw.c | 16 ++++++++++++----1 file changed, 12 insertions(+), 4 deletions(-)net/can/raw.c +0
-0@@ -663,14 +663,22 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,case
CAN_RAW_FILTER:
lock_sock(sk);
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-ERANGEand 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;
}
release_sock(sk);
Marc Kleine-Budde
maintainerQuoted 14 lines · Oliver Hartkopp
Multiple filters (struct
can_filter) can be set with thesetsockopt()function, which was originally intended as a write-only operation.As
getsockopt()also provides aCAN_RAW_FILTERoption to read back the given filters, the caller has to provide an appropriate user space buffer. In the case this buffer is too small thegetsockopt()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.ctheSO_PEERGROUPSsockopt had a similar requirement and solved it by returning-ERANGEin 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.
Quoted 4 lines
This patch adopts this approach for
CAN_RAW_FILTERgetsockopt().Reported-by Phillip Schichtel <[email protected]>Signed-off-by Oliver Hartkopp <[email protected]>
Added to linux-can-next/testing. Do we need an update to the in kernel Documentation?
Marc
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung West/Dortmund | Phone: +49-231-2826-924 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Oliver Hartkopp
maintainerQuoted 15 lines · Marc Kleine-Budde
Quoted 14 lines · Oliver Hartkopp
Multiple filters (struct
can_filter) can be set with thesetsockopt()function, which was originally intended as a write-only operation.As
getsockopt()also provides aCAN_RAW_FILTERoption to read back the given filters, the caller has to provide an appropriate user space buffer. In the case this buffer is too small thegetsockopt()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.ctheSO_PEERGROUPSsockopt had a similar requirement and solved it by returning-ERANGEin 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.
Quoted 7 lines
Quoted 4 lines
This patch adopts this approach for
CAN_RAW_FILTERgetsockopt().Reported-by Phillip Schichtel <[email protected]>Signed-off-by Oliver Hartkopp <[email protected]>Added to linux-can-next/testing. Do we need an update to the in kernel Documentation?
Yes. Also thought about it.
Will prepare a patch for the documentation too.
Regards,
Oliver