Skip to contentSkip to conversation

usb/gadget: function fs req_match endpoint address fix

PATCH In review [email protected] 3 participants 4 messages Oct 3, 2023 – Oct 10, 2023 USB

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb/gadget: function fs req_match endpoint address fix

From: Dean Anderson <[email protected]>

Fixes f_fs.c handling USB_RECIP_ENDPOINT request types incorrectly for endpoints not belonging to it. f_fs.c needs to distinguish between IN and OUT endpoints, not just the endpoint number. Otherwise, f_fs may handle endpoints belonging to other functions. This occurs in the gadget/composite.c composite_setup function in the req_match callback.

---
 drivers/usb/gadget/function/f_fs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_fs.c +8 -4
index c727cb5de871..fb95ca4aa025 100644
@@ -71,7 +71,7 @@ struct ffs_function {
 	struct ffs_data			*ffs;
 
 	struct ffs_ep			*eps;
-	u8				eps_revmap[16];
+	u8				eps_revmap[32]; /* 16 in endpoints, 16 out endpoints*/
 	short				*interfaces_nums;
 
 	struct usb_function		function;
@@ -2847,6 +2847,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
 		struct usb_ep *ep;
 		u8 bEndpointAddress;
 		u16 wMaxPacketSize;
+		u8 addr;
 
 		/*
 		 * We back up bEndpointAddress because autoconfig overwrites
@@ -2870,8 +2871,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
 
 		ffs_ep->ep  = ep;
 		ffs_ep->req = req;
-		func->eps_revmap[ds->bEndpointAddress &
-				 USB_ENDPOINT_NUMBER_MASK] = idx + 1;
+		addr = ((ds->bEndpointAddress & USB_ENDPOINT_DIR_MASK) >> 3)
+			| (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		func->eps_revmap[addr] = idx + 1;
 		/*
 		 * If we use virtual address mapping, we restore
 		 * original bEndpointAddress value.
@@ -3403,7 +3405,9 @@ static void ffs_func_resume(struct usb_function *f)
 
 static int ffs_func_revmap_ep(struct ffs_function *func, u8 num)
 {
-	num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
+	u8 addr = ((num & USB_ENDPOINT_DIR_MASK) >> 3)
+		| (num & USB_ENDPOINT_NUMBER_MASK);
+	num = func->eps_revmap[addr];
 	return num ? num : -EDOM;
 }
 
Signature · 1 line
2.30.2
#1 lore raw
Quoted 9 lines · On Tue, Oct 03, 2023 at 03:11:03PM -0700, [email protected] wrote:

From: Dean Anderson <[email protected]>

Fixes f_fs.c handling USB_RECIP_ENDPOINT request types incorrectly for endpoints not belonging to it. f_fs.c needs to distinguish between IN and OUT endpoints, not just the endpoint number. Otherwise, f_fs may handle endpoints belonging to other functions. This occurs in the gadget/composite.c composite_setup function in the req_match callback.

What commit id does this fix?

Quoted 9 lines
---
 drivers/usb/gadget/function/f_fs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_fs.c +0 -0
index c727cb5de871..fb95ca4aa025 100644

drivers/usb/gadget/function/f_fs.c struct ffs_function { · line 74

Quoted 5 lines
drivers/usb/gadget/function/f_fs.c +1 -1
@@ -71,7 +71,7 @@ struct ffs_function {
 	struct ffs_data			*ffs;
 
 	struct ffs_ep			*eps;
-	u8				eps_revmap[16];
+	u8				eps_revmap[32]; /* 16 in endpoints, 16 out endpoints*/

Can't this be two separate arrays so you don't have to do fun masks to pick out which is an in and which is an out?

Quoted 24 lines
drivers/usb/gadget/function/f_fs.c +4 -2
 	short				*interfaces_nums;
 
 	struct usb_function		function;
@@ -2847,6 +2847,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
 		struct usb_ep *ep;
 		u8 bEndpointAddress;
 		u16 wMaxPacketSize;
+		u8 addr;
 
 		/*
 		 * We back up bEndpointAddress because autoconfig overwrites
@@ -2870,8 +2871,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep,
 
 		ffs_ep->ep  = ep;
 		ffs_ep->req = req;
-		func->eps_revmap[ds->bEndpointAddress &
-				 USB_ENDPOINT_NUMBER_MASK] = idx + 1;
+		addr = ((ds->bEndpointAddress & USB_ENDPOINT_DIR_MASK) >> 3)
+			| (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		func->eps_revmap[addr] = idx + 1;
 		/*
 		 * If we use virtual address mapping, we restore
 		 * original bEndpointAddress value.

drivers/usb/gadget/function/f_fs.c static void ffs_func_resume(struct usb_function *f) · line 3410

Quoted 7 lines
drivers/usb/gadget/function/f_fs.c +3 -1
@@ -3403,7 +3405,9 @@ static void ffs_func_resume(struct usb_function *f)
 
 static int ffs_func_revmap_ep(struct ffs_function *func, u8 num)
 {
-	num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
+	u8 addr = ((num & USB_ENDPOINT_DIR_MASK) >> 3)
+		| (num & USB_ENDPOINT_NUMBER_MASK);
+	num = func->eps_revmap[addr];

That's messy, again, 2 arrays would make this much simpler I think?

thanks,

greg k-h

#2 lore raw
Quoted 9 lines · Greg KH
Quoted 8 lines · On Tue, Oct 03, 2023 at 03:11:03PM -0700, [email protected] wrote:

From: Dean Anderson <[email protected]>

Fixes f_fs.c handling USB_RECIP_ENDPOINT request types incorrectly for endpoints not belonging to it. f_fs.c needs to distinguish between IN and OUT endpoints, not just the endpoint number. Otherwise, f_fs may handle endpoints belonging to other functions. This occurs in the gadget/composite.c composite_setup function in the req_match callback.

Quoted 3 lines
Quoted 1 line

What commit id does this fix?

It's out of date. I'll resubmit with the suggested changes.

Quoted 47 lines
Quoted 10 lines
---
 drivers/usb/gadget/function/f_fs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/f_fs.c +0 -0
index c727cb5de871..fb95ca4aa025 100644

drivers/usb/gadget/function/f_fs.c struct ffs_function { · line 74

Quoted 5 lines
drivers/usb/gadget/function/f_fs.c +1 -1
@@ -71,7 +71,7 @@ struct ffs_function {
 	struct ffs_data			*ffs;
 
 	struct ffs_ep			*eps;
-	u8				eps_revmap[16];
+	u8				eps_revmap[32]; /* 16 in endpoints, 16 out endpoints*/

Can't this be two separate arrays so you don't have to do fun masks to pick out which is an in and which is an out?

Quoted 28 lines
drivers/usb/gadget/function/f_fs.c +1 -0
 	short				*interfaces_nums;
 
 	struct usb_function		function;
@@ -2847,6 +2847,7 @@ static int __ffs_func_bind_do_descs(enum 
 ffs_entity_type type, u8 *valuep,
 		struct usb_ep *ep;
 		u8 bEndpointAddress;
 		u16 wMaxPacketSize;
+		u8 addr;
 
 		/*
drivers/usb/gadget/function/f_fs.c +3 -2
 		 * We back up bEndpointAddress because autoconfig overwrites
@@ -2870,8 +2871,9 @@ static int __ffs_func_bind_do_descs(enum 
 ffs_entity_type type, u8 *valuep,
 
 		ffs_ep->ep  = ep;
 		ffs_ep->req = req;
-		func->eps_revmap[ds->bEndpointAddress &
-				 USB_ENDPOINT_NUMBER_MASK] = idx + 1;
+		addr = ((ds->bEndpointAddress & USB_ENDPOINT_DIR_MASK) >> 3)
+			| (ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+		func->eps_revmap[addr] = idx + 1;
 		/*
 		 * If we use virtual address mapping, we restore
drivers/usb/gadget/function/f_fs.c +0 -0
 		 * original bEndpointAddress value.
@@ -3403,7 +3405,9 @@ static void ffs_func_resume(struct usb_function 
 *f)
 
Quoted 8 lines

drivers/usb/gadget/function/f_fs.c static void ffs_func_resume(struct usb_function *f) · line 3410

Quoted 6 lines
drivers/usb/gadget/function/f_fs.c +3 -1
 static int ffs_func_revmap_ep(struct ffs_function *func, u8 num)
 {
-	num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
+	u8 addr = ((num & USB_ENDPOINT_DIR_MASK) >> 3)
+		| (num & USB_ENDPOINT_NUMBER_MASK);
+	num = func->eps_revmap[addr];

That's messy, again, 2 arrays would make this much simpler I think?

It's similar to the approach in composite.c. v6.6-rc4, line 1013, but yes 2 arrays would be simpler.

BTW, should composite.c at least get rid of the magic numbers?

composite.c commit 8a749fd1a8720d4619c91c8b6e7528c0a355c0aa
line: 1013

addr = ((ep->bEndpointAddress & 0x80) >> 3)

     |  (ep->bEndpointAddress & 0x0f);
Quoted 4 lines

thanks,

greg k-h

Thanks,

Dean A

#3 lore raw
Quoted 12 lines · On Mon, Oct 09, 2023 at 04:29:48PM -0500, [email protected] wrote:
Quoted 8 lines

drivers/usb/gadget/function/f_fs.c static void ffs_func_resume(struct usb_function *f) · line 3410

Quoted 6 lines

static int ffs_func_revmap_ep(struct ffs_function *func, u8 num) {

drivers/usb/gadget/function/f_fs.c +3 -1
-	num = func->eps_revmap[num & USB_ENDPOINT_NUMBER_MASK];
+	u8 addr = ((num & USB_ENDPOINT_DIR_MASK) >> 3)
+		| (num & USB_ENDPOINT_NUMBER_MASK);
+	num = func->eps_revmap[addr];

That's messy, again, 2 arrays would make this much simpler I think?

It's similar to the approach in composite.c. v6.6-rc4, line 1013, but yes 2 arrays would be simpler.

Quoted 7 lines

BTW, should composite.c at least get rid of the magic numbers?

composite.c commit 8a749fd1a8720d4619c91c8b6e7528c0a355c0aa
line: 1013

addr = ((ep->bEndpointAddress & 0x80) >> 3)

     |  (ep->bEndpointAddress & 0x0f);

Yes, it should.

thanks,

greg k-h