ANDROID: binder: retry security_secid_to_secctx()
security_secid_to_secctx() can fail because of a GFP_ATOMIC allocation
This needs to be retried from userspace. However, binder driver doesn't
propagate specific enough error codes just yet (WIP b/28321379). We'll
retry on the binder driver as a temporary work around until userspace
can do this instead.
Bug: 174806915
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Change-Id: Ifebddeb7adf9707613512952b97ab702f0d2d592
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 5e4bb83..735b35e 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3223,9 +3223,28 @@
if (target_node && target_node->txn_security_ctx) {
u32 secid;
size_t added_size;
+ int max_retries = 100;
security_task_getsecid(proc->tsk, &secid);
+ retry_alloc:
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
+ if (ret == -ENOMEM && max_retries-- > 0) {
+ struct page *dummy_page;
+
+ /*
+ * security_secid_to_secctx() can fail because of a
+ * GFP_ATOMIC allocation in which case -ENOMEM is
+ * returned. This needs to be retried, but there is
+ * currently no way to tell userspace to retry so we
+ * do it here. We make sure there is still available
+ * memory first and then retry.
+ */
+ dummy_page = alloc_page(GFP_KERNEL);
+ if (dummy_page) {
+ __free_page(dummy_page);
+ goto retry_alloc;
+ }
+ }
if (ret) {
return_error = BR_FAILED_REPLY;
return_error_param = ret;