|
@@ -4661,6 +4661,42 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int binder_ioctl_get_node_info_for_ref(struct binder_proc *proc,
|
|
|
+ struct binder_node_info_for_ref *info)
|
|
|
+{
|
|
|
+ struct binder_node *node;
|
|
|
+ struct binder_context *context = proc->context;
|
|
|
+ __u32 handle = info->handle;
|
|
|
+
|
|
|
+ if (info->strong_count || info->weak_count || info->reserved1 ||
|
|
|
+ info->reserved2 || info->reserved3) {
|
|
|
+ binder_user_error("%d BINDER_GET_NODE_INFO_FOR_REF: only handle may be non-zero.",
|
|
|
+ proc->pid);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* This ioctl may only be used by the context manager */
|
|
|
+ mutex_lock(&context->context_mgr_node_lock);
|
|
|
+ if (!context->binder_context_mgr_node ||
|
|
|
+ context->binder_context_mgr_node->proc != proc) {
|
|
|
+ mutex_unlock(&context->context_mgr_node_lock);
|
|
|
+ return -EPERM;
|
|
|
+ }
|
|
|
+ mutex_unlock(&context->context_mgr_node_lock);
|
|
|
+
|
|
|
+ node = binder_get_node_from_ref(proc, handle, true, NULL);
|
|
|
+ if (!node)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ info->strong_count = node->local_strong_refs +
|
|
|
+ node->internal_strong_refs;
|
|
|
+ info->weak_count = node->local_weak_refs;
|
|
|
+
|
|
|
+ binder_put_node(node);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,
|
|
|
struct binder_node_debug_info *info)
|
|
|
{
|
|
@@ -4755,6 +4791,25 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
+ case BINDER_GET_NODE_INFO_FOR_REF: {
|
|
|
+ struct binder_node_info_for_ref info;
|
|
|
+
|
|
|
+ if (copy_from_user(&info, ubuf, sizeof(info))) {
|
|
|
+ ret = -EFAULT;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = binder_ioctl_get_node_info_for_ref(proc, &info);
|
|
|
+ if (ret < 0)
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ if (copy_to_user(ubuf, &info, sizeof(info))) {
|
|
|
+ ret = -EFAULT;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
case BINDER_GET_NODE_DEBUG_INFO: {
|
|
|
struct binder_node_debug_info info;
|
|
|
|