|
72 | 72 | #include <linux/spinlock.h>
|
73 | 73 | #include <linux/ratelimit.h>
|
74 | 74 | #include <linux/syscalls.h>
|
| 75 | +#include <linux/task_work.h> |
75 | 76 |
|
76 | 77 | #include <uapi/linux/android/binder.h>
|
77 | 78 |
|
@@ -2170,6 +2171,64 @@ static bool binder_validate_fixup(struct binder_buffer *b,
|
2170 | 2171 | return (fixup_offset >= last_min_offset);
|
2171 | 2172 | }
|
2172 | 2173 |
|
| 2174 | +/** |
| 2175 | + * struct binder_task_work_cb - for deferred close |
| 2176 | + * |
| 2177 | + * @twork: callback_head for task work |
| 2178 | + * @fd: fd to close |
| 2179 | + * |
| 2180 | + * Structure to pass task work to be handled after |
| 2181 | + * returning from binder_ioctl() via task_work_add(). |
| 2182 | + */ |
| 2183 | +struct binder_task_work_cb { |
| 2184 | + struct callback_head twork; |
| 2185 | + struct file *file; |
| 2186 | +}; |
| 2187 | + |
| 2188 | +/** |
| 2189 | + * binder_do_fd_close() - close list of file descriptors |
| 2190 | + * @twork: callback head for task work |
| 2191 | + * |
| 2192 | + * It is not safe to call ksys_close() during the binder_ioctl() |
| 2193 | + * function if there is a chance that binder's own file descriptor |
| 2194 | + * might be closed. This is to meet the requirements for using |
| 2195 | + * fdget() (see comments for __fget_light()). Therefore use |
| 2196 | + * task_work_add() to schedule the close operation once we have |
| 2197 | + * returned from binder_ioctl(). This function is a callback |
| 2198 | + * for that mechanism and does the actual ksys_close() on the |
| 2199 | + * given file descriptor. |
| 2200 | + */ |
| 2201 | +static void binder_do_fd_close(struct callback_head *twork) |
| 2202 | +{ |
| 2203 | + struct binder_task_work_cb *twcb = container_of(twork, |
| 2204 | + struct binder_task_work_cb, twork); |
| 2205 | + |
| 2206 | + fput(twcb->file); |
| 2207 | + kfree(twcb); |
| 2208 | +} |
| 2209 | + |
| 2210 | +/** |
| 2211 | + * binder_deferred_fd_close() - schedule a close for the given file-descriptor |
| 2212 | + * @fd: file-descriptor to close |
| 2213 | + * |
| 2214 | + * See comments in binder_do_fd_close(). This function is used to schedule |
| 2215 | + * a file-descriptor to be closed after returning from binder_ioctl(). |
| 2216 | + */ |
| 2217 | +static void binder_deferred_fd_close(int fd) |
| 2218 | +{ |
| 2219 | + struct binder_task_work_cb *twcb; |
| 2220 | + |
| 2221 | + twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); |
| 2222 | + if (!twcb) |
| 2223 | + return; |
| 2224 | + init_task_work(&twcb->twork, binder_do_fd_close); |
| 2225 | + __close_fd_get_file(fd, &twcb->file); |
| 2226 | + if (twcb->file) |
| 2227 | + task_work_add(current, &twcb->twork, true); |
| 2228 | + else |
| 2229 | + kfree(twcb); |
| 2230 | +} |
| 2231 | + |
2173 | 2232 | static void binder_transaction_buffer_release(struct binder_proc *proc,
|
2174 | 2233 | struct binder_buffer *buffer,
|
2175 | 2234 | binder_size_t *failed_at)
|
@@ -2309,7 +2368,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
|
2309 | 2368 | }
|
2310 | 2369 | fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
|
2311 | 2370 | for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
|
2312 |
| - ksys_close(fd_array[fd_index]); |
| 2371 | + binder_deferred_fd_close(fd_array[fd_index]); |
2313 | 2372 | } break;
|
2314 | 2373 | default:
|
2315 | 2374 | pr_err("transaction release %d bad object type %x\n",
|
@@ -3928,7 +3987,7 @@ static int binder_apply_fd_fixups(struct binder_transaction *t)
|
3928 | 3987 | } else if (ret) {
|
3929 | 3988 | u32 *fdp = (u32 *)(t->buffer->data + fixup->offset);
|
3930 | 3989 |
|
3931 |
| - ksys_close(*fdp); |
| 3990 | + binder_deferred_fd_close(*fdp); |
3932 | 3991 | }
|
3933 | 3992 | list_del(&fixup->fixup_entry);
|
3934 | 3993 | kfree(fixup);
|
|
0 commit comments