usb: f_fs: Drop check on Reserved1 field on OS_DESC_EXT_COMPAT
Subsystems (2)
PATCH 1/1 usb: f_fs: Drop check on Reserved1 field on OS_DESC_EXT_COMPAT
This check has gone through several incompatible variations in commits 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT"), 354bc45bf329 ("usb: gadget: f_fs: Fix ExtCompat descriptor validation") and 3ba534df815f ("Revert "usb: gadget: f_fs:
Fix ExtCompat descriptor validation"") after initially being introduced in commit f0175ab51993 ("usb: gadget: f_fs: OS descriptors support").
The various changes make it impossible for a single userspace implementation to work with different kernel versions, so let's just drop the condition to avoid breaking userspace.
--- drivers/usb/gadget/function/f_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/gadget/function/f_fs.c +1 -2
@@ -2282,8 +2282,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ;for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])
Signature · 1 line
2.15.0
Hi,
Quoted 23 lines · John Keeping
This check has gone through several incompatible variations in commits
53642399aa71("usb: gadget:f_fs: Fix wrong check on reserved1 ofOS_DESC_EXT_COMPAT"),354bc45bf329("usb: gadget:f_fs: Fix ExtCompat descriptor validation") and3ba534df815f("Revert "usb: gadget:f_fs:
Fix ExtCompat descriptor validation"") after initially being introduced in commitf0175ab51993("usb: gadget:f_fs: OS descriptors support").The various changes make it impossible for a single userspace implementation to work with different kernel versions, so let's just drop the condition to avoid breaking userspace.
Fixes 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT")Cc [email protected] # v4.7+Signed-off-by John Keeping <[email protected]>--- drivers/usb/gadget/function/f_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/usb/gadget/function/f_fs.c +0
-0
drivers/usb/gadget/function/f_fs.c static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, · line 2288
Quoted 9 lines
drivers/usb/gadget/function/f_fs.c +1
-2@@ -2282,8 +2282,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ;for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])
Sorry, but no. We want to be compliant with the specification. If there are older still-maintained stable trees which are not working, we need to backport a fix to them, but we're not allowing uncompliant implementations.
Signature · 1 line
balbi
Quoted 26 lines · Felipe Balbi
Quoted 25 lines · John Keeping
This check has gone through several incompatible variations in commits
53642399aa71("usb: gadget:f_fs: Fix wrong check on reserved1 ofOS_DESC_EXT_COMPAT"),354bc45bf329("usb: gadget:f_fs: Fix ExtCompat descriptor validation") and3ba534df815f("Revert "usb: gadget:f_fs:
Fix ExtCompat descriptor validation"") after initially being introduced in commitf0175ab51993("usb: gadget:f_fs: OS descriptors support").The various changes make it impossible for a single userspace implementation to work with different kernel versions, so let's just drop the condition to avoid breaking userspace.
Fixes 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT")Cc [email protected] # v4.7+Signed-off-by John Keeping <[email protected]>--- drivers/usb/gadget/function/f_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/usb/gadget/function/f_fs.c +0
-0@@ -2282,8 +2282,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;
Quoted 12 lines
drivers/usb/gadget/function/f_fs.c static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, · line 2288
Quoted 7 lines
drivers/usb/gadget/function/f_fs.c +1
-2if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ;for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])Sorry, but no. We want to be compliant with the specification. If there are older still-maintained stable trees which are not working, we need to backport a fix to them, but we're not allowing uncompliant implementations.
Aren't we allowing non-compliant implementations now? The spec says the value must be 1 but since v4.7 this code has allowed all non-zero values.
At this point I don't think the kernel can disallow any values of Reserved1 without breaking someone's userspace.
Hi,
Quoted 41 lines · John Keeping
Quoted 26 lines · Felipe Balbi
Quoted 25 lines · John Keeping
This check has gone through several incompatible variations in commits
53642399aa71("usb: gadget:f_fs: Fix wrong check on reserved1 ofOS_DESC_EXT_COMPAT"),354bc45bf329("usb: gadget:f_fs: Fix ExtCompat descriptor validation") and3ba534df815f("Revert "usb: gadget:f_fs:
Fix ExtCompat descriptor validation"") after initially being introduced in commitf0175ab51993("usb: gadget:f_fs: OS descriptors support").The various changes make it impossible for a single userspace implementation to work with different kernel versions, so let's just drop the condition to avoid breaking userspace.
Fixes 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT")Cc [email protected] # v4.7+Signed-off-by John Keeping <[email protected]>--- drivers/usb/gadget/function/f_fs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/usb/gadget/function/f_fs.c +0
-0@@ -2282,8 +2282,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;Quoted 12 lines
drivers/usb/gadget/function/f_fs.c static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, · line 2288
Quoted 7 lines
drivers/usb/gadget/function/f_fs.c +1
-2if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ;for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])Sorry, but no. We want to be compliant with the specification. If there are older still-maintained stable trees which are not working, we need to backport a fix to them, but we're not allowing uncompliant implementations.
Quoted 3 lines
Aren't we allowing non-compliant implementations now? The spec says the value must be 1 but since v4.7 this code has allowed all non-zero values.
Good point. Then how about we just force the value to 1 in f_fs.c and remove the check?
Signature · 1 line
balbi
Quoted 2 lines · Felipe Balbi
Good point. Then how about we just force the value to 1 in
f_fs.cand remove the check?
That seems reasonable. Something like this?
-- >8 --
Subject: [PATCH] usb: f_fs: Force Reserved1=1 in OS_DESC_EXT_COMPAT
The specification says that the Reserved1 field in OS_DESC_EXT_COMPAT must have the value "1", but when this feature was first implemented we rejected any non-zero values.
This was adjusted to accept all non-zero values (while now rejecting zero) in commit 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT"), but that breaks any userspace programs that worked previously by returning EINVAL when Reserved1 == 0 which was previously the only value that succeeded!
If we just set the field to "1" ourselves, both old and new userspace programs continue to work correctly and, as a bonus, old programs are now compliant with the specification without having to fix anything themselves.
--- drivers/usb/gadget/function/f_fs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/usb/gadget/function/f_fs.c +11 -2
@@ -2282,9 +2282,18 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ; +if (d->Reserved1 !=1 ) { +/* +* According to the spec, Reserved1 must be set to 1 +* but older kernels incorrectly rejected non-zero +* values. We fix it here to avoid returning EINVAL +* in response to values we used to accept. +*/ +pr_debug ("usb_ext_compat_desc::Reserved1 forced to 1\n" ); + d->Reserved1 =1 ; + }for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])return -EINVAL ;
Signature · 1 line
2.15.0
Hi,
Quoted 43 lines · John Keeping
Quoted 2 lines · Felipe Balbi
Good point. Then how about we just force the value to 1 in
f_fs.cand remove the check?That seems reasonable. Something like this?
-- >8 --
Subject: [PATCH] usb:f_fs: Force Reserved1=1 inOS_DESC_EXT_COMPATThe specification says that the Reserved1 field in
OS_DESC_EXT_COMPATmust have the value "1", but when this feature was first implemented we rejected any non-zero values.This was adjusted to accept all non-zero values (while now rejecting zero) in commit
53642399aa71("usb: gadget:f_fs: Fix wrong check on reserved1 ofOS_DESC_EXT_COMPAT"), but that breaks any userspace programs that worked previously by returning EINVAL when Reserved1 == 0 which was previously the only value that succeeded!If we just set the field to "1" ourselves, both old and new userspace programs continue to work correctly and, as a bonus, old programs are now compliant with the specification without having to fix anything themselves.
Fixes 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT")Signed-off-by John Keeping <[email protected]>--- drivers/usb/gadget/function/f_fs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)drivers/usb/gadget/function/f_fs.c +1
-2@@ -2282,9 +2282,18 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ;
drivers/usb/gadget/function/f_fs.c static int __ffs_data_do_os_desc(enum ffs_os_desc_type type, · line 2296
Quoted 10 lines
drivers/usb/gadget/function/f_fs.c +10
-0+if (d->Reserved1 !=1 ) { +/* +* According to the spec, Reserved1 must be set to 1 +* but older kernels incorrectly rejected non-zero +* values. We fix it here to avoid returning EINVAL +* in response to values we used to accept. +*/ +pr_debug ("usb_ext_compat_desc::Reserved1 forced to 1\n" ); + d->Reserved1 =1 ; + }
exactly like that. Care to send as a formal patch so I can apply?
Signature · 1 line
balbi
PATCH v2 1/1 usb: f_fs: Force Reserved1=1 in OS_DESC_EXT_COMPAT
The specification says that the Reserved1 field in OS_DESC_EXT_COMPAT must have the value "1", but when this feature was first implemented we rejected any non-zero values.
This was adjusted to accept all non-zero values (while now rejecting zero) in commit 53642399aa71 ("usb: gadget: f_fs: Fix wrong check on reserved1 of OS_DESC_EXT_COMPAT"), but that breaks any userspace programs that worked previously by returning EINVAL when Reserved1 == 0 which was previously the only value that succeeded!
If we just set the field to "1" ourselves, both old and new userspace programs continue to work correctly and, as a bonus, old programs are now compliant with the specification without having to fix anything themselves.
--- drivers/usb/gadget/function/f_fs.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
Quoted 1 line · Felipe Balbi
exactly like that. Care to send as a formal patch so I can apply?
Here it is.
drivers/usb/gadget/function/f_fs.c +11 -2
@@ -2282,9 +2282,18 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,int i;if (len <sizeof (*d) || - d->bFirstInterfaceNumber >= ffs->interfaces_count || - !d->Reserved1) + d->bFirstInterfaceNumber >= ffs->interfaces_count)return -EINVAL ; +if (d->Reserved1 !=1 ) { +/* +* According to the spec, Reserved1 must be set to 1 +* but older kernels incorrectly rejected non-zero +* values. We fix it here to avoid returning EINVAL +* in response to values we used to accept. +*/ +pr_debug ("usb_ext_compat_desc::Reserved1 forced to 1\n" ); + d->Reserved1 =1 ; + }for (i =0 ; i <ARRAY_SIZE (d->Reserved2); ++i)if (d->Reserved2[i])return -EINVAL ;
Signature · 1 line
2.15.0