diff options
Diffstat (limited to 'drivers/android/binder.c')
-rw-r--r-- | drivers/android/binder.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a73596a4f804..bccec9de0533 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
@@ -1948,6 +1948,26 @@ static void binder_send_failed_reply(struct binder_transaction *t, | |||
1948 | } | 1948 | } |
1949 | 1949 | ||
1950 | /** | 1950 | /** |
1951 | * binder_cleanup_transaction() - cleans up undelivered transaction | ||
1952 | * @t: transaction that needs to be cleaned up | ||
1953 | * @reason: reason the transaction wasn't delivered | ||
1954 | * @error_code: error to return to caller (if synchronous call) | ||
1955 | */ | ||
1956 | static void binder_cleanup_transaction(struct binder_transaction *t, | ||
1957 | const char *reason, | ||
1958 | uint32_t error_code) | ||
1959 | { | ||
1960 | if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) { | ||
1961 | binder_send_failed_reply(t, error_code); | ||
1962 | } else { | ||
1963 | binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, | ||
1964 | "undelivered transaction %d, %s\n", | ||
1965 | t->debug_id, reason); | ||
1966 | binder_free_transaction(t); | ||
1967 | } | ||
1968 | } | ||
1969 | |||
1970 | /** | ||
1951 | * binder_validate_object() - checks for a valid metadata object in a buffer. | 1971 | * binder_validate_object() - checks for a valid metadata object in a buffer. |
1952 | * @buffer: binder_buffer that we're parsing. | 1972 | * @buffer: binder_buffer that we're parsing. |
1953 | * @offset: offset in the buffer at which to validate an object. | 1973 | * @offset: offset in the buffer at which to validate an object. |
@@ -4015,12 +4035,20 @@ retry: | |||
4015 | if (put_user(cmd, (uint32_t __user *)ptr)) { | 4035 | if (put_user(cmd, (uint32_t __user *)ptr)) { |
4016 | if (t_from) | 4036 | if (t_from) |
4017 | binder_thread_dec_tmpref(t_from); | 4037 | binder_thread_dec_tmpref(t_from); |
4038 | |||
4039 | binder_cleanup_transaction(t, "put_user failed", | ||
4040 | BR_FAILED_REPLY); | ||
4041 | |||
4018 | return -EFAULT; | 4042 | return -EFAULT; |
4019 | } | 4043 | } |
4020 | ptr += sizeof(uint32_t); | 4044 | ptr += sizeof(uint32_t); |
4021 | if (copy_to_user(ptr, &tr, sizeof(tr))) { | 4045 | if (copy_to_user(ptr, &tr, sizeof(tr))) { |
4022 | if (t_from) | 4046 | if (t_from) |
4023 | binder_thread_dec_tmpref(t_from); | 4047 | binder_thread_dec_tmpref(t_from); |
4048 | |||
4049 | binder_cleanup_transaction(t, "copy_to_user failed", | ||
4050 | BR_FAILED_REPLY); | ||
4051 | |||
4024 | return -EFAULT; | 4052 | return -EFAULT; |
4025 | } | 4053 | } |
4026 | ptr += sizeof(tr); | 4054 | ptr += sizeof(tr); |
@@ -4090,15 +4118,9 @@ static void binder_release_work(struct binder_proc *proc, | |||
4090 | struct binder_transaction *t; | 4118 | struct binder_transaction *t; |
4091 | 4119 | ||
4092 | t = container_of(w, struct binder_transaction, work); | 4120 | t = container_of(w, struct binder_transaction, work); |
4093 | if (t->buffer->target_node && | 4121 | |
4094 | !(t->flags & TF_ONE_WAY)) { | 4122 | binder_cleanup_transaction(t, "process died.", |
4095 | binder_send_failed_reply(t, BR_DEAD_REPLY); | 4123 | BR_DEAD_REPLY); |
4096 | } else { | ||
4097 | binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, | ||
4098 | "undelivered transaction %d\n", | ||
4099 | t->debug_id); | ||
4100 | binder_free_transaction(t); | ||
4101 | } | ||
4102 | } break; | 4124 | } break; |
4103 | case BINDER_WORK_RETURN_ERROR: { | 4125 | case BINDER_WORK_RETURN_ERROR: { |
4104 | struct binder_error *e = container_of( | 4126 | struct binder_error *e = container_of( |