diff options
Diffstat (limited to 'drivers/usb/mon/mon_text.c')
-rw-r--r-- | drivers/usb/mon/mon_text.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index ac043ec2b8dc..e02c1a30c4cd 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -26,10 +26,13 @@ | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * This limit exists to prevent OOMs when the user process stops reading. | 28 | * This limit exists to prevent OOMs when the user process stops reading. |
29 | * If usbmon were available to unprivileged processes, it might be open | ||
30 | * to a local DoS. But we have to keep to root in order to prevent | ||
31 | * password sniffing from HID devices. | ||
29 | */ | 32 | */ |
30 | #define EVENT_MAX 25 | 33 | #define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text)) |
31 | 34 | ||
32 | #define PRINTF_DFL 130 | 35 | #define PRINTF_DFL 160 |
33 | 36 | ||
34 | struct mon_event_text { | 37 | struct mon_event_text { |
35 | struct list_head e_link; | 38 | struct list_head e_link; |
@@ -111,7 +114,7 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
111 | * number of corner cases, but it seems that the following is | 114 | * number of corner cases, but it seems that the following is |
112 | * more or less safe. | 115 | * more or less safe. |
113 | * | 116 | * |
114 | * We do not even try to look transfer_buffer, because it can | 117 | * We do not even try to look at transfer_buffer, because it can |
115 | * contain non-NULL garbage in case the upper level promised to | 118 | * contain non-NULL garbage in case the upper level promised to |
116 | * set DMA for the HCD. | 119 | * set DMA for the HCD. |
117 | */ | 120 | */ |
@@ -179,6 +182,32 @@ static void mon_text_complete(void *data, struct urb *urb) | |||
179 | mon_text_event(rp, urb, 'C'); | 182 | mon_text_event(rp, urb, 'C'); |
180 | } | 183 | } |
181 | 184 | ||
185 | static void mon_text_error(void *data, struct urb *urb, int error) | ||
186 | { | ||
187 | struct mon_reader_text *rp = data; | ||
188 | struct mon_event_text *ep; | ||
189 | |||
190 | if (rp->nevents >= EVENT_MAX || | ||
191 | (ep = kmem_cache_alloc(rp->e_slab, SLAB_ATOMIC)) == NULL) { | ||
192 | rp->r.m_bus->cnt_text_lost++; | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | ep->type = 'E'; | ||
197 | ep->pipe = urb->pipe; | ||
198 | ep->id = (unsigned long) urb; | ||
199 | ep->tstamp = 0; | ||
200 | ep->length = 0; | ||
201 | ep->status = error; | ||
202 | |||
203 | ep->setup_flag = '-'; | ||
204 | ep->data_flag = 'E'; | ||
205 | |||
206 | rp->nevents++; | ||
207 | list_add_tail(&ep->e_link, &rp->e_list); | ||
208 | wake_up(&rp->wait); | ||
209 | } | ||
210 | |||
182 | /* | 211 | /* |
183 | * Fetch next event from the circular buffer. | 212 | * Fetch next event from the circular buffer. |
184 | */ | 213 | */ |
@@ -232,6 +261,7 @@ static int mon_text_open(struct inode *inode, struct file *file) | |||
232 | rp->r.m_bus = mbus; | 261 | rp->r.m_bus = mbus; |
233 | rp->r.r_data = rp; | 262 | rp->r.r_data = rp; |
234 | rp->r.rnf_submit = mon_text_submit; | 263 | rp->r.rnf_submit = mon_text_submit; |
264 | rp->r.rnf_error = mon_text_error; | ||
235 | rp->r.rnf_complete = mon_text_complete; | 265 | rp->r.rnf_complete = mon_text_complete; |
236 | 266 | ||
237 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, | 267 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, |