USB: cdc-acm: TIOCSSERIAL fixes
Subsystems (3)
cover USB: cdc-acm: TIOCSSERIAL fixes
This series fixes up a few issues with cdc-acm TIOCSSERIAL implementation.
Johan
Johan Hovold (3):
Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL"
USB: cdc-acm: fix unprivileged TIOCCSERIAL
USB: cdc-acm: fix TIOCGSERIAL implementation
drivers/usb/class/cdc-acm.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-)
Signature · 1 line
2.26.3
PATCH 1/3 Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL"
This reverts commit b401f8c4f492cbf74f3f59c9141e5be3071071bb.
The offending commit claimed that trying to set the values reported back by TIOCGSERIAL as a regular user could result in an -EPERM error when HZ is 250, but that was never the case.
With HZ=250, the default 0.5 second value of close_delay is converted to 125 jiffies when set and is converted back to 50 centiseconds by TIOCGSERIAL as expected (not 12 cs as was claimed).
Comparing the internal current and new jiffies values is just fine to determine if the value is about to change so drop the bogus workaround (which was also backported to stable).
For completeness: With different default values for these parameters or with a HZ value not divisible by two, the lack of rounding when setting the default values in tty_port_init() could result in an -EPERM being returned, but this is hardly something we need to worry about.
--- drivers/usb/class/cdc-acm.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/usb/class/cdc-acm.c +2 -9
@@ -942,7 +942,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) {struct acm *acm = tty->driver_data;unsigned int closing_wait, close_delay; -unsigned int old_closing_wait, old_close_delay;int retval =0 ; close_delay =msecs_to_jiffies (ss->close_delay *10 );
@@ -950,17 +949,11 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) ASYNC_CLOSING_WAIT_NONE :msecs_to_jiffies (ss->closing_wait *10 ); -/* we must redo the rounding here, so that the values match */ - old_close_delay =jiffies_to_msecs (acm->port.close_delay) /10 ; - old_closing_wait = acm->port.closing_wait ==ASYNC_CLOSING_WAIT_NONE ? -ASYNC_CLOSING_WAIT_NONE : -jiffies_to_msecs (acm->port.closing_wait) /10 ; -mutex_lock (&acm->port.mutex);if (!capable (CAP_SYS_ADMIN )) { -if ((ss->close_delay != old_close_delay) || - (ss->closing_wait != old_closing_wait)) +if ((close_delay != acm->port.close_delay) || + (closing_wait != acm->port.closing_wait)) retval = -EPERM ;else retval = -EOPNOTSUPP ;
Signature · 1 line
2.26.3
PATCH 1/3 Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL"
Quoted 3 lines · Johan Hovold
With HZ=250, the default 0.5 second value of
close_delayis converted to 125 jiffies when set and is converted back to 50 centiseconds by TIOCGSERIAL as expected (not 12 cs as was claimed).
It was "12" (instead of 50) because the conversion gor TIOCGSERIAL was initially broken, and that was fixed in the previous commit 633e2b2ded739a34bd0fb1d8b5b871f7e489ea29
Quoted 4 lines
For completeness: With different default values for these parameters or with a HZ value not divisible by two, the lack of rounding when setting the default values in
tty_port_init()could result in an-EPERMbeing returned, but this is hardly something we need to worry about.
The -EPERM is harmful when a regular user wants to update other members of serial_struct without changing the close delays, e.g. ASYNC_LOW_LATENCY, which is granted to regular users.
Best,
Anthony
Re: [PATCH 1/3] Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL"
Quoted 8 lines · Anthony Mallet
Quoted 3 lines · Johan Hovold
With HZ=250, the default 0.5 second value of
close_delayis converted to 125 jiffies when set and is converted back to 50 centiseconds by TIOCGSERIAL as expected (not 12 cs as was claimed).It was "12" (instead of 50) because the conversion gor TIOCGSERIAL was initially broken, and that was fixed in the previous commit
633e2b2ded739a34bd0fb1d8b5b871f7e489ea29
Right, so this patch is still just broken. The missing jiffies conversion had already been added.
Quoted 8 lines
Quoted 4 lines
For completeness: With different default values for these parameters or with a HZ value not divisible by two, the lack of rounding when setting the default values in
tty_port_init()could result in an-EPERMbeing returned, but this is hardly something we need to worry about.The
-EPERMis harmful when a regular user wants to update other members ofserial_structwithout changing the close delays, e.g.ASYNC_LOW_LATENCY, which is granted to regular users.
You're missing the point; -EPERM will *not* be returned -- and this patch was never needed.
Johan
PATCH 2/3 USB: cdc-acm: fix unprivileged TIOCCSERIAL
In reply to Johan HovoldTIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
A non-privileged user has only ever been able to set the since long deprecated ASYNC_SPD flags and trying to change any other *supported* feature should result in -EPERM being returned. Setting the current values for any supported features should return success.
Fix the cdc-acm implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
--- drivers/usb/class/cdc-acm.c | 2 -- 1 file changed, 2 deletions(-)
drivers/usb/class/cdc-acm.c +0 -2
@@ -955,8 +955,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)if ((close_delay != acm->port.close_delay) || (closing_wait != acm->port.closing_wait)) retval = -EPERM ; -else - retval = -EOPNOTSUPP ; }else { acm->port.close_delay = close_delay; acm->port.closing_wait = closing_wait;
Signature · 1 line
2.26.3
Oliver Neukum
maintainerRe: [PATCH 2/3] USB: cdc-acm: fix unprivileged TIOCCSERIAL
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Quoted 4 lines
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the
close_delayandclosing_waitparameters.
Quoted 8 lines
A non-privileged user has only ever been able to set the since long deprecated
ASYNC_SPDflags and trying to change any other *supported* feature should result in-EPERMbeing returned. Setting the current values for any supported features should return success.Fix the cdc-acm implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
Hi,
the idea here was that you are setting something else, if you are not changing a parameter that can be changed. That conclusion is dubious, but at the same time, this implementation can change only these two parameters. So can the test really be dropped as opposed to be modified?
Regards
Oliver
Re: [PATCH 2/3] USB: cdc-acm: fix unprivileged TIOCCSERIAL
Quoted 14 lines · Oliver Neukum
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Quoted 4 lines
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the
close_delayandclosing_waitparameters.Quoted 8 lines
A non-privileged user has only ever been able to set the since long deprecated
ASYNC_SPDflags and trying to change any other *supported* feature should result in-EPERMbeing returned. Setting the current values for any supported features should return success.Fix the cdc-acm implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
Quoted 7 lines
Hi,
the idea here was that you are setting something else, if you are not changing a parameter that can be changed. That conclusion is dubious, but at the same time, this implementation can change only these two parameters. So can the test really be dropped as opposed to be modified?
The de-facto standard for how to handle change requests for non-supported features (e.g. changing the I/O port or IRQ) is to simply ignore them and return 0.
For most (non-legacy) serial devices the only relevant parameters are close_delay and closing_wait. And as we need to return -EPERM when a non-privileged user tries to change these, we cannot drop the test.
(And returning -EOPNOTSUPP was never correct as the ioctl is indeed supported.)
Johan
Oliver Neukum
maintainerRe: [PATCH 2/3] USB: cdc-acm: fix unprivileged TIOCCSERIAL
Am Donnerstag, den 08.04.2021, 11:42 +0200 schrieb Johan Hovold:
Quoted 27 lines · Oliver Neukum
Quoted 14 lines
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Quoted 4 lines
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the
close_delayandclosing_waitparameters.Quoted 8 lines
A non-privileged user has only ever been able to set the since long deprecated
ASYNC_SPDflags and trying to change any other *supported* feature should result in-EPERMbeing returned. Setting the current values for any supported features should return success.Fix the cdc-acm implementation which instead indicated that the TIOCSSERIAL ioctl was not even implemented when a non-privileged user set the current values.
Quoted 7 lines
Hi,
the idea here was that you are setting something else, if you are not changing a parameter that can be changed. That conclusion is dubious, but at the same time, this implementation can change only these two parameters. So can the test really be dropped as opposed to be modified?
The de-facto standard for how to handle change requests for non-supported features (e.g. changing the I/O port or IRQ) is to simply ignore them and return 0.
Quoted 6 lines
For most (non-legacy) serial devices the only relevant parameters are
close_delayandclosing_wait. And as we need to return-EPERMwhen a non-privileged user tries to change these, we cannot drop the test.(And returning
-EOPNOTSUPPwas never correct as the ioctl is indeed supported.)
OK, thanks for clarification. Yes the fix makes sense.
Regards
Oliver
PATCH 3/3 USB: cdc-acm: fix TIOCGSERIAL implementation
In reply to Johan HovoldTIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the close_delay and closing_wait parameters.
The xmit_fifo_size parameter could be used to set the hardware transmit fifo size of a legacy UART when it could not be detected, but the interface is limited to eight bits and should be left unset when it is not used.
Similarly, baud_base could be used to set the uart base clock when it could not be detected, but might as well be left unset when it is not known.
Fix the cdc-acm TIOCGSERIAL implementation by dropping its custom interpretation of the unused xmit_fifo_size and baud_base fields, which overflowed the former with the URB buffer size and set the latter to the current line speed. Also return the port line number, which is the only other value used besides the close parameters.
--- drivers/usb/class/cdc-acm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/usb/class/cdc-acm.c +1 -2
@@ -929,8 +929,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) {struct acm *acm = tty->driver_data; - ss->xmit_fifo_size = acm->writesize; - ss->baud_base =le32_to_cpu (acm->line.dwDTERate); + ss->line = acm->minor; ss->close_delay =jiffies_to_msecs (acm->port.close_delay) /10 ; ss->closing_wait = acm->port.closing_wait ==ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE :
Signature · 1 line
2.26.3
Oliver Neukum
maintainerRe: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Quoted 8 lines
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the
close_delayandclosing_waitparameters.The
xmit_fifo_sizeparameter could be used to set the hardware transmit fifo size of a legacy UART when it could not be detected, but the interface is limited to eight bits and should be left unset when it is not used.
OK.
Quoted 3 lines
Similarly,
baud_basecould be used to set the uart base clock when it could not be detected, but might as well be left unset when it is not known.
Well, the devices report it. It is part of the standard.
Quoted 17 lines
Fix the cdc-acm TIOCGSERIAL implementation by dropping its custom interpretation of the unused
xmit_fifo_sizeandbaud_basefields, which overflowed the former with the URB buffer size and set the latter to the current line speed. Also return the port line number, which is the only other value used besides the close parameters.Fixes 18c75720e667 ("USB: allow users to run setserial with cdc-acm")Signed-off-by Johan Hovold <[email protected]>--- drivers/usb/class/cdc-acm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/usb/class/cdc-acm.c +0
-0
drivers/usb/class/cdc-acm.c static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) · line 933
Quoted 5 lines
drivers/usb/class/cdc-acm.c +0
-2@@ -929,8 +929,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) {struct acm *acm = tty->driver_data; - ss->xmit_fifo_size = acm->writesize; - ss->baud_base =le32_to_cpu (acm->line.dwDTERate);
If we do this, we have a value that can be set, but is not reported. That looks a bit strange to me.
Regards
Oliver
Re: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Quoted 10 lines · Oliver Neukum
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Quoted 8 lines
TIOCSSERIAL is a horrid, underspecified, legacy interface which for most serial devices is only useful for setting the
close_delayandclosing_waitparameters.The
xmit_fifo_sizeparameter could be used to set the hardware transmit fifo size of a legacy UART when it could not be detected, but the interface is limited to eight bits and should be left unset when it is not used.
Quoted 7 lines
OK.
Quoted 3 lines
Similarly,
baud_basecould be used to set the uart base clock when it could not be detected, but might as well be left unset when it is not known.Well, the devices report it. It is part of the standard.
No, the standard doesn't include anything about a baud-base clock AFAICT.
Quoted 20 lines
Quoted 20 lines
Fix the cdc-acm TIOCGSERIAL implementation by dropping its custom interpretation of the unused
xmit_fifo_sizeandbaud_basefields, which overflowed the former with the URB buffer size and set the latter to the current line speed. Also return the port line number, which is the only other value used besides the close parameters.Fixes 18c75720e667 ("USB: allow users to run setserial with cdc-acm")Signed-off-by Johan Hovold <[email protected]>--- drivers/usb/class/cdc-acm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)drivers/usb/class/cdc-acm.c +0
-0@@ -929,8 +929,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) {struct acm *acm = tty->driver_data;
Quoted 5 lines
drivers/usb/class/cdc-acm.c static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) · line 933
Quoted 2 lines
drivers/usb/class/cdc-acm.c +0
-2- ss->xmit_fifo_size = acm->writesize; - ss->baud_base =le32_to_cpu (acm->line.dwDTERate);If we do this, we have a value that can be set, but is not reported. That looks a bit strange to me.
Again, no, the baud_base cannot be set and it is unknown and unused.
The only reason to report back baud_base is to support the deprecated ASYNC_SPD_CUST interface used to set a custom divisor. cdc-acm has never supported that for obvious reasons.
Johan
Oliver Neukum
maintainerRe: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Am Donnerstag, den 08.04.2021, 11:48 +0200 schrieb Johan Hovold:
Quoted 7 lines · Oliver Neukum
Quoted 3 lines
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Well, the devices report it. It is part of the standard.
No, the standard doesn't include anything about a baud-base clock AFAICT.
Unfortunately it does.
dwDTERate - chapter 6.3.11 - table 17
If we does this wrongly, we should certainly fix it, but just removing the reporting doesn't look right to me.
Regards
Oliver
Re: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Quoted 11 lines · Oliver Neukum
Am Donnerstag, den 08.04.2021, 11:48 +0200 schrieb Johan Hovold:
Quoted 7 lines · Oliver Neukum
Quoted 3 lines
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Well, the devices report it. It is part of the standard.
No, the standard doesn't include anything about a baud-base clock AFAICT.
Unfortunately it does.
dwDTERate - chapter 6.3.11 - table 17
That's not the base clock rate, that's just the currently configured line speed which you can read from termios.
Quoted 2 lines
If we does this wrongly, we should certainly fix it, but just removing the reporting doesn't look right to me.
The driver got its interpretation of baud_base wrong, and CDC doesn't even have a concept of base clock rate so removing it is the right thing to do.
Again, baud_base is really only relevant with legacy UARTs and when using the deprecated ASYNC_SPD_CUST.
And if the user wants to knows the current line speed we have a different interface for that.
Johan
Oliver Neukum
maintainerRe: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Am Donnerstag, den 08.04.2021, 13:54 +0200 schrieb Johan Hovold:
Quoted 21 lines · Oliver Neukum
Quoted 10 lines
Am Donnerstag, den 08.04.2021, 11:48 +0200 schrieb Johan Hovold:
Quoted 6 lines · Oliver Neukum
Quoted 2 lines
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Well, the devices report it. It is part of the standard.No, the standard doesn't include anything about a baud-base clock AFAICT.
Unfortunately it does.
dwDTERate - chapter 6.3.11 - table 17That's not the base clock rate, that's just the currently configured line speed which you can read from termios
Quoted 2 lines
If we does this wrongly, we should certainly fix it, but just removing the reporting doesn't look right to me.
The driver got its interpretation of
baud_basewrong, and CDC doesn't even have a concept of base clock rate so removing it is the right thing to do.
Quoted 5 lines
Again,
baud_baseis really only relevant with legacy UARTs and when using the deprecatedASYNC_SPD_CUST.And if the user wants to knows the current line speed we have a different interface for that.
Hi,
thank you, that clarifies things. I am happy with the patch itself, but could I ask you to do two things:
1. Edit the commit description
making clear that the difference
between the base clock rate and the line speed.
2. Mark the patch specially to NOT be included in stable. We may have
users misusing the current API.
Regards
Oliver
Greg Kroah-Hartman
maintainerRe: [PATCH 3/3] USB: cdc-acm: fix TIOCGSERIAL implementation
Quoted 33 lines · Oliver Neukum
Am Donnerstag, den 08.04.2021, 13:54 +0200 schrieb Johan Hovold:
Quoted 21 lines · Oliver Neukum
Quoted 10 lines
Am Donnerstag, den 08.04.2021, 11:48 +0200 schrieb Johan Hovold:
Quoted 6 lines · Oliver Neukum
Quoted 2 lines
Am Mittwoch, den 07.04.2021, 12:28 +0200 schrieb Johan Hovold:
Well, the devices report it. It is part of the standard.No, the standard doesn't include anything about a baud-base clock AFAICT.
Unfortunately it does.
dwDTERate - chapter 6.3.11 - table 17That's not the base clock rate, that's just the currently configured line speed which you can read from termios
Quoted 2 lines
If we does this wrongly, we should certainly fix it, but just removing the reporting doesn't look right to me.
The driver got its interpretation of
baud_basewrong, and CDC doesn't even have a concept of base clock rate so removing it is the right thing to do.Quoted 5 lines
Again,
baud_baseis really only relevant with legacy UARTs and when using the deprecatedASYNC_SPD_CUST.And if the user wants to knows the current line speed we have a different interface for that.
Hi,
thank you, that clarifies things. I am happy with the patch itself, but could I ask you to do two things:
Quoted 7 lines
1. Edit the commit description
making clear that the difference
between the base clock rate and the line speed.2. Mark the patch specially to NOT be included in stable. We may have
users misusing the current API.
That doesn't matter, if there are misusers then their use will "break" on newer kernels. And if so, then it doesn't deserve to be in any release.
If a change is good enough for Linus's tree, that means it is good enough for a stable tree, the requirements are exactly the same when it comes to userspace interactions.
thanks,
greg k-h