Skip to content

Commit

Permalink
tx_hook shall have a white-list of messages (#381)
Browse files Browse the repository at this point in the history
* Started whitelisting messages

* Also toyota and cadilalc fix

* bug fixes and better checks. Need to figure out a solution for honda

* Whitelist also for subaru

* Added Chrysler as well to whitelist

* And Hyundai too

* now all supported cars should have a whitelist of messages

* Fix linter

* This should fix process replay

* Honda too is now whitelisted

* struct typedef

* Had forgot GM

* had a wrong addr for GM whitelist

* This should fix all the tests

* bump panda
  • Loading branch information
rbiasini committed Nov 17, 2019
1 parent 8138fc1 commit 6249a18
Show file tree
Hide file tree
Showing 24 changed files with 189 additions and 52 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.6.2
v1.6.3
11 changes: 11 additions & 0 deletions board/safety.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
return current_hooks->fwd(bus_num, to_fwd);
}

bool addr_allowed(int addr, int bus, const AddrBus addr_list[], int len) {
bool allowed = false;
for (int i = 0; i < len; i++) {
if ((addr == addr_list[i].addr) && (bus == addr_list[i].bus)) {
allowed = true;
break;
}
}
return allowed;
}

typedef struct {
uint16_t id;
const safety_hooks *hooks;
Expand Down
6 changes: 6 additions & 0 deletions board/safety/safety_cadillac.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define CADILLAC_TORQUE_MSG_N 4 // 4 torque messages: 0x151, 0x152, 0x153, 0x154

const AddrBus CADILLAC_TX_MSGS[] = {{0x151, 2}, {0x152, 0}, {0x153, 2}, {0x154, 0}};
const int CADILLAC_MAX_STEER = 150; // 1s
// real time torque limit to prevent controls spamming
// the real time limit is 1500/sec
Expand Down Expand Up @@ -55,6 +56,11 @@ static void cadillac_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, CADILLAC_TX_MSGS, sizeof(CADILLAC_TX_MSGS) / sizeof(CADILLAC_TX_MSGS[0]))) {
tx = 0;
}

// steer cmd checks
if ((addr == 0x151) || (addr == 0x152) || (addr == 0x153) || (addr == 0x154)) {
Expand Down
8 changes: 7 additions & 1 deletion board/safety/safety_chrysler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const uint32_t CHRYSLER_RT_INTERVAL = 250000; // 250ms between real time checks
const int CHRYSLER_MAX_RATE_UP = 3;
const int CHRYSLER_MAX_RATE_DOWN = 3;
const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor
const AddrBus CHRYSLER_TX_MSGS[] = {{571, 0}, {658, 0}, {678, 0}};

int chrysler_rt_torque_last = 0;
int chrysler_desired_torque_last = 0;
Expand Down Expand Up @@ -43,8 +44,13 @@ static void chrysler_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {

static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

int addr = GET_ADDR(to_send);
int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, CHRYSLER_TX_MSGS, sizeof(CHRYSLER_TX_MSGS) / sizeof(CHRYSLER_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
Expand Down
35 changes: 19 additions & 16 deletions board/safety/safety_gm.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ const int GM_DRIVER_TORQUE_FACTOR = 4;
const int GM_MAX_GAS = 3072;
const int GM_MAX_REGEN = 1404;
const int GM_MAX_BRAKE = 350;
const AddrBus GM_TX_MSGS[] = {{384, 0}, {1033, 0}, {1034, 0}, {715, 0}, {880, 0}, // pt bus
{161, 1}, {774, 1}, {776, 1}, {784, 1}, // obs bus
{789, 2}, // ch bus
{0x104c006c, 3}, {0x10400060, 3}}; // gmlan

int gm_brake_prev = 0;
int gm_gas_prev = 0;
Expand All @@ -28,7 +32,7 @@ uint32_t gm_ts_last = 0;
struct sample_t gm_torque_driver; // last few driver torques measured

static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus_number = GET_BUS(to_push);
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);

if (addr == 388) {
Expand All @@ -44,14 +48,6 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
gm_moving = GET_BYTE(to_push, 0) | GET_BYTE(to_push, 1);
}

// Check if ASCM or LKA camera are online
// on powertrain bus.
// 384 = ASCMLKASteeringCmd
// 715 = ASCMGasRegenCmd
if ((bus_number == 0) && ((addr == 384) || (addr == 715))) {
relay_malfunction = true;
}

// ACC steering wheel buttons
if (addr == 481) {
int button = (GET_BYTE(to_push, 5) & 0x70) >> 4;
Expand Down Expand Up @@ -99,6 +95,14 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
controls_allowed = 0;
}
}

// Check if ASCM or LKA camera are online
// on powertrain bus.
// 384 = ASCMLKASteeringCmd
// 715 = ASCMGasRegenCmd
if ((bus == 0) && ((addr == 384) || (addr == 715))) {
relay_malfunction = true;
}
}

