Re: How does binder pass File Descriptors between processes

1,603 views
Skip to first unread message

Glenn Kasten

unread,
Mar 18, 2013, 8:00:47 PM3/18/13
to android-...@googlegroups.com
It's similar to the way sendmsg can send file descriptors over UNIX domain sockets
(this is an over-simplification, but there's more public documentation about sendmsg/recvmsg
and the ancillary data mechanism, so you should be able to apply some of the concepts to understanding how binder does it)

On Monday, March 18, 2013 3:59:46 PM UTC-7, 竹下幸夫 wrote:
Hi there, I tried to read the binder driver but it's impossible for me to understand, and actually understanding it at this level only helps me adding one or two lines to my presentation so it's not worth sticking my nose too much into the low level code. I only have a quick question here: how does a binder pass FD from this process to another? How could it make the receiver be able to handle the file? Does it change the receiver's file descriptor table?
Thank you so much.

Kaspter Ju

unread,
Mar 18, 2013, 10:10:38 PM3/18/13
to android-...@googlegroups.com
On 03/19/2013 06:59 AM, 竹下幸夫 wrote:
> Hi there, I tried to read the binder driver but it's impossible for me to
> understand, and actually understanding it at this level only helps me
> adding one or two lines to my presentation so it's not worth sticking my
> nose too much into the low level code. I only have a quick question here:
> how does a binder pass FD from this process to another? How could it make
> the receiver be able to handle the file? Does it change the receiver's file
> descriptor table?
> Thank you so much.
>

Hi 竹下幸夫,

see userspace code here:
status_t Parcel::writeFileDescriptor(int fd)
{
flat_binder_object obj;
obj.type = BINDER_TYPE_FD;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
obj.handle = fd;
obj.cookie = (void*)0;
return writeObject(obj, true);
}


and the driver code below:
------------------
case BINDER_TYPE_FD: {
int target_fd;
struct file *file;

if (reply) {
if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}
} else if (!target_node->accept_fds) {
binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fd_not_allowed;
}

file = fget(fp->handle);
if (file == NULL) {
binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
goto err_fget_failed;
}
target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
if (target_fd < 0) {
fput(file);
return_error = BR_FAILED_REPLY;
goto err_get_unused_fd_failed;
}
task_fd_install(target_proc, target_fd, file);
binder_debug(BINDER_DEBUG_TRANSACTION,
" fd %ld -> %d\n", fp->handle, target_fd);
/* TODO: fput? */
fp->handle = target_fd;
} break;
-------------

as you can see, the binder driver open the same file in the target process..

--
Kaspter Ju

gopal krishna shukla

unread,
Aug 31, 2016, 11:53:48 AM8/31/16
to android-platform
           file = fget(fp->handle); 
           if (file == NULL) { 
               binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", 
                   proc->pid, thread->pid, fp->handle); 
               return_error = BR_FAILED_REPLY; 
               goto err_fget_failed; 


here what is the meaning of invalid fd? Is that fd got closed or there could be multiple reason of that ?
please elaborate
Reply all
Reply to author
Forward
0 new messages