aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace_uprobe.c35
1 files changed, 14 insertions, 21 deletions
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 34fd0e0ec51d..ac892878dbe6 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -55,6 +55,7 @@ struct trace_uprobe {
55 struct list_head list; 55 struct list_head list;
56 struct trace_uprobe_filter filter; 56 struct trace_uprobe_filter filter;
57 struct uprobe_consumer consumer; 57 struct uprobe_consumer consumer;
58 struct path path;
58 struct inode *inode; 59 struct inode *inode;
59 char *filename; 60 char *filename;
60 unsigned long offset; 61 unsigned long offset;
@@ -289,7 +290,7 @@ static void free_trace_uprobe(struct trace_uprobe *tu)
289 for (i = 0; i < tu->tp.nr_args; i++) 290 for (i = 0; i < tu->tp.nr_args; i++)
290 traceprobe_free_probe_arg(&tu->tp.args[i]); 291 traceprobe_free_probe_arg(&tu->tp.args[i]);
291 292
292 iput(tu->inode); 293 path_put(&tu->path);
293 kfree(tu->tp.call.class->system); 294 kfree(tu->tp.call.class->system);
294 kfree(tu->tp.call.name); 295 kfree(tu->tp.call.name);
295 kfree(tu->filename); 296 kfree(tu->filename);
@@ -363,7 +364,6 @@ end:
363static int create_trace_uprobe(int argc, char **argv) 364static int create_trace_uprobe(int argc, char **argv)
364{ 365{
365 struct trace_uprobe *tu; 366 struct trace_uprobe *tu;
366 struct inode *inode;
367 char *arg, *event, *group, *filename; 367 char *arg, *event, *group, *filename;
368 char buf[MAX_EVENT_NAME_LEN]; 368 char buf[MAX_EVENT_NAME_LEN];
369 struct path path; 369 struct path path;
@@ -371,7 +371,6 @@ static int create_trace_uprobe(int argc, char **argv)
371 bool is_delete, is_return; 371 bool is_delete, is_return;
372 int i, ret; 372 int i, ret;
373 373
374 inode = NULL;
375 ret = 0; 374 ret = 0;
376 is_delete = false; 375 is_delete = false;
377 is_return = false; 376 is_return = false;
@@ -437,21 +436,16 @@ static int create_trace_uprobe(int argc, char **argv)
437 } 436 }
438 /* Find the last occurrence, in case the path contains ':' too. */ 437 /* Find the last occurrence, in case the path contains ':' too. */
439 arg = strrchr(argv[1], ':'); 438 arg = strrchr(argv[1], ':');
440 if (!arg) { 439 if (!arg)
441 ret = -EINVAL; 440 return -EINVAL;
442 goto fail_address_parse;
443 }
444 441
445 *arg++ = '\0'; 442 *arg++ = '\0';
446 filename = argv[1]; 443 filename = argv[1];
447 ret = kern_path(filename, LOOKUP_FOLLOW, &path); 444 ret = kern_path(filename, LOOKUP_FOLLOW, &path);
448 if (ret) 445 if (ret)
449 goto fail_address_parse; 446 return ret;
450
451 inode = igrab(d_real_inode(path.dentry));
452 path_put(&path);
453 447
454 if (!inode || !S_ISREG(inode->i_mode)) { 448 if (!d_is_reg(path.dentry)) {
455 ret = -EINVAL; 449 ret = -EINVAL;
456 goto fail_address_parse; 450 goto fail_address_parse;
457 } 451 }
@@ -490,7 +484,7 @@ static int create_trace_uprobe(int argc, char **argv)
490 goto fail_address_parse; 484 goto fail_address_parse;
491 } 485 }
492 tu->offset = offset; 486 tu->offset = offset;
493 tu->inode = inode; 487 tu->path = path;
494 tu->filename = kstrdup(filename, GFP_KERNEL); 488 tu->filename = kstrdup(filename, GFP_KERNEL);
495 489
496 if (!tu->filename) { 490 if (!tu->filename) {
@@ -558,7 +552,7 @@ error:
558 return ret; 552 return ret;
559 553
560fail_address_parse: 554fail_address_parse:
561 iput(inode); 555 path_put(&path);
562 556
563 pr_info("Failed to parse address or file.\n"); 557 pr_info("Failed to parse address or file.\n");
564 558
@@ -922,6 +916,7 @@ probe_event_enable(struct trace_uprobe *tu, struct trace_event_file *file,
922 goto err_flags; 916 goto err_flags;
923 917
924 tu->consumer.filter = filter; 918 tu->consumer.filter = filter;
919 tu->inode = d_real_inode(tu->path.dentry);
925 ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); 920 ret = uprobe_register(tu->inode, tu->offset, &tu->consumer);
926 if (ret) 921 if (ret)
927 goto err_buffer; 922 goto err_buffer;
@@ -967,6 +962,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file)
967 WARN_ON(!uprobe_filter_is_empty(&tu->filter)); 962 WARN_ON(!uprobe_filter_is_empty(&tu->filter));
968 963
969 uprobe_unregister(tu->inode, tu->offset, &tu->consumer); 964 uprobe_unregister(tu->inode, tu->offset, &tu->consumer);
965 tu->inode = NULL;
970 tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE; 966 tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE;
971 967
972 uprobe_buffer_disable(); 968 uprobe_buffer_disable();
@@ -1337,7 +1333,6 @@ struct trace_event_call *
1337create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) 1333create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
1338{ 1334{
1339 struct trace_uprobe *tu; 1335 struct trace_uprobe *tu;
1340 struct inode *inode;
1341 struct path path; 1336 struct path path;
1342 int ret; 1337 int ret;
1343 1338
@@ -1345,11 +1340,8 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
1345 if (ret) 1340 if (ret)
1346 return ERR_PTR(ret); 1341 return ERR_PTR(ret);
1347 1342
1348 inode = igrab(d_inode(path.dentry)); 1343 if (!d_is_reg(path.dentry)) {
1349 path_put(&path); 1344 path_put(&path);
1350
1351 if (!inode || !S_ISREG(inode->i_mode)) {
1352 iput(inode);
1353 return ERR_PTR(-EINVAL); 1345 return ERR_PTR(-EINVAL);
1354 } 1346 }
1355 1347
@@ -1364,11 +1356,12 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return)
1364 if (IS_ERR(tu)) { 1356 if (IS_ERR(tu)) {
1365 pr_info("Failed to allocate trace_uprobe.(%d)\n", 1357 pr_info("Failed to allocate trace_uprobe.(%d)\n",
1366 (int)PTR_ERR(tu)); 1358 (int)PTR_ERR(tu));
1359 path_put(&path);
1367 return ERR_CAST(tu); 1360 return ERR_CAST(tu);
1368 } 1361 }
1369 1362
1370 tu->offset = offs; 1363 tu->offset = offs;
1371 tu->inode = inode; 1364 tu->path = path;
1372 tu->filename = kstrdup(name, GFP_KERNEL); 1365 tu->filename = kstrdup(name, GFP_KERNEL);
1373 init_trace_event_call(tu, &tu->tp.call); 1366 init_trace_event_call(tu, &tu->tp.call);
1374 1367