3030#define IOCTL_MBOX_PROPERTY32 _IOWR(VCIO_IOC_MAGIC, 0, compat_uptr_t)
3131#endif
3232
33+ /* Tags permitted via /dev/vcio_provisioning. */
34+ static const u32 vcio_provisioning_tags [] = {
35+ 0x00038021 , /* SET_CUSTOMER_OTP */
36+ 0x00038024 , /* SET_USER_OTP */
37+ 0x00038082 , /* SET_CUSTOMER_ETHER_MAC_OTP */
38+ 0x00038083 , /* SET_CUSTOMER_WIFI_MAC_OTP */
39+ 0x00038084 , /* SET_CUSTOMER_BT_MAC_OTP */
40+ 0x00030085 , /* TST_MAC_OTP */
41+ 0x00030086 , /* SET_CUSTOMER_OTP_LOCK */
42+ };
43+
44+ /* Tags permitted via /dev/vcio_ab. */
45+ static const u32 vcio_ab_tags [] = {
46+ 0x00030048 , /* SET_NOTIFY_REBOOT */
47+ 0x00030057 , /* SET_GLOBAL_RESET */
48+ 0x00030064 , /* GET_REBOOT_FLAGS */
49+ 0x00038064 , /* SET_REBOOT_FLAGS */
50+ 0x0003008b , /* GET_REBOOT_ORDER */
51+ 0x0003808b , /* SET_REBOOT_ORDER */
52+ 0x0003008c , /* GET_REBOOT_ARG */
53+ 0x0003808c , /* SET_REBOOT_ARG */
54+ 0x0003008d , /* GET_BOOT_COUNT */
55+ 0x0003808d , /* SET_BOOT_COUNT */
56+ 0x00040011 , /* GET_RSTS */
57+ 0x00030096 , /* GET_EEPROM_PACKET */
58+ 0x00038096 , /* SET_EEPROM_PACKET */
59+ 0x00030097 , /* GET_EEPROM_UPDATE_STATUS */
60+ 0x00038097 , /* SET_EEPROM_UPDATE_STATUS */
61+ 0x00030098 , /* GET_EEPROM_PARTITION */
62+ 0x00038098 , /* SET_EEPROM_PARTITION */
63+ 0x00030099 , /* GET_EEPROM_AB_PARAMS */
64+ 0x00038099 , /* SET_EEPROM_AB_PARAMS */
65+ };
66+
67+ /* Tags permitted via /dev/vcio_gencmd. */
68+ static const u32 vcio_gencmd_tags [] = {
69+ 0x00030080 , /* GET_GENCMD_RESULT */
70+ };
71+
72+ /* Tags permitted via /dev/vcio_crypto. */
73+ static const u32 vcio_crypto_tags [] = {
74+ 0x0003008e , /* GET_CRYPTO_LAST_ERROR */
75+ 0x0003008f , /* GET_CRYPTO_NUM_OTP_KEYS */
76+ 0x00030090 , /* GET_CRYPTO_KEY_STATUS */
77+ 0x00038090 , /* SET_CRYPTO_KEY_STATUS */
78+ 0x00030091 , /* GET_CRYPTO_ECDSA_SIGN */
79+ 0x00030092 , /* GET_CRYPTO_HMAC_SHA256 */
80+ 0x00030093 , /* GET_CRYPTO_PUBLIC_KEY */
81+ 0x00030094 , /* GET_CRYPTO_PRIVATE_KEY */
82+ 0x00030095 , /* GET_CRYPTO_GEN_ECDSA */
83+ };
84+
85+ struct vcio_group {
86+ const char * name ;
87+ const u32 * tags ;
88+ size_t num_tags ;
89+ };
90+
91+ #define VCIO_GROUP (suffix ) { \
92+ .name = "vcio_" #suffix, \
93+ .tags = vcio_ ## suffix ## _tags, \
94+ .num_tags = ARRAY_SIZE(vcio_ ## suffix ## _tags), \
95+ }
96+
97+ static const struct vcio_group vcio_groups [] = {
98+ VCIO_GROUP (provisioning ),
99+ VCIO_GROUP (ab ),
100+ VCIO_GROUP (gencmd ),
101+ VCIO_GROUP (crypto ),
102+ };
103+
104+ struct vcio_dev {
105+ struct miscdevice misc_dev ;
106+ struct rpi_firmware * fw ;
107+ const u32 * allowed_tags ;
108+ size_t num_allowed_tags ;
109+ };
110+
33111struct vcio_data {
34112 struct rpi_firmware * fw ;
35- struct miscdevice misc_dev ;
113+ struct vcio_dev vcio ;
114+ struct vcio_dev groups [ARRAY_SIZE (vcio_groups )];
36115};
37116
38- static int vcio_user_property_list (struct vcio_data * vcio , void * user )
117+ static bool vcio_tag_allowed (const struct vcio_dev * vdev , u32 tag )
118+ {
119+ size_t i ;
120+
121+ if (!vdev -> allowed_tags )
122+ return true;
123+
124+ for (i = 0 ; i < vdev -> num_allowed_tags ; i ++ )
125+ if (vdev -> allowed_tags [i ] == tag )
126+ return true;
127+
128+ return false;
129+ }
130+
131+ static int vcio_check_tags (const struct vcio_dev * vdev , const u32 * buf ,
132+ size_t size )
133+ {
134+ size_t offset = 8 ; /* skip total size and status words */
135+
136+ if (!vdev -> allowed_tags )
137+ return 0 ;
138+
139+ while (offset + 12 <= size ) {
140+ u32 tag = buf [offset / 4 ];
141+ u32 val_size ;
142+
143+ if (tag == 0 )
144+ return 0 ;
145+
146+ if (!vcio_tag_allowed (vdev , tag )) {
147+ pr_warn_ratelimited ("%s: tag 0x%08x not permitted\n" ,
148+ vdev -> misc_dev .name , tag );
149+ return - EPERM ;
150+ }
151+
152+ val_size = buf [offset / 4 + 1 ];
153+ if (val_size > size - offset - 12 )
154+ return - EINVAL ;
155+ offset += 12 + ALIGN (val_size , 4 );
156+
157+ if (offset > size )
158+ return - EINVAL ;
159+ }
160+
161+ return 0 ;
162+ }
163+
164+ static int vcio_user_property_list (struct vcio_dev * vdev , void * user )
39165{
40166 u32 * buf , size ;
41167 int ret ;
@@ -44,6 +170,9 @@ static int vcio_user_property_list(struct vcio_data *vcio, void *user)
44170 if (copy_from_user (& size , user , sizeof (size )))
45171 return - EFAULT ;
46172
173+ if (size < 12 )
174+ return - EINVAL ;
175+
47176 buf = kmalloc (size , GFP_KERNEL );
48177 if (!buf )
49178 return - ENOMEM ;
@@ -53,8 +182,14 @@ static int vcio_user_property_list(struct vcio_data *vcio, void *user)
53182 return - EFAULT ;
54183 }
55184
185+ ret = vcio_check_tags (vdev , buf , size );
186+ if (ret ) {
187+ kfree (buf );
188+ return ret ;
189+ }
190+
56191 /* Strip off protocol encapsulation */
57- ret = rpi_firmware_property_list (vcio -> fw , & buf [2 ], size - 12 );
192+ ret = rpi_firmware_property_list (vdev -> fw , & buf [2 ], size - 12 );
58193 if (ret ) {
59194 kfree (buf );
60195 return ret ;
@@ -86,12 +221,12 @@ static int vcio_device_release(struct inode *inode, struct file *file)
86221static long vcio_device_ioctl (struct file * file , unsigned int ioctl_num ,
87222 unsigned long ioctl_param )
88223{
89- struct vcio_data * vcio = container_of (file -> private_data ,
90- struct vcio_data , misc_dev );
224+ struct vcio_dev * vdev = container_of (file -> private_data ,
225+ struct vcio_dev , misc_dev );
91226
92227 switch (ioctl_num ) {
93228 case IOCTL_MBOX_PROPERTY :
94- return vcio_user_property_list (vcio , (void * )ioctl_param );
229+ return vcio_user_property_list (vdev , (void * )ioctl_param );
95230 default :
96231 pr_err ("unknown ioctl: %x\n" , ioctl_num );
97232 return - EINVAL ;
@@ -102,12 +237,12 @@ static long vcio_device_ioctl(struct file *file, unsigned int ioctl_num,
102237static long vcio_device_compat_ioctl (struct file * file , unsigned int ioctl_num ,
103238 unsigned long ioctl_param )
104239{
105- struct vcio_data * vcio = container_of (file -> private_data ,
106- struct vcio_data , misc_dev );
240+ struct vcio_dev * vdev = container_of (file -> private_data ,
241+ struct vcio_dev , misc_dev );
107242
108243 switch (ioctl_num ) {
109244 case IOCTL_MBOX_PROPERTY32 :
110- return vcio_user_property_list (vcio , compat_ptr (ioctl_param ));
245+ return vcio_user_property_list (vdev , compat_ptr (ioctl_param ));
111246 default :
112247 pr_err ("unknown ioctl: %x\n" , ioctl_num );
113248 return - EINVAL ;
@@ -124,13 +259,30 @@ const struct file_operations vcio_fops = {
124259 .release = vcio_device_release ,
125260};
126261
262+ static int vcio_register (struct device * dev , struct vcio_dev * vdev ,
263+ struct rpi_firmware * fw , const char * name ,
264+ const u32 * allowed_tags , size_t num_allowed_tags )
265+ {
266+ vdev -> fw = fw ;
267+ vdev -> allowed_tags = allowed_tags ;
268+ vdev -> num_allowed_tags = num_allowed_tags ;
269+ vdev -> misc_dev .fops = & vcio_fops ;
270+ vdev -> misc_dev .minor = MISC_DYNAMIC_MINOR ;
271+ vdev -> misc_dev .name = name ;
272+ vdev -> misc_dev .parent = dev ;
273+
274+ return misc_register (& vdev -> misc_dev );
275+ }
276+
127277static int vcio_probe (struct platform_device * pdev )
128278{
129279 struct device * dev = & pdev -> dev ;
130280 struct device_node * np = dev -> of_node ;
131281 struct device_node * fw_node ;
132282 struct rpi_firmware * fw ;
133283 struct vcio_data * vcio ;
284+ size_t i ;
285+ int ret ;
134286
135287 fw_node = of_get_parent (np );
136288 if (!fw_node ) {
@@ -143,24 +295,43 @@ static int vcio_probe(struct platform_device *pdev)
143295 if (!fw )
144296 return - EPROBE_DEFER ;
145297
146- vcio = devm_kzalloc (dev , sizeof (struct vcio_data ), GFP_KERNEL );
298+ vcio = devm_kzalloc (dev , sizeof (* vcio ), GFP_KERNEL );
147299 if (!vcio )
148300 return - ENOMEM ;
149301
150302 vcio -> fw = fw ;
151- vcio -> misc_dev .fops = & vcio_fops ;
152- vcio -> misc_dev .minor = MISC_DYNAMIC_MINOR ;
153- vcio -> misc_dev .name = "vcio" ;
154- vcio -> misc_dev .parent = dev ;
303+ platform_set_drvdata (pdev , vcio );
304+
305+ ret = vcio_register (dev , & vcio -> vcio , fw , "vcio" , NULL , 0 );
306+ if (ret )
307+ return ret ;
155308
156- return misc_register (& vcio -> misc_dev );
309+ for (i = 0 ; i < ARRAY_SIZE (vcio_groups ); i ++ ) {
310+ const struct vcio_group * g = & vcio_groups [i ];
311+
312+ ret = vcio_register (dev , & vcio -> groups [i ], fw , g -> name ,
313+ g -> tags , g -> num_tags );
314+ if (ret )
315+ goto err_groups ;
316+ }
317+
318+ return 0 ;
319+
320+ err_groups :
321+ while (i -- )
322+ misc_deregister (& vcio -> groups [i ].misc_dev );
323+ misc_deregister (& vcio -> vcio .misc_dev );
324+ return ret ;
157325}
158326
159327static void vcio_remove (struct platform_device * pdev )
160328{
161- struct device * dev = & pdev -> dev ;
329+ struct vcio_data * vcio = platform_get_drvdata (pdev );
330+ size_t i = ARRAY_SIZE (vcio_groups );
162331
163- misc_deregister (dev_get_drvdata (dev ));
332+ while (i -- )
333+ misc_deregister (& vcio -> groups [i ].misc_dev );
334+ misc_deregister (& vcio -> vcio .misc_dev );
164335}
165336
166337static const struct of_device_id vcio_ids [] = {
0 commit comments