From: Matteo Croce <mcroce(a)microsoft.com>
The parsing of the reboot= cmdline has two major errors:
- a missing bound check can crash the system on reboot
- parsing of the cpu number only works if specified last
Fix both, along with a small code refactor.
Matteo Croce (2):
reboot: fix overflow parsing reboot cpu number
reboot: fix parsing of reboot cpu number
kernel/reboot.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
--
2.26.2
The console part of sisusbvga is broken vs. printk(). It uses in_atomic()
to detect contexts in which it cannot sleep despite the big fat comment in
preempt.h which says: Do not use in_atomic() in driver code.
in_atomic() does not work on kernels with CONFIG_PREEMPT_COUNT=n which
means that spin/rw_lock held regions are not detected by it.
There is no way to make this work by handing context information through to
the driver and this only can be solved once the core printk infrastructure
supports sleepable console drivers.
Make it depend on BROKEN for now.
Fixes: 1bbb4f2035d9 ("[PATCH] USB: sisusb[vga] update")
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Thomas Winischhofer <thomas(a)winischhofer.net>
Cc: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Cc: linux-usb(a)vger.kernel.org
Cc: stable(a)vger.kernel.org
---
drivers/usb/misc/sisusbvga/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/misc/sisusbvga/Kconfig
+++ b/drivers/usb/misc/sisusbvga/Kconfig
@@ -16,7 +16,7 @@ config USB_SISUSBVGA
config USB_SISUSBVGA_CON
bool "Text console and mode switching support" if USB_SISUSBVGA
- depends on VT
+ depends on VT && BROKEN
select FONT_8x16
help
Say Y here if you want a VGA text console via the USB dongle or
Use 'strlen' of the string, add one for NUL terminator and simply do
'copy_to_user' instead of the explicit 'for' loop. This makes the
KDGKBSENT case more compact.
The only thing we need to take care about is NULL 'func_table[i]'. Use
an empty string in that case.
The original check for overflow could never trigger as the func_buf
strings are always shorter or equal to 'struct kbsentry's.
Signed-off-by: Jiri Slaby <jslaby(a)suse.cz>
Cc: <stable(a)vger.kernel.org>
---
[v2] Removed the need for "reorder user buffer handling in
vt_do_kdgkb_ioctl" patch.
drivers/tty/vt/keyboard.c | 28 +++++++++-------------------
1 file changed, 9 insertions(+), 19 deletions(-)
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 0db53b5b3acf..7bfa95c3252c 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1995,9 +1995,7 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
struct kbsentry *kbs;
- char *p;
u_char *q;
- u_char __user *up;
int sz, fnw_sz;
int delta;
char *first_free, *fj, *fnw;
@@ -2023,23 +2021,15 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
switch (cmd) {
- case KDGKBSENT:
- sz = sizeof(kbs->kb_string) - 1; /* sz should have been
- a struct member */
- up = user_kdgkb->kb_string;
- p = func_table[i];
- if(p)
- for ( ; *p && sz; p++, sz--)
- if (put_user(*p, up++)) {
- ret = -EFAULT;
- goto reterr;
- }
- if (put_user('\0', up)) {
- ret = -EFAULT;
- goto reterr;
- }
- kfree(kbs);
- return ((p && *p) ? -EOVERFLOW : 0);
+ case KDGKBSENT: {
+ /* size should have been a struct member */
+ unsigned char *from = func_table[i] ? : "";
+
+ ret = copy_to_user(user_kdgkb->kb_string, from,
+ strlen(from) + 1) ? -EFAULT : 0;
+
+ goto reterr;
+ }
case KDSKBSENT:
if (!perm) {
ret = -EPERM;
--
2.28.0
If linux is running as a guest and the host is doing igd pass-through
with VT-d enabled, this message is logged dozens of times per second.
Cc: stable(a)vger.kernel.org
Signed-off-by: Stefan Fritsch <sf(a)sfritsch.de>
---
The i915 driver should also detect VT-d in this case, but that is a
different issue. I have sent a separate mail with subject 'Detecting
Vt-d when running as guest os'.
drivers/gpu/drm/i915/i915_irq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 759f523c6a6b..29096634e697 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2337,7 +2337,7 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv);
if (fault_errors)
- drm_err(&dev_priv->drm,
+ drm_err_ratelimited(&dev_priv->drm,
"Fault errors on pipe %c: 0x%08x\n",
pipe_name(pipe),
fault_errors);
--
2.28.0
On Sun, Oct 18, 2020 at 12:23:14PM +0000, Barnabás Pőcze wrote:
>> [...]
>> > > > > > +static int i2c_hid_polling_thread(void *i2c_hid)
>> > > > > > +{
>> > > > > >
>> > > > > > - struct i2c_hid *ihid = i2c_hid;
>> > > > > > - struct i2c_client *client = ihid->client;
>> > > > > > - unsigned int polling_interval_idle;
>> > > > > > -
>> > > > > > - while (1) {
>> > > > > > - /*
>> > > > > >
>> > > > > >
>> > > > > > - * re-calculate polling_interval_idle
>> > > > > >
>> > > > > >
>> > > > > > - * so the module parameters polling_interval_idle_ms can be
>> > > > > >
>> > > > > >
>> > > > > > - * changed dynamically through sysfs as polling_interval_active_us
>> > > > > >
>> > > > > >
>> > > > > > - */
>> > > > > >
>> > > > > >
>> > > > > > - polling_interval_idle = polling_interval_idle_ms * 1000;
>> > > > > >
>> > > > > >
>> > > > > > - if (test_bit(I2C_HID_READ_PENDING, &ihid->flags))
>> > > > > >
>> > > > > >
>> > > > > > - usleep_range(50000, 100000);
>> > > > > >
>> > > > > >
>> > > > > > -
>> > > > > > - if (kthread_should_stop())
>> > > > > >
>> > > > > >
>> > > > > > - break;
>> > > > > >
>> > > > > >
>> > > > > > -
>> > > > > > - while (interrupt_line_active(client)) {
>> > > > > >
>> > > > > >
>> > > > >
>> > > > > I realize it's quite unlikely, but can't this be a endless loop if data is coming
>> > > > > in at a high enough rate? Maybe the maximum number of iterations could be limited here?
>> > > >
>> > > > If we find HID reports are constantly read and send to front-end
>> > > > application like libinput, won't it help expose the problem of the I2C
>> > > > HiD device?
>> > > >
>> > > > >
>> > >
>> > > I'm not sure I completely understand your point. The reason why I wrote what I wrote
>> > > is that this kthread could potentially could go on forever (since `kthread_should_stop()`
>> > > is not checked in the inner while loop) if the data is supplied at a high enough rate.
>> > > That's why I said, to avoid this problem, only allow a certain number of iterations
>> > > for the inner loop, to guarantee that the kthread can stop in any case.
>> >
>> > I mean if "data is supplied at a high enough rate" does happen, this is
>> > an abnormal case and indicates a bug. So we shouldn't cover it up. We
>> > expect the user to report it to us.
>> >
>> > >
>>
>> I agree in principle, but if this abnormal case ever occurs, that'll prevent
>> this module from being unloaded since `kthread_stop()` will hang because the
>> thread is "stuck" in the inner loop, never checking `kthread_should_stop()`.
>> That's why I think it makes sense to only allow a certain number of operations
>> for the inner loop, and maybe show a warning if that's exceeded:
>>
>> for (i = 0; i < max_iter && interrupt_line_active(...); i++) {
>> ....
>> }
>>
>> WARN_ON[CE](i == max_iter[, "data is coming in at an unreasonably high rate"]);
>>
>
>I now realize that WARN_ON[CE] is probably not the best fit here, `hid_warn()` is possibly better.
>
Thank you for the suggestion!
>
>> or something like this, where `max_iter` could possibly be some value dependent on
>> `polling_interval_active_us`, or even just a constant.
>> [...]
>
>
>Regards,
>Barnabás Pőcze
--
Best regards,
Coiby
On Sat, Oct 17, 2020 at 02:58:13PM +0000, Barnabás Pőcze wrote:
>> [...]
>> >> >> +static int get_gpio_pin_state(struct irq_desc *irq_desc)
>> >> >> +{
>> >> >> + struct gpio_chip *gc = irq_data_get_irq_chip_data(&irq_desc->irq_data);
>> >> >> +
>> >> >> + return gc->get(gc, irq_desc->irq_data.hwirq);
>> >> >> +}
>> >> >> +
>> >> >> +static bool interrupt_line_active(struct i2c_client *client)
>> >> >> +{
>> >> >> + unsigned long trigger_type = irq_get_trigger_type(client->irq);
>> >> >> + struct irq_desc *irq_desc = irq_to_desc(client->irq);
>> >> >> +
>> >> >> + /*
>> >> >> + * According to Windows Precsiontion Touchpad's specs
>> >> >> + * https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelin…,
>> >> >> + * GPIO Interrupt Assertion Leve could be either ActiveLow or
>> >> >> + * ActiveHigh.
>> >> >> + */
>> >> >> + if (trigger_type & IRQF_TRIGGER_LOW)
>> >> >> + return !get_gpio_pin_state(irq_desc);
>> >> >> +
>> >> >> + return get_gpio_pin_state(irq_desc);
>> >> >> +}
>> >> >
>> >> >Excuse my ignorance, but I think some kind of error handling regarding the return
>> >> >value of `get_gpio_pin_state()` should be present here.
>> >> >
>> >> What kind of errors would you expect? It seems (struct gpio_chip *)->get
>> >> only return 0 or 1.
>> >> >
>> >
>> >I read the code of a couple gpio chips and - I may be wrong, but - it seems they
>> >can return an arbitrary errno.
>> >
>> I thought all GPIO chip return 0 or 1 since !!val is returned. I find
>> an example which could return negative value,
>>
>
>Yes, when a function returns `int`, there is a very high chance that the return
>value may be an errno.
>
>
>> >
>> >> >> +
>> >> >> +static int i2c_hid_polling_thread(void *i2c_hid)
>> >> >> +{
>> >> >> + struct i2c_hid *ihid = i2c_hid;
>> >> >> + struct i2c_client *client = ihid->client;
>> >> >> + unsigned int polling_interval_idle;
>> >> >> +
>> >> >> + while (1) {
>> >> >> + /*
>> >> >> + * re-calculate polling_interval_idle
>> >> >> + * so the module parameters polling_interval_idle_ms can be
>> >> >> + * changed dynamically through sysfs as polling_interval_active_us
>> >> >> + */
>> >> >> + polling_interval_idle = polling_interval_idle_ms * 1000;
>> >> >> + if (test_bit(I2C_HID_READ_PENDING, &ihid->flags))
>> >> >> + usleep_range(50000, 100000);
>> >> >> +
>> >> >> + if (kthread_should_stop())
>> >> >> + break;
>> >> >> +
>> >> >> + while (interrupt_line_active(client)) {
>> >> >
>> >> >I realize it's quite unlikely, but can't this be a endless loop if data is coming
>> >> >in at a high enough rate? Maybe the maximum number of iterations could be limited here?
>> >> >
>> >> If we find HID reports are constantly read and send to front-end
>> >> application like libinput, won't it help expose the problem of the I2C
>> >> HiD device?
>> >> >
>> >
>> >I'm not sure I completely understand your point. The reason why I wrote what I wrote
>> >is that this kthread could potentially could go on forever (since `kthread_should_stop()`
>> >is not checked in the inner while loop) if the data is supplied at a high enough rate.
>> >That's why I said, to avoid this problem, only allow a certain number of iterations
>> >for the inner loop, to guarantee that the kthread can stop in any case.
>> >
>> I mean if "data is supplied at a high enough rate" does happen, this is
>> an abnormal case and indicates a bug. So we shouldn't cover it up. We
>> expect the user to report it to us.
>> >
>
>I agree in principle, but if this abnormal case ever occurs, that'll prevent
>this module from being unloaded since `kthread_stop()` will hang because the
>thread is "stuck" in the inner loop, never checking `kthread_should_stop()`.
>That's why I think it makes sense to only allow a certain number of operations
>for the inner loop, and maybe show a warning if that's exceeded:
>
> for (i = 0; i < max_iter && interrupt_line_active(...); i++) {
> ....
> }
>
> WARN_ON[CE](i == max_iter[, "data is coming in at an unreasonably high rate"]);
>
>or something like this, where `max_iter` could possibly be some value dependent on
>`polling_interval_active_us`, or even just a constant.
>
Thank you for suggesting this approach! It seems it would add a bit of
complexity to detect this situation which could introduce other bugs.
I did a experiment of creating a kthread that will loop forever and found
the rebooting process wasn't stalled. I don't expect user to load&unload
this module. So the end user could not notice this problem so my rationale
is invalid.
Thus I would be prefer to check `kthread_should_stop()` in the inner
while loop instead.
>
>> >> >> + i2c_hid_get_input(ihid);
>> >> >> + usleep_range(polling_interval_active_us,
>> >> >> + polling_interval_active_us + 100);
>> >> >> + }
>> >> >> +
>> >> >> + usleep_range(polling_interval_idle,
>> >> >> + polling_interval_idle + 1000);
>> >> >> + }
>> >> >> +
>> >> >> + do_exit(0);
>> >> >> + return 0;
>> >> >> +}
>> [...]
>> Thank you for offering your understandings on this patch. When I'm going
>> to submit next version, I will add a "Signed-off-by" tag with your name
>> and email, does it look good to you?
>> [...]
>
>I'm not sure if that follows proper procedures.
>
> "The sign-off is a simple line at the end of the explanation for the patch, which
> certifies that you wrote it or otherwise have the right to pass it on as an
> open-source patch."[1]
>
>I'm not the author, nor co-author, nor am I going to pass this patch on, so I don't
>think that's appropriate.
>
>Furthermore, please note that
>
> "[...] you may optionally add a Cc: tag to the patch. **This is the only tag which
> might be added without an explicit action by the person it names** - but it should
> indicate that this person was copied on the patch."[2]
> (emphasis mine)
>
You have been directly contributing to this patch because several
improvements of next version are from you. I experienced a similar
situation when submitting patches for QEMU. The only difference is
that the feedbacks on the QEMU patches were also given in the format
of patch. Or do you think a reviewed-by tag from you after you think
the next version is of production quality is a better way to credit
you?
>
>Regards,
>Barnabás Pőcze
>
>
>[1]: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign…
>[2]: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when…
--
Best regards,
Coiby