1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
# AF_CAN support.
include <linux/net.h>
include <linux/socket.h>
include <uapi/linux/if.h>
include <uapi/linux/can.h>
include <uapi/linux/can/raw.h>
include <uapi/linux/can/bcm.h>
include <uapi/linux/can/j1939.h>
resource sock_can[sock]
resource sock_can_raw[sock_can]
resource sock_can_bcm[sock_can]
resource sock_can_j1939[sock_can]
resource ifindex_vcan[ifindex]
socket$can_raw(domain const[AF_CAN], type const[SOCK_RAW], proto const[CAN_RAW]) sock_can_raw
bind$can_raw(fd sock_can_raw, addr ptr[in, sockaddr_can], len bytesize[addr])
sendmsg$can_raw(fd sock_can_raw, msg ptr[in, msghdr_can[can_raw_msg]], f flags[send_flags])
recvmsg$can_raw(fd sock_can_raw, msg ptr[inout, recv_msghdr], f flags[recv_flags])
setsockopt$CAN_RAW_FILTER(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_FILTER], val ptr[in, array[can_filter]], len bytesize[val])
setsockopt$CAN_RAW_ERR_FILTER(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_ERR_FILTER], val ptr[in, int32], len bytesize[val])
setsockopt$CAN_RAW_LOOPBACK(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_LOOPBACK], val ptr[in, bool32], len bytesize[val])
setsockopt$CAN_RAW_RECV_OWN_MSGS(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_RECV_OWN_MSGS], val ptr[in, bool32], len bytesize[val])
setsockopt$CAN_RAW_FD_FRAMES(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_FD_FRAMES], val ptr[in, bool32], len bytesize[val])
setsockopt$CAN_RAW_JOIN_FILTERS(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_JOIN_FILTERS], val ptr[in, bool32], len bytesize[val])
getsockopt$CAN_RAW_FILTER(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_FILTER], val ptr[out, array[can_filter]], len ptr[inout, bytesize[val, int32]])
getsockopt$CAN_RAW_LOOPBACK(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_LOOPBACK], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
getsockopt$CAN_RAW_RECV_OWN_MSGS(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_RECV_OWN_MSGS], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
getsockopt$CAN_RAW_FD_FRAMES(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_FD_FRAMES], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
getsockopt$CAN_RAW_JOIN_FILTERS(fd sock_can_raw, level const[SOL_CAN_RAW], opt const[CAN_RAW_JOIN_FILTERS], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
socket$can_bcm(domain const[AF_CAN], type const[SOCK_DGRAM], proto const[CAN_BCM]) sock_can_bcm
connect$can_bcm(fd sock_can_bcm, addr ptr[in, sockaddr_can], len bytesize[addr])
sendmsg$can_bcm(fd sock_can_bcm, msg ptr[in, msghdr_can[can_bcm_msg]], f flags[send_flags])
recvmsg$can_bcm(fd sock_can_bcm, msg ptr[inout, recv_msghdr], f flags[recv_flags])
socket$can_j1939(domain const[AF_CAN], type const[SOCK_DGRAM], proto const[CAN_J1939]) sock_can_j1939
bind$can_j1939(fd sock_can_j1939, addr ptr[in, sockaddr_can_j1939], len bytesize[addr])
connect$can_j1939(fd sock_can_j1939, addr ptr[in, sockaddr_can_j1939], len bytesize[addr])
sendmsg$can_j1939(fd sock_can_j1939, msg ptr[in, msghdr_can_j1939], f flags[send_flags])
recvmsg$can_j1939(fd sock_can_j1939, msg ptr[inout, recv_msghdr], f flags[recv_flags])
setsockopt$SO_J1939_FILTER(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_FILTER], val ptr[in, array[j1939_filter]], len bytesize[val])
setsockopt$SO_J1939_PROMISC(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_PROMISC], val ptr[in, bool32], len bytesize[val])
setsockopt$SO_J1939_ERRQUEUE(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_ERRQUEUE], val ptr[in, bool32], len bytesize[val])
setsockopt$SO_J1939_SEND_PRIO(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_SEND_PRIO], val ptr[in, int32[0:7]], len bytesize[val])
getsockopt$SO_J1939_PROMISC(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_PROMISC], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
getsockopt$SO_J1939_ERRQUEUE(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_ERRQUEUE], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
getsockopt$SO_J1939_SEND_PRIO(fd sock_can_j1939, level const[SOL_CAN_J1939], opt const[SO_J1939_SEND_PRIO], val ptr[out, int32], len ptr[inout, bytesize[val, int32]])
ioctl$ifreq_SIOCGIFINDEX_vcan(fd sock, cmd const[SIOCGIFINDEX], arg ptr[out, ifreq_dev_t[vcan_device_names, ifindex_vcan]])
vcan_device_names = "vcan0", "vxcan0", "vxcan1"
sockaddr_can {
can_family const[AF_CAN, int16]
can_ifindex ifindex_vcan[opt]
rx_id const[0, int32]
tx_id const[0, int32]
}
sockaddr_can_j1939 {
can_family const[AF_CAN, int16]
can_ifindex ifindex_vcan
name can_j1939_name
pgn can_j1939_pgn
addr can_j1939_addr
}
can_j1939_pgn {
pgn_ps flags[can_j1939_pgn_ps, int8]
pgn_pf flags[can_j1939_pgn_pf, int8]
pgn_flags flags[can_j1939_pgn_flags, int8]
pgn_unused const[0, int8]
} [align[4]]
can_j1939_pgn_ps = 0, 1, 2
can_j1939_pgn_pf = 0, 1, 0xf0, 0xff
can_j1939_pgn_flags = 0, 1, 2, 3, 4
type can_j1939_name int64[0:3]
type can_j1939_addr flags[can_j1939_addrs, int8]
can_j1939_addrs = J1939_MAX_UNICAST_ADDR, J1939_IDLE_ADDR, J1939_NO_ADDR, 0, 1, 2
type msghdr_can[MSG] {
addr ptr[in, sockaddr_can, opt]
addrlen len[addr, int32]
vec ptr[in, iovec[in, MSG]]
vlen const[1, intptr]
ctrl const[0, intptr]
ctrllen const[0, intptr]
f flags[send_flags, int32]
}
msghdr_can_j1939 {
addr ptr[in, sockaddr_can_j1939, opt]
addrlen len[addr, int32]
vec ptr[in, iovec[in, array[int8]]]
vlen const[1, intptr]
ctrl const[0, intptr]
ctrllen const[0, intptr]
f flags[send_flags, int32]
}
can_raw_msg [
can can_frame
canfd canfd_frame
] [varlen]
can_bcm_msg {
opcode flags[can_bcm_opcodes, int32]
flags flags[can_bcm_flags, int32]
count int32
ival1 timeval
ival2 timeval
can_id canid_t
nframes const[1, int32]
frames can_raw_msg
}
type can_frame_t[DATA_SIZE] {
can_id canid_t
len int8[0:DATA_SIZE]
flags flags[can_frame_flags, int8]
__res0 const[0, int8]
__res1 const[0, int8]
data array[int8, DATA_SIZE]
}
type can_frame can_frame_t[CAN_MAX_DLEN]
type canfd_frame can_frame_t[CANFD_MAX_DLEN]
canid_t {
id int32:29[0:4]
err int32:1
rtr int32:1
eff int32:1
}
can_filter {
can_id canid_t
can_mask canid_t
}
j1939_filter {
name can_j1939_name
name_mask can_j1939_name
pgn can_j1939_pgn
pgn_mask can_j1939_pgn
addr can_j1939_addr
addr_mask can_j1939_addr
}
can_bcm_opcodes = TX_SETUP, TX_DELETE, TX_READ, TX_SEND, RX_SETUP, RX_DELETE, RX_READ
can_bcm_flags = SETTIMER, STARTTIMER, TX_COUNTEVT, TX_ANNOUNCE, TX_CP_CAN_ID, RX_FILTER_ID, RX_CHECK_DLC, RX_NO_AUTOTIMER, RX_ANNOUNCE_RESUME, TX_RESET_MULTI_IDX, RX_RTR_FRAME, CAN_FD_FRAME
can_frame_flags = CANFD_BRS, CANFD_ESI
|