aboutsummaryrefslogtreecommitdiffstats
path: root/net/can/gw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/can/gw.c')
-rw-r--r--net/can/gw.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/net/can/gw.c b/net/can/gw.c
index faa3da88a127..53859346dc9a 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -416,13 +416,29 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
416 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx]) 416 while (modidx < MAX_MODFUNCTIONS && gwj->mod.modfunc[modidx])
417 (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod); 417 (*gwj->mod.modfunc[modidx++])(cf, &gwj->mod);
418 418
419 /* check for checksum updates when the CAN frame has been modified */ 419 /* Has the CAN frame been modified? */
420 if (modidx) { 420 if (modidx) {
421 if (gwj->mod.csumfunc.crc8) 421 /* get available space for the processed CAN frame type */
422 int max_len = nskb->len - offsetof(struct can_frame, data);
423
424 /* dlc may have changed, make sure it fits to the CAN frame */
425 if (cf->can_dlc > max_len)
426 goto out_delete;
427
428 /* check for checksum updates in classic CAN length only */
429 if (gwj->mod.csumfunc.crc8) {
430 if (cf->can_dlc > 8)
431 goto out_delete;
432
422 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8); 433 (*gwj->mod.csumfunc.crc8)(cf, &gwj->mod.csum.crc8);
434 }
435
436 if (gwj->mod.csumfunc.xor) {
437 if (cf->can_dlc > 8)
438 goto out_delete;
423 439
424 if (gwj->mod.csumfunc.xor)
425 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor); 440 (*gwj->mod.csumfunc.xor)(cf, &gwj->mod.csum.xor);
441 }
426 } 442 }
427 443
428 /* clear the skb timestamp if not configured the other way */ 444 /* clear the skb timestamp if not configured the other way */
@@ -434,6 +450,14 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
434 gwj->dropped_frames++; 450 gwj->dropped_frames++;
435 else 451 else
436 gwj->handled_frames++; 452 gwj->handled_frames++;
453
454 return;
455
456 out_delete:
457 /* delete frame due to misconfiguration */
458 gwj->deleted_frames++;
459 kfree_skb(nskb);
460 return;
437} 461}
438 462
439static inline int cgw_register_filter(struct net *net, struct cgw_job *gwj) 463static inline int cgw_register_filter(struct net *net, struct cgw_job *gwj)