diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-09-06 15:51:00 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2019-09-11 16:46:55 +0000 |
commit | 0e02771e5cb185d8939930e65cc6e63ca226b6f7 (patch) | |
tree | 4d80af8261f67ba7e56b54dde5c627b20ec2e6b2 /src/mm-filter.c | |
parent | 2a8d20292abc55f28cc8b1d8218513626878a7d8 (diff) |
filter: require >1 port in devices with AT-capable ttyACMs
Instead of blindly allowing to be probed all ttyACM ports that report
them as AT-capable, we will now instead forbid all ttyACM ports that
don't report themselves as AT-capable.
Also, require the modem to expose other additional ports (of any kind
usable by ModemManager) in addition to the AT-capable ttyACM port.
This update should avoid automatically probing Arduino devices that
wrongly report their exposed single ttyACM port as AT-capable.
https://github.com/arduino/ArduinoCore-avr/pull/92
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/140
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/127
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930264
Diffstat (limited to 'src/mm-filter.c')
-rw-r--r-- | src/mm-filter.c | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/src/mm-filter.c b/src/mm-filter.c index 9a22cdd4..3695fa9a 100644 --- a/src/mm-filter.c +++ b/src/mm-filter.c @@ -172,7 +172,13 @@ mm_filter_port (MMFilter *self, } /* - * If the TTY kernel driver is cdc-acm and the interface is class=2/subclass=2/protocol=[1-6], allow it. + * If the TTY kernel driver is cdc-acm and the interface is not + * class=2/subclass=2/protocol=[1-6], forbidden. + * + * Otherwise, we'll require the modem to have more ports other + * than the ttyACM one (see mm_filter_device_and_port()), because + * there are lots of Arduino devices out there exposing a single + * ttyACM port and wrongly claiming AT protocol support... * * Class definitions for Communication Devices 1.2 * Communications Interface Class Control Protocol Codes: @@ -190,11 +196,12 @@ mm_filter_port (MMFilter *self, */ if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_ACM_INTERFACE) && (!g_strcmp0 (driver, "cdc_acm")) && - (mm_kernel_device_get_interface_class (port) == 2) && - (mm_kernel_device_get_interface_subclass (port) == 2) && - (mm_kernel_device_get_interface_protocol (port) >= 1) && (mm_kernel_device_get_interface_protocol (port) <= 6)) { - mm_dbg ("[filter] (%s/%s): port allowed: cdc-acm interface reported AT-capable", subsystem, name); - return TRUE; + ((mm_kernel_device_get_interface_class (port) != 2) || + (mm_kernel_device_get_interface_subclass (port) != 2) || + (mm_kernel_device_get_interface_protocol (port) < 1) || + (mm_kernel_device_get_interface_protocol (port) > 6))) { + mm_dbg ("[filter] (%s/%s): port filtered: cdc-acm interface is not AT-capable", subsystem, name); + return FALSE; } /* Default forbidden? flag the port as maybe-forbidden, and go on */ @@ -213,6 +220,24 @@ mm_filter_port (MMFilter *self, /*****************************************************************************/ +static gboolean +device_has_net_port (MMDevice *device) +{ + GList *l; + + for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) { + if (!g_strcmp0 (mm_port_probe_get_port_subsys (MM_PORT_PROBE (l->data)), "net")) + return TRUE; + } + return FALSE; +} + +static gboolean +device_has_multiple_ports (MMDevice *device) +{ + return (g_list_length (mm_device_peek_port_probe_list (device)) > 1); +} + gboolean mm_filter_device_and_port (MMFilter *self, MMDevice *device, @@ -220,6 +245,7 @@ mm_filter_device_and_port (MMFilter *self, { const gchar *subsystem; const gchar *name; + const gchar *driver; /* If it wasn't flagged as maybe forbidden, there's nothing to do */ if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (port), FILTER_PORT_MAYBE_FORBIDDEN))) @@ -229,16 +255,19 @@ mm_filter_device_and_port (MMFilter *self, name = mm_kernel_device_get_name (port); /* Check whether this device holds a NET port in addition to this TTY */ - if (self->priv->enabled_rules & MM_FILTER_RULE_TTY_WITH_NET) { - GList *l; + if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_WITH_NET) && + device_has_net_port (device)) { + mm_dbg ("[filter] (%s/%s): port allowed: device also exports a net interface", subsystem, name); + return TRUE; + } - for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) { - if (!g_strcmp0 (mm_port_probe_get_port_subsys (MM_PORT_PROBE (l->data)), "net")) { - mm_dbg ("[filter] (%s/%s): port allowed: device also exports a net interface (%s)", - subsystem, name, mm_port_probe_get_port_name (MM_PORT_PROBE (l->data))); - return TRUE; - } - } + /* Check whether this device holds any other port in addition to the ttyACM port */ + driver = mm_kernel_device_get_driver (port); + if ((self->priv->enabled_rules & MM_FILTER_RULE_TTY_ACM_INTERFACE) && + (!g_strcmp0 (driver, "cdc_acm")) && + device_has_multiple_ports (device)) { + mm_dbg ("[filter] (%s/%s): port allowed: device exports multiple interfaces", subsystem, name); + return TRUE; } mm_dbg ("[filter] (%s/%s) port filtered: forbidden", subsystem, name); |