summaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.h
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-10-01 14:52:55 +0000
committerKumar Kartikeya Dwivedi <memxor@gmail.com>2026-10-01 18:39:27 +0200
commit33a154a96e71a34a1bcca9f40da343dbbf7b38b4 (patch)
tree543be8029ab3d8a3a63994ae23385a053ed30029 /drivers/usb/class/cdc-acm.h
downloadlinux-stable-33a154a96e71a34a1bcca9f40da343dbbf7b38b4.tar.gz
linux-stable-33a154a96e71a34a1bcca9f40da343dbbf7b38b4.zip
selftests/bpf: Test packet range of pointers sharing an idgrafted
Add tests where two packet pointers share an id and tightening one pointer's umax from its var_off would put it less than their constant distance from the other's umax: with an index & 0x38 capped at 50, the base pointer keeps umax 50, so the pointer 8 bytes further on must keep umax 58, even though its known bits allow at most 56. These refused a valid program or accepted an out-of-bounds access before the fix: - check the advanced copy, load through the base: valid, was refused; - check the base, load the byte at base + 1 through a copy advanced by 8: was accepted; - check base + 4, load 4 bytes at base + 2 through base + 8: reads two bytes past the checked range, was accepted; - the same as the second with data_meta pointers checked against data: was accepted. These pass with and without the fix and cover nearby paths: - subtract an unknown scalar from a checked pointer and load below it (the range is kept across a new id); - reach a load through two paths whose checks cover 8 and 7 bytes after the loaded pointer; the second path must not be pruned by the first; - spill a copy of a pointer, check the pointer, fill the copy and load one byte past the checked range: the load is refused, and the copy has the range of the check. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20261001145255.855630-2-alexei.starovoitov@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'drivers/usb/class/cdc-acm.h')
-rw-r--r--drivers/usb/class/cdc-acm.h119
1 files changed, 119 insertions, 0 deletions
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
new file mode 100644
index 000000000..01f448a78
--- /dev/null
+++ b/drivers/usb/class/cdc-acm.h
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *
+ * Includes for cdc-acm.c
+ *
+ * Mainly take from usbnet's cdc-ether part
+ *
+ */
+
+/*
+ * Major and minor numbers.
+ */
+
+#define ACM_TTY_MAJOR 166
+#define ACM_TTY_MINORS 256
+
+#define ACM_MINOR_INVALID ACM_TTY_MINORS
+
+/*
+ * Requests.
+ */
+
+#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+
+/*
+ * Internal driver structures.
+ */
+
+/*
+ * The only reason to have several buffers is to accommodate assumptions
+ * in line disciplines. They ask for empty space amount, receive our URB size,
+ * and proceed to issue several 1-character writes, assuming they will fit.
+ * The very first write takes a complete URB. Fortunately, this only happens
+ * when processing onlcr, so we only need 2 buffers. These values must be
+ * powers of 2.
+ */
+#define ACM_NW 16
+#define ACM_NR 16
+
+struct acm_wb {
+ u8 *buf;
+ dma_addr_t dmah;
+ unsigned int len;
+ struct urb *urb;
+ struct acm *instance;
+ bool use;
+};
+
+struct acm_rb {
+ int size;
+ unsigned char *base;
+ dma_addr_t dma;
+ int index;
+ struct acm *instance;
+};
+
+struct acm {
+ struct usb_device *dev; /* the corresponding usb device */
+ struct usb_interface *control; /* control interface */
+ struct usb_interface *data; /* data interface */
+ unsigned in, out; /* i/o pipes */
+ struct tty_port port; /* our tty port data */
+ struct urb *ctrlurb; /* urbs */
+ u8 *ctrl_buffer; /* buffers of urbs */
+ dma_addr_t ctrl_dma; /* dma handles of buffers */
+ u8 *country_codes; /* country codes from device */
+ unsigned int country_code_size; /* size of this buffer */
+ unsigned int country_rel_date; /* release date of version */
+ struct acm_wb wb[ACM_NW];
+ unsigned long read_urbs_free;
+ struct urb *read_urbs[ACM_NR];
+ struct acm_rb read_buffers[ACM_NR];
+ int rx_buflimit;
+ spinlock_t read_lock;
+ u8 *notification_buffer; /* to reassemble fragmented notifications */
+ unsigned int nb_index;
+ unsigned int nb_size;
+ int transmitting;
+ spinlock_t write_lock;
+ struct mutex mutex;
+ bool disconnected;
+ unsigned long flags;
+# define EVENT_TTY_WAKEUP 0
+# define EVENT_RX_STALL 1
+# define ACM_THROTTLED 2
+# define ACM_ERROR_DELAY 3
+ unsigned long urbs_in_error_delay; /* these need to be restarted after a delay */
+ struct usb_cdc_line_coding line; /* bits, stop, parity */
+ struct delayed_work dwork; /* work queue entry for various purposes */
+ unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
+ unsigned int ctrlout; /* output control lines (DTR, RTS) */
+ struct async_icount iocount; /* counters for control line changes */
+ struct async_icount oldcount; /* for comparison of counter */
+ wait_queue_head_t wioctl; /* for ioctl */
+ unsigned int writesize; /* max packet size for the output bulk endpoint */
+ unsigned int readsize,ctrlsize; /* buffer sizes for freeing */
+ unsigned int minor; /* acm minor number */
+ unsigned char clocal; /* termios CLOCAL */
+ unsigned int ctrl_caps; /* control capabilities from the class specific header */
+ unsigned int susp_count; /* number of suspended interfaces */
+ unsigned int combined_interfaces:1; /* control and data collapsed */
+ u8 bInterval;
+ struct usb_anchor delayed; /* writes queued for a device about to be woken */
+ unsigned long quirks;
+};
+
+/* constants describing various quirks and errors */
+#define NO_UNION_NORMAL BIT(0)
+#define SINGLE_RX_URB BIT(1)
+#define NO_CAP_LINE BIT(2)
+#define IGNORE_DEVICE BIT(3)
+#define QUIRK_CONTROL_LINE_STATE BIT(4)
+#define CLEAR_HALT_CONDITIONS BIT(5)
+#define SEND_ZERO_PACKET BIT(6)
+#define DISABLE_ECHO BIT(7)
+#define MISSING_CAP_BRK BIT(8)
+#define NO_UNION_12 BIT(9)
+#define VENDOR_CLASS_DATA_IFACE BIT(10) /* data interface uses vendor-specific class */
+#define ALWAYS_POLL_CTRL BIT(11) /* keep ctrl URB active even without an open TTY */