@@ -48,7 +48,7 @@ static int errpos(const char *str)
4848 return err_pos (last_cmd , str );
4949}
5050
51- static void last_cmd_set (char * str )
51+ static void last_cmd_set (const char * str )
5252{
5353 if (!str )
5454 return ;
@@ -579,18 +579,14 @@ static void free_synth_field(struct synth_field *field)
579579 kfree (field );
580580}
581581
582- static struct synth_field * parse_synth_field (int argc , const char * * argv ,
583- int * consumed )
582+ static struct synth_field * parse_synth_field (int argc , char * * argv )
584583{
585- struct synth_field * field ;
586584 const char * prefix = NULL , * field_type = argv [0 ], * field_name , * array ;
587- int len , ret = - ENOMEM ;
585+ int len , consumed , ret = - ENOMEM ;
586+ struct synth_field * field ;
588587 struct seq_buf s ;
589588 ssize_t size ;
590589
591- if (field_type [0 ] == ';' )
592- field_type ++ ;
593-
594590 if (!strcmp (field_type , "unsigned" )) {
595591 if (argc < 3 ) {
596592 synth_err (SYNTH_ERR_INCOMPLETE_TYPE , errpos (field_type ));
@@ -599,10 +595,20 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
599595 prefix = "unsigned " ;
600596 field_type = argv [1 ];
601597 field_name = argv [2 ];
602- * consumed = 3 ;
598+ consumed = 3 ;
603599 } else {
604600 field_name = argv [1 ];
605- * consumed = 2 ;
601+ consumed = 2 ;
602+ }
603+
604+ if (consumed < argc ) {
605+ synth_err (SYNTH_ERR_INVALID_FIELD , errpos (field_type ));
606+ return ERR_PTR (- EINVAL );
607+ }
608+
609+ if (!field_name ) {
610+ synth_err (SYNTH_ERR_INVALID_FIELD , errpos (field_type ));
611+ return ERR_PTR (- EINVAL );
606612 }
607613
608614 field = kzalloc (sizeof (* field ), GFP_KERNEL );
@@ -613,8 +619,6 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
613619 array = strchr (field_name , '[' );
614620 if (array )
615621 len -= strlen (array );
616- else if (field_name [len - 1 ] == ';' )
617- len -- ;
618622
619623 field -> name = kmemdup_nul (field_name , len , GFP_KERNEL );
620624 if (!field -> name )
@@ -626,8 +630,6 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
626630 goto free ;
627631 }
628632
629- if (field_type [0 ] == ';' )
630- field_type ++ ;
631633 len = strlen (field_type ) + 1 ;
632634
633635 if (array )
@@ -644,11 +646,8 @@ static struct synth_field *parse_synth_field(int argc, const char **argv,
644646 if (prefix )
645647 seq_buf_puts (& s , prefix );
646648 seq_buf_puts (& s , field_type );
647- if (array ) {
649+ if (array )
648650 seq_buf_puts (& s , array );
649- if (s .buffer [s .len - 1 ] == ';' )
650- s .len -- ;
651- }
652651 if (WARN_ON_ONCE (!seq_buf_buffer_left (& s )))
653652 goto free ;
654653
@@ -1160,46 +1159,12 @@ int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name,
11601159}
11611160EXPORT_SYMBOL_GPL (synth_event_gen_cmd_array_start );
11621161
1163- static int save_cmdstr (int argc , const char * name , const char * * argv )
1164- {
1165- struct seq_buf s ;
1166- char * buf ;
1167- int i ;
1168-
1169- buf = kzalloc (MAX_DYNEVENT_CMD_LEN , GFP_KERNEL );
1170- if (!buf )
1171- return - ENOMEM ;
1172-
1173- seq_buf_init (& s , buf , MAX_DYNEVENT_CMD_LEN );
1174-
1175- seq_buf_puts (& s , name );
1176-
1177- for (i = 0 ; i < argc ; i ++ ) {
1178- seq_buf_putc (& s , ' ' );
1179- seq_buf_puts (& s , argv [i ]);
1180- }
1181-
1182- if (!seq_buf_buffer_left (& s )) {
1183- synth_err (SYNTH_ERR_CMD_TOO_LONG , 0 );
1184- kfree (buf );
1185- return - EINVAL ;
1186- }
1187- buf [s .len ] = 0 ;
1188- last_cmd_set (buf );
1189-
1190- kfree (buf );
1191- return 0 ;
1192- }
1193-
1194- static int __create_synth_event (int argc , const char * name , const char * * argv )
1162+ static int __create_synth_event (const char * name , const char * raw_fields )
11951163{
1164+ char * * argv , * field_str , * tmp_fields , * saved_fields = NULL ;
11961165 struct synth_field * field , * fields [SYNTH_FIELDS_MAX ];
1166+ int i , argc , n_fields = 0 , ret = 0 ;
11971167 struct synth_event * event = NULL ;
1198- int i , consumed = 0 , n_fields = 0 , ret = 0 ;
1199-
1200- ret = save_cmdstr (argc , name , argv );
1201- if (ret )
1202- return ret ;
12031168
12041169 /*
12051170 * Argument syntax:
@@ -1208,46 +1173,60 @@ static int __create_synth_event(int argc, const char *name, const char **argv)
12081173 * where 'field' = type field_name
12091174 */
12101175
1211- if (name [0 ] == '\0' || argc < 1 ) {
1176+ if (name [0 ] == '\0' ) {
12121177 synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
12131178 return - EINVAL ;
12141179 }
12151180
1216- mutex_lock (& event_mutex );
1217-
12181181 if (!is_good_name (name )) {
12191182 synth_err (SYNTH_ERR_BAD_NAME , errpos (name ));
1220- ret = - EINVAL ;
1221- goto out ;
1183+ return - EINVAL ;
12221184 }
12231185
1186+ mutex_lock (& event_mutex );
1187+
12241188 event = find_synth_event (name );
12251189 if (event ) {
12261190 synth_err (SYNTH_ERR_EVENT_EXISTS , errpos (name ));
12271191 ret = - EEXIST ;
1228- goto out ;
1192+ goto err ;
12291193 }
12301194
1231- for (i = 0 ; i < argc - 1 ; i ++ ) {
1232- if (strcmp (argv [i ], ";" ) == 0 )
1233- continue ;
1234- if (n_fields == SYNTH_FIELDS_MAX ) {
1235- synth_err (SYNTH_ERR_TOO_MANY_FIELDS , 0 );
1236- ret = - EINVAL ;
1195+ tmp_fields = saved_fields = kstrdup (raw_fields , GFP_KERNEL );
1196+ if (!tmp_fields ) {
1197+ ret = - ENOMEM ;
1198+ goto err ;
1199+ }
1200+
1201+ while ((field_str = strsep (& tmp_fields , ";" )) != NULL ) {
1202+ argv = argv_split (GFP_KERNEL , field_str , & argc );
1203+ if (!argv ) {
1204+ ret = - ENOMEM ;
12371205 goto err ;
12381206 }
12391207
1240- field = parse_synth_field (argc - i , & argv [i ], & consumed );
1208+ if (!argc )
1209+ continue ;
1210+
1211+ field = parse_synth_field (argc , argv );
12411212 if (IS_ERR (field )) {
1213+ argv_free (argv );
12421214 ret = PTR_ERR (field );
12431215 goto err ;
12441216 }
1217+
1218+ argv_free (argv );
1219+
12451220 fields [n_fields ++ ] = field ;
1246- i += consumed - 1 ;
1221+ if (n_fields == SYNTH_FIELDS_MAX ) {
1222+ synth_err (SYNTH_ERR_TOO_MANY_FIELDS , 0 );
1223+ ret = - EINVAL ;
1224+ goto err ;
1225+ }
12471226 }
12481227
1249- if (i < argc && strcmp ( argv [ i ], ";" ) ! = 0 ) {
1250- synth_err (SYNTH_ERR_INVALID_FIELD , errpos ( argv [ i ]) );
1228+ if (n_fields = = 0 ) {
1229+ synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
12511230 ret = - EINVAL ;
12521231 goto err ;
12531232 }
@@ -1266,6 +1245,8 @@ static int __create_synth_event(int argc, const char *name, const char **argv)
12661245 out :
12671246 mutex_unlock (& event_mutex );
12681247
1248+ kfree (saved_fields );
1249+
12691250 return ret ;
12701251 err :
12711252 for (i = 0 ; i < n_fields ; i ++ )
@@ -1383,31 +1364,79 @@ int synth_event_delete(const char *event_name)
13831364}
13841365EXPORT_SYMBOL_GPL (synth_event_delete );
13851366
1386- static int create_or_delete_synth_event (const char * raw_command )
1367+ static int check_command (const char * raw_command )
13871368{
1388- char * * argv , * name = NULL ;
1389- int argc = 0 , ret = 0 ;
1369+ char * * argv = NULL , * cmd , * saved_cmd , * name_and_field ;
1370+ int argc , ret = 0 ;
13901371
1391- argv = argv_split ( GFP_KERNEL , raw_command , & argc );
1392- if (!argv )
1372+ cmd = saved_cmd = kstrdup ( raw_command , GFP_KERNEL );
1373+ if (!cmd )
13931374 return - ENOMEM ;
13941375
1395- if (!argc )
1376+ name_and_field = strsep (& cmd , ";" );
1377+ if (!name_and_field ) {
1378+ ret = - EINVAL ;
1379+ goto free ;
1380+ }
1381+
1382+ if (name_and_field [0 ] == '!' )
1383+ goto free ;
1384+
1385+ argv = argv_split (GFP_KERNEL , name_and_field , & argc );
1386+ if (!argv ) {
1387+ ret = - ENOMEM ;
13961388 goto free ;
1389+ }
1390+ argv_free (argv );
1391+
1392+ if (argc < 3 )
1393+ ret = - EINVAL ;
1394+ free :
1395+ kfree (saved_cmd );
13971396
1398- name = argv [0 ];
1397+ return ret ;
1398+ }
1399+
1400+ static int create_or_delete_synth_event (const char * raw_command )
1401+ {
1402+ char * name = NULL , * fields , * p ;
1403+ int ret = 0 ;
1404+
1405+ raw_command = skip_spaces (raw_command );
1406+ if (raw_command [0 ] == '\0' )
1407+ return ret ;
1408+
1409+ last_cmd_set (raw_command );
1410+
1411+ ret = check_command (raw_command );
1412+ if (ret ) {
1413+ synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
1414+ return ret ;
1415+ }
1416+
1417+ p = strpbrk (raw_command , " \t" );
1418+ if (!p && raw_command [0 ] != '!' ) {
1419+ synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
1420+ ret = - EINVAL ;
1421+ goto free ;
1422+ }
1423+
1424+ name = kmemdup_nul (raw_command , p ? p - raw_command : strlen (raw_command ), GFP_KERNEL );
1425+ if (!name )
1426+ return - ENOMEM ;
13991427
1400- /* trace_run_command() ensures argc != 0 */
14011428 if (name [0 ] == '!' ) {
14021429 ret = synth_event_delete (name + 1 );
14031430 goto free ;
14041431 }
14051432
1406- ret = __create_synth_event (argc - 1 , name , (const char * * )argv + 1 );
1433+ fields = skip_spaces (p );
1434+
1435+ ret = __create_synth_event (name , fields );
14071436free :
1408- argv_free ( argv );
1437+ kfree ( name );
14091438
1410- return ret == - ECANCELED ? - EINVAL : ret ;
1439+ return ret ;
14111440}
14121441
14131442static int synth_event_run_command (struct dynevent_cmd * cmd )
@@ -1953,39 +1982,51 @@ EXPORT_SYMBOL_GPL(synth_event_trace_end);
19531982
19541983static int create_synth_event (const char * raw_command )
19551984{
1956- char * * argv , * name ;
1957- int len , argc = 0 , ret = 0 ;
1985+ char * fields , * p ;
1986+ const char * name ;
1987+ int len , ret = 0 ;
19581988
1959- argv = argv_split (GFP_KERNEL , raw_command , & argc );
1960- if (!argv ) {
1961- ret = - ENOMEM ;
1989+ raw_command = skip_spaces (raw_command );
1990+ if (raw_command [0 ] == '\0' )
19621991 return ret ;
1963- }
19641992
1965- if (!argc )
1966- goto free ;
1993+ last_cmd_set (raw_command );
19671994
1968- name = argv [0 ];
1995+ p = strpbrk (raw_command , " \t" );
1996+ if (!p )
1997+ return - EINVAL ;
19691998
1970- if (name [0 ] != 's' || name [1 ] != ':' ) {
1971- ret = - ECANCELED ;
1972- goto free ;
1973- }
1999+ fields = skip_spaces (p );
2000+
2001+ name = raw_command ;
2002+
2003+ if (name [0 ] != 's' || name [1 ] != ':' )
2004+ return - ECANCELED ;
19742005 name += 2 ;
19752006
19762007 /* This interface accepts group name prefix */
19772008 if (strchr (name , '/' )) {
19782009 len = str_has_prefix (name , SYNTH_SYSTEM "/" );
1979- if (len == 0 ) {
1980- ret = - EINVAL ;
1981- goto free ;
1982- }
2010+ if (len == 0 )
2011+ return - EINVAL ;
19832012 name += len ;
19842013 }
19852014
1986- ret = __create_synth_event (argc - 1 , name , (const char * * )argv + 1 );
1987- free :
1988- argv_free (argv );
2015+ len = name - raw_command ;
2016+
2017+ ret = check_command (raw_command + len );
2018+ if (ret ) {
2019+ synth_err (SYNTH_ERR_CMD_INCOMPLETE , 0 );
2020+ return ret ;
2021+ }
2022+
2023+ name = kmemdup_nul (raw_command + len , p - raw_command - len , GFP_KERNEL );
2024+ if (!name )
2025+ return - ENOMEM ;
2026+
2027+ ret = __create_synth_event (name , fields );
2028+
2029+ kfree (name );
19892030
19902031 return ret ;
19912032}
0 commit comments