// all commands: gas/regen, friction brake and steering
Expand All @@ -110,6 +114,12 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, GM_TX_MSGS, sizeof(GM_TX_MSGS)/sizeof(GM_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
Expand All @@ -120,8 +130,6 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int pedal_pressed = gm_gas_prev || (gm_brake_prev && gm_moving);
bool current_controls_allowed = controls_allowed && !pedal_pressed;

int addr = GET_ADDR(to_send);

// BRAKE: safety check
if (addr == 789) {
int brake = ((GET_BYTE(to_send, 0) & 0xFU) << 8) + GET_BYTE(to_send, 1);
Expand Down Expand Up @@ -184,11 +192,6 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
}
}

// PARK ASSIST STEER: unlimited torque, no thanks
if (addr == 823) {
tx = 0;
}

// GAS/REGEN: safety check
if (addr == 715) {
int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
Expand Down
18 changes: 16 additions & 2 deletions board/safety/safety_honda.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
// accel rising edge
// brake rising edge
// brake > 0mph

const AddrBus HONDA_N_TX_MSGS[] = {{0xE4, 0}, {0x194, 0}, {0x1FA, 0}, {0x200, 0}, {0x30C, 0}, {0x33D, 0}, {0x39F, 0}};
const AddrBus HONDA_BH_TX_MSGS[] = {{0xE4, 0}, {0x296, 1}, {0x33D, 0}}; // Bosch Harness
const AddrBus HONDA_BG_TX_MSGS[] = {{0xE4, 2}, {0x296, 0}, {0x33D, 2}}; // Bosch Giraffe
const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 328; // ratio between offset and gain from dbc file
int honda_brake = 0;
int honda_gas_prev = 0;
Expand Down Expand Up @@ -95,7 +97,7 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
} else if (honda_stock_brake >= honda_brake) {
honda_fwd_brake = true;
} else {
// Leave honda forward brake as is
// Leave Honda forward brake as is
}
}

