|
@@ -1588,6 +1588,72 @@ static void __kprobes kill_kprobe(struct kprobe *p)
|
|
|
arch_remove_kprobe(p);
|
|
|
}
|
|
|
|
|
|
+/* Disable one kprobe */
|
|
|
+int __kprobes disable_kprobe(struct kprobe *kp)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ struct kprobe *p;
|
|
|
+
|
|
|
+ mutex_lock(&kprobe_mutex);
|
|
|
+
|
|
|
+ /* Check whether specified probe is valid. */
|
|
|
+ p = __get_valid_kprobe(kp);
|
|
|
+ if (unlikely(p == NULL)) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If the probe is already disabled (or gone), just return */
|
|
|
+ if (kprobe_disabled(kp))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ kp->flags |= KPROBE_FLAG_DISABLED;
|
|
|
+ if (p != kp)
|
|
|
+ /* When kp != p, p is always enabled. */
|
|
|
+ try_to_disable_aggr_kprobe(p);
|
|
|
+
|
|
|
+ if (!kprobes_all_disarmed && kprobe_disabled(p))
|
|
|
+ disarm_kprobe(p);
|
|
|
+out:
|
|
|
+ mutex_unlock(&kprobe_mutex);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(disable_kprobe);
|
|
|
+
|
|
|
+/* Enable one kprobe */
|
|
|
+int __kprobes enable_kprobe(struct kprobe *kp)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ struct kprobe *p;
|
|
|
+
|
|
|
+ mutex_lock(&kprobe_mutex);
|
|
|
+
|
|
|
+ /* Check whether specified probe is valid. */
|
|
|
+ p = __get_valid_kprobe(kp);
|
|
|
+ if (unlikely(p == NULL)) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (kprobe_gone(kp)) {
|
|
|
+ /* This kprobe has gone, we couldn't enable it. */
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p != kp)
|
|
|
+ kp->flags &= ~KPROBE_FLAG_DISABLED;
|
|
|
+
|
|
|
+ if (!kprobes_all_disarmed && kprobe_disabled(p)) {
|
|
|
+ p->flags &= ~KPROBE_FLAG_DISABLED;
|
|
|
+ arm_kprobe(p);
|
|
|
+ }
|
|
|
+out:
|
|
|
+ mutex_unlock(&kprobe_mutex);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(enable_kprobe);
|
|
|
+
|
|
|
void __kprobes dump_kprobe(struct kprobe *kp)
|
|
|
{
|
|
|
printk(KERN_WARNING "Dumping kprobe:\n");
|
|
@@ -1805,72 +1871,6 @@ static const struct file_operations debugfs_kprobes_operations = {
|
|
|
.release = seq_release,
|
|
|
};
|
|
|
|
|
|
-/* Disable one kprobe */
|
|
|
-int __kprobes disable_kprobe(struct kprobe *kp)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
- struct kprobe *p;
|
|
|
-
|
|
|
- mutex_lock(&kprobe_mutex);
|
|
|
-
|
|
|
- /* Check whether specified probe is valid. */
|
|
|
- p = __get_valid_kprobe(kp);
|
|
|
- if (unlikely(p == NULL)) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- /* If the probe is already disabled (or gone), just return */
|
|
|
- if (kprobe_disabled(kp))
|
|
|
- goto out;
|
|
|
-
|
|
|
- kp->flags |= KPROBE_FLAG_DISABLED;
|
|
|
- if (p != kp)
|
|
|
- /* When kp != p, p is always enabled. */
|
|
|
- try_to_disable_aggr_kprobe(p);
|
|
|
-
|
|
|
- if (!kprobes_all_disarmed && kprobe_disabled(p))
|
|
|
- disarm_kprobe(p);
|
|
|
-out:
|
|
|
- mutex_unlock(&kprobe_mutex);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL_GPL(disable_kprobe);
|
|
|
-
|
|
|
-/* Enable one kprobe */
|
|
|
-int __kprobes enable_kprobe(struct kprobe *kp)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
- struct kprobe *p;
|
|
|
-
|
|
|
- mutex_lock(&kprobe_mutex);
|
|
|
-
|
|
|
- /* Check whether specified probe is valid. */
|
|
|
- p = __get_valid_kprobe(kp);
|
|
|
- if (unlikely(p == NULL)) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- if (kprobe_gone(kp)) {
|
|
|
- /* This kprobe has gone, we couldn't enable it. */
|
|
|
- ret = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- if (p != kp)
|
|
|
- kp->flags &= ~KPROBE_FLAG_DISABLED;
|
|
|
-
|
|
|
- if (!kprobes_all_disarmed && kprobe_disabled(p)) {
|
|
|
- p->flags &= ~KPROBE_FLAG_DISABLED;
|
|
|
- arm_kprobe(p);
|
|
|
- }
|
|
|
-out:
|
|
|
- mutex_unlock(&kprobe_mutex);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-EXPORT_SYMBOL_GPL(enable_kprobe);
|
|
|
-
|
|
|
static void __kprobes arm_all_kprobes(void)
|
|
|
{
|
|
|
struct hlist_head *head;
|