staging: lustre: integer overflow in obd_ioctl_is_invalid()
Subsystems (2)
PATCH 2/2 staging: lustre: integer overflow in obd_ioctl_is_invalid()
The obd_ioctl_getdata() function caps "data->ioc_len" at OBD_MAX_IOCTL_BUFFER and then calls this obd_ioctl_is_invalid() to check that the other values inside data are valid.
There are several lengths inside data but when they are added together they must not be larger than "data->ioc_len". The checks against "(data->ioc_inllen1 > (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits so the checks are insufficient.
I have changed it to "> OBD_MAX_IOCTL_BUFFER" instead.
drivers/staging/lustre/lustre/include/lustre_lib.h +5 -5
@@ -192,23 +192,23 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen1 > (1 <<30 )) { +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen2 > (1 <<30 )) { +if (data->ioc_inllen2 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen2 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen3 > (1 <<30 )) { +if (data->ioc_inllen3 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen3 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen4 > (1 <<30 )) { +if (data->ioc_inllen4 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen4 larger than 1<<30\n" );return 1 ; }
Quoted 4 lines · Dan Carpenter
The
obd_ioctl_getdata()function caps "data->ioc_len" atOBD_MAX_IOCTL_BUFFERand then calls thisobd_ioctl_is_invalid()to check that the other values inside data are valid.
Quoted 8 lines
There are several lengths inside data but when they are added together they must not be larger than "
data->ioc_len". The checks against "(data->ioc_inllen1> (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits so the checks are insufficient.I have changed it to ">
OBD_MAX_IOCTL_BUFFER" instead.
Thanks,
Tao
Quoted 35 lines
Signed-off-by Dan Carpenter <[email protected]>drivers/staging/lustre/lustre/include/lustre_lib.h +5
-5@@ -192,23 +192,23 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen1 > (1 <<30 )) { +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen2 > (1 <<30 )) { +if (data->ioc_inllen2 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen2 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen3 > (1 <<30 )) { +if (data->ioc_inllen3 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen3 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen4 > (1 <<30 )) { +if (data->ioc_inllen4 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen4 larger than 1<<30\n" );return 1 ; }
Am 24.04.2014 23:49, schrieb Dan Carpenter:
Quoted 19 lines
The
obd_ioctl_getdata()function caps "data->ioc_len" atOBD_MAX_IOCTL_BUFFERand then calls thisobd_ioctl_is_invalid()to check that the other values inside data are valid.There are several lengths inside data but when they are added together they must not be larger than "
data->ioc_len". The checks against "(data->ioc_inllen1> (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits so the checks are insufficient.I have changed it to ">
OBD_MAX_IOCTL_BUFFER" instead.Signed-off-by Dan Carpenter <[email protected]>drivers/staging/lustre/lustre/include/lustre_lib.h +0
-0
drivers/staging/lustre/lustre/include/lustre_lib.h static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) · line 198
Quoted 8 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +1
-1@@ -192,23 +192,23 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" );return 1 ; }
I would suggest to adjust the errormsg also like:CERROR("OBD ioctl: ioc_len larger than OBD_MAX_IOCTL_BUFFER\n");
otherwise future debuggers will be confused.
just my 2 cents
re,
wh
Quoted 25 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +4
-5-if (data->ioc_inllen1 > (1 <<30 )) { +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen2 > (1 <<30 )) { +if (data->ioc_inllen2 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen2 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen3 > (1 <<30 )) { +if (data->ioc_inllen3 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen3 larger than 1<<30\n" );return 1 ; } -if (data->ioc_inllen4 > (1 <<30 )) { +if (data->ioc_inllen4 >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_inllen4 larger than 1<<30\n" );return 1 ; } --To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 34 lines · walter harms
Am 24.04.2014 23:49, schrieb Dan Carpenter:
Quoted 19 lines
The
obd_ioctl_getdata()function caps "data->ioc_len" atOBD_MAX_IOCTL_BUFFERand then calls thisobd_ioctl_is_invalid()to check that the other values inside data are valid.There are several lengths inside data but when they are added together they must not be larger than "
data->ioc_len". The checks against "(data->ioc_inllen1> (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits so the checks are insufficient.I have changed it to ">
OBD_MAX_IOCTL_BUFFER" instead.Signed-off-by Dan Carpenter <[email protected]>drivers/staging/lustre/lustre/include/lustre_lib.h +0
-0drivers/staging/lustre/lustre/include/lustre_lib.h static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) · line 198
Quoted 8 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +1
-1@@ -192,23 +192,23 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) {CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" );return 1 ; }I would suggest to adjust the errormsg also like:
CERROR("OBD ioctl: ioc_len larger than OBD_MAX_IOCTL_BUFFER\n");
Quoted 4 lines
otherwise future debuggers will be confused.
just my 2 cents
Ah yes. I will resend.
regards,
dan carpenter
PATCH v2 2/2 staging: lustre: integer overflow in obd_ioctl_is_invalid()
The obd_ioctl_getdata() function caps "data->ioc_len" at OBD_MAX_IOCTL_BUFFER and then calls this obd_ioctl_is_invalid() to check that the other values inside data are valid.
There are several lengths inside data but when they are added together they must not be larger than "data->ioc_len". The checks against "(data->ioc_inllen1 > (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits, so the checks are insufficient.
I have changed it to "> OBD_MAX_IOCTL_BUFFER" instead.
---
v2: Updated the error messages as Walter Harms pointed out.
drivers/staging/lustre/lustre/include/lustre_lib.h +11 -10
@@ -179,24 +179,25 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" ); +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_len larger than %d\n" , +OBD_MAX_IOCTL_BUFFER );return 1 ; } -if (data->ioc_inllen1 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" ); +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen1 larger than ioc_len\n" );return 1 ; } -if (data->ioc_inllen2 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen2 larger than 1<<30\n" ); +if (data->ioc_inllen2 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen2 larger than ioc_len\n" );return 1 ; } -if (data->ioc_inllen3 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen3 larger than 1<<30\n" ); +if (data->ioc_inllen3 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen3 larger than ioc_len\n" );return 1 ; } -if (data->ioc_inllen4 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen4 larger than 1<<30\n" ); +if (data->ioc_inllen4 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen4 larger than ioc_len\n" );return 1 ; }if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
Am 28.04.2014 12:58, schrieb Dan Carpenter:
Quoted 27 lines
The
obd_ioctl_getdata()function caps "data->ioc_len" atOBD_MAX_IOCTL_BUFFERand then calls thisobd_ioctl_is_invalid()to check that the other values inside data are valid.There are several lengths inside data but when they are added together they must not be larger than "
data->ioc_len". The checks against "(data->ioc_inllen1> (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits, so the checks are insufficient.I have changed it to ">
OBD_MAX_IOCTL_BUFFER" instead.Signed-off-by Dan Carpenter <[email protected]>---
v2: Updated the error messages as Walter Harms pointed out.drivers/staging/lustre/lustre/include/lustre_lib.h +1
-2@@ -179,24 +179,25 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" ); +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) {
drivers/staging/lustre/lustre/include/lustre_lib.h static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) · line 190
Quoted 10 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +4
-2+CERROR ("OBD ioctl: ioc_len larger than %d\n" , +OBD_MAX_IOCTL_BUFFER );return 1 ; } -if (data->ioc_inllen1 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" ); +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen1 larger than ioc_len\n" );return 1 ; }
The error mention ioc_len the compare is OBD_MAX_IOCTL_BUFFER ? Is that intentional ?
re,
wh
Quoted 20 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +6
-6-if (data->ioc_inllen2 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen2 larger than 1<<30\n" ); +if (data->ioc_inllen2 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen2 larger than ioc_len\n" );return 1 ; } -if (data->ioc_inllen3 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen3 larger than 1<<30\n" ); +if (data->ioc_inllen3 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen3 larger than ioc_len\n" );return 1 ; } -if (data->ioc_inllen4 > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_inllen4 larger than 1<<30\n" ); +if (data->ioc_inllen4 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen4 larger than ioc_len\n" );return 1 ; }if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
Quoted 35 lines · walter harms
Am 28.04.2014 12:58, schrieb Dan Carpenter:
Quoted 32 lines
The
obd_ioctl_getdata()function caps "data->ioc_len" atOBD_MAX_IOCTL_BUFFERand then calls thisobd_ioctl_is_invalid()to check that the other values inside data are valid.There are several lengths inside data but when they are added together they must not be larger than "
data->ioc_len". The checks against "(data->ioc_inllen1> (1<<30))" are supposed to ensure that the addition does not have an integer overflow. But "(1<<30) * 4" actually can overflow 32 bits, so the checks are insufficient.I have changed it to ">
OBD_MAX_IOCTL_BUFFER" instead.Signed-off-by Dan Carpenter <[email protected]>---
v2: Updated the error messages as Walter Harms pointed out.drivers/staging/lustre/lustre/include/lustre_lib.h +3
-3@@ -179,24 +179,25 @@ static inline int obd_ioctl_packlen(struct obd_ioctl_data *data)static inline int obd_ioctl_is_invalid (struct obd_ioctl_data *data) { -if (data->ioc_len > (1 <<30 )) { -CERROR ("OBD ioctl: ioc_len larger than 1<<30\n" ); +if (data->ioc_len >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_len larger than %d\n" , +OBD_MAX_IOCTL_BUFFER );return 1 ; } -if (data->ioc_inllen1 > (1 <<30 )) {
Quoted 8 lines
drivers/staging/lustre/lustre/include/lustre_lib.h static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) · line 190
Quoted 5 lines
drivers/staging/lustre/lustre/include/lustre_lib.h +2
-1-CERROR ("OBD ioctl: ioc_inllen1 larger than 1<<30\n" ); +if (data->ioc_inllen1 >OBD_MAX_IOCTL_BUFFER ) { +CERROR ("OBD ioctl: ioc_inllen1 larger than ioc_len\n" );return 1 ; }The error mention
ioc_lenthe compare isOBD_MAX_IOCTL_BUFFER? Is that intentional ?
Yep.
regards,
dan carpenter