Expand All @@ -122,6 +124,18 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (honda_bosch_hardware) {
if (board_has_relay() && !addr_allowed(addr, bus, HONDA_BH_TX_MSGS, sizeof(HONDA_BH_TX_MSGS)/sizeof(HONDA_BH_TX_MSGS[0]))) {
tx = 0;
}
if (!board_has_relay() && !addr_allowed(addr, bus, HONDA_BG_TX_MSGS, sizeof(HONDA_BG_TX_MSGS)/sizeof(HONDA_BG_TX_MSGS[0]))) {
tx = 0;
}
}
if (!honda_bosch_hardware && !addr_allowed(addr, bus, HONDA_N_TX_MSGS, sizeof(HONDA_N_TX_MSGS)/sizeof(HONDA_N_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
}
Expand Down
7 changes: 7 additions & 0 deletions board/safety/safety_hyundai.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const int HYUNDAI_MAX_RATE_DOWN = 7;
const int HYUNDAI_DRIVER_TORQUE_ALLOWANCE = 50;
const int HYUNDAI_DRIVER_TORQUE_FACTOR = 2;

const AddrBus HYUNDAI_TX_MSGS[] = {{832, 0}, {1265, 0}};

int hyundai_rt_torque_last = 0;
int hyundai_desired_torque_last = 0;
int hyundai_cruise_engaged_last = 0;
Expand Down Expand Up @@ -45,6 +47,11 @@ static int hyundai_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {

int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, HYUNDAI_TX_MSGS, sizeof(HYUNDAI_TX_MSGS)/sizeof(HYUNDAI_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
Expand Down
7 changes: 7 additions & 0 deletions board/safety/safety_subaru.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const int SUBARU_MAX_RATE_DOWN = 70;
const int SUBARU_DRIVER_TORQUE_ALLOWANCE = 60;
const int SUBARU_DRIVER_TORQUE_FACTOR = 10;

const AddrBus SUBARU_TX_MSGS[] = {{0x122, 0}, {0x164, 0}, {0x221, 0}, {0x322, 0}};

int subaru_cruise_engaged_last = 0;
int subaru_rt_torque_last = 0;
int subaru_desired_torque_last = 0;
Expand Down Expand Up @@ -47,6 +49,11 @@ static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
static int subaru_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int tx = 1;
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, SUBARU_TX_MSGS, sizeof(SUBARU_TX_MSGS) / sizeof(SUBARU_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
Expand Down
16 changes: 10 additions & 6 deletions board/safety/safety_toyota.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2

const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and gain from dbc file

// allowed DSU messages on bus 0 and 1
const AddrBus TOYOTA_TX_MSGS[] = {{0x283, 0}, {0x2E6, 0}, {0x2E7, 0}, {0x33E, 0}, {0x344, 0}, {0x365, 0}, {0x366, 0}, {0x4CB, 0}, // DSU bus 0
{0x128, 1}, {0x141, 1}, {0x160, 1}, {0x161, 1}, {0x470, 1}, // DSU bus 1
{0x2E4, 0}, {0x412, 0}, {0x191, 0}, {0x343, 0}, // LKAS + ACC
{0x200, 0}}; // interceptor

// global actuation limit states
int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file

Expand Down Expand Up @@ -97,18 +103,17 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int addr = GET_ADDR(to_send);
int bus = GET_BUS(to_send);

if (!addr_allowed(addr, bus, TOYOTA_TX_MSGS, sizeof(TOYOTA_TX_MSGS)/sizeof(TOYOTA_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
}

// Check if msg is sent on BUS 0
if (bus == 0) {

// no IPAS in non IPAS mode
if ((addr == 0x266) || (addr == 0x167)) {
tx = 0;
}

// GAS PEDAL: safety check
if (addr == 0x200) {
if (!controls_allowed || !long_controls_allowed) {
Expand Down Expand Up @@ -182,7 +187,6 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
}
}

// 1 allows the message through
return tx;
}

Expand Down
24 changes: 15 additions & 9 deletions board/safety/safety_volkswagen.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// Safety-relevant CAN messages for the Volkswagen MQB platform.
#define MSG_EPS_01 0x09F
#define MSG_MOTOR_20 0x121
#define MSG_ACC_06 0x122
#define MSG_HCA_01 0x126
#define MSG_GRA_ACC_01 0x12B
#define MSG_LDW_02 0x397
#define MSG_KLEMMEN_STATUS_01 0x3C0

const int VOLKSWAGEN_MAX_STEER = 250; // 2.5 Nm (EPS side max of 3.0Nm with fault if violated)
const int VOLKSWAGEN_MAX_RT_DELTA = 75; // 4 max rate up * 50Hz send rate * 250000 RT interval / 1000000 = 50 ; 50 * 1.5 for safety pad = 75
const uint32_t VOLKSWAGEN_RT_INTERVAL = 250000; // 250ms between real time checks
Expand All @@ -6,21 +15,14 @@ const int VOLKSWAGEN_MAX_RATE_DOWN = 10; // 5.0 Nm/s available rate o
const int VOLKSWAGEN_DRIVER_TORQUE_ALLOWANCE = 80;
const int VOLKSWAGEN_DRIVER_TORQUE_FACTOR = 3;

const AddrBus VOLKSWAGEN_TX_MSGS[] = {{MSG_HCA_01, 0}, {MSG_GRA_ACC_01, 2}, {MSG_LDW_02, 0}};

struct sample_t volkswagen_torque_driver; // last few driver torques measured
int volkswagen_rt_torque_last = 0;
int volkswagen_desired_torque_last = 0;
uint32_t volkswagen_ts_last = 0;
int volkswagen_gas_prev = 0;

// Safety-relevant CAN messages for the Volkswagen MQB platform.
#define MSG_EPS_01 0x09F
#define MSG_MOTOR_20 0x121
#define MSG_ACC_06 0x122
#define MSG_HCA_01 0x126
#define MSG_GRA_ACC_01 0x12B
#define MSG_LDW_02 0x397
#define MSG_KLEMMEN_STATUS_01 0x3C0

static void volkswagen_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
int bus = GET_BUS(to_push);
int addr = GET_ADDR(to_push);
Expand Down Expand Up @@ -64,6 +66,10 @@ static int volkswagen_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
int bus = GET_BUS(to_send);
int tx = 1;

if (!addr_allowed(addr, bus, VOLKSWAGEN_TX_MSGS, sizeof(VOLKSWAGEN_TX_MSGS)/sizeof(VOLKSWAGEN_TX_MSGS[0]))) {
tx = 0;
}

if (relay_malfunction) {
tx = 0;
}
Expand Down
6 changes: 6 additions & 0 deletions board/safety_declarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ struct lookup_t {
float y[3];
};

typedef struct {
int addr;
int bus;
} AddrBus;

void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push);
int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
int safety_tx_lin_hook(int lin_num, uint8_t *data, int len);
Expand All @@ -25,6 +30,7 @@ bool driver_limit_check(int val, int val_last, struct sample_t *val_driver,
const int MAX_ALLOWANCE, const int DRIVER_FACTOR);
bool rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
float interpolate(struct lookup_t xy, float x);
bool addr_allowed(int addr, int bus, const AddrBus addr_list[], int len);

typedef void (*safety_hook_init)(int16_t param);
typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push);
Expand Down
11 changes: 10 additions & 1 deletion tests/safety/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

def make_msg(bus, addr, length):
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
to_send[0].RIR = addr << 21
if addr >= 0x800:
to_send[0].RIR = (addr << 3) | 5
else:
to_send[0].RIR = (addr << 21) | 1
to_send[0].RDTR = length
to_send[0].RDTR = bus << 4

Expand All @@ -25,3 +28,9 @@ def test_manually_enable_controls_allowed(test):
test.assertTrue(test.safety.get_controls_allowed())
test.safety.set_controls_allowed(0)
test.assertFalse(test.safety.get_controls_allowed())

def test_spam_can_buses(test, TX_MSGS):
for addr in range(1, 0x800):
for bus in range(0, 4):
if all(addr != m[0] or bus != m[1] for m in TX_MSGS):
test.assertFalse(test.safety.safety_tx_hook(make_msg(bus, addr, 8)))
8 changes: 7 additions & 1 deletion tests/safety/test_cadillac.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import numpy as np
from panda import Panda
from panda.tests.safety import libpandasafety_py
from panda.tests.safety.common import make_msg, test_manually_enable_controls_allowed
from panda.tests.safety.common import make_msg, test_manually_enable_controls_allowed, test_spam_can_buses


MAX_RATE_UP = 2
Expand All @@ -18,6 +18,8 @@

IPAS_OVERRIDE_THRESHOLD = 200

TX_MSGS = [[0x151, 2], [0x152, 0], [0x153, 2], [0x154, 0]]

def twos_comp(val, bits):
if val >= 0:
return val
Expand Down Expand Up @@ -52,11 +54,15 @@ def _torque_driver_msg(self, torque):
def _torque_msg(self, torque):
to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *')
to_send[0].RIR = 0x151 << 21
to_send[0].RDTR = 2 << 4

t = twos_comp(torque, 14)
to_send[0].RDLR = ((t >> 8) & 0x3F) | ((t & 0xFF) << 8)
return to_send

def test_spam_can_buses(self):
test_spam_can_buses(self, TX_MSGS)

def test_default_controls_not_allowed(self):
self.assertFalse(self.safety.get_controls_allowed())

Expand Down
Loading

0 comments on commit 6249a18

Please sign in to comment.