Example #1
0
        private int HandleWriteRead(Thread current, UserPtr userBwr, ref Arch.ExceptionRegisters pt_regs)
        {
            var bwr = new binder_write_read();

            if (userBwr.Read(current, out bwr) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            if (bwr.write_size > 0 || bwr.read_size > 0)
            {
                var ret = HandleWriteRead(current, ref pt_regs, userBwr, bwr);
                if (ret < 0)
                {
                    bwr.read_consumed = 0;
                    if (userBwr.Write(current, ref bwr) != 0)
                    {
                        return(-ErrorCode.EFAULT);
                    }
                }
            }

            if (userBwr.Write(current, ref bwr) != 0)
            {
                return(-ErrorCode.EFAULT);
            }

            return(0);
        }
Example #2
0
        internal int Ioctl(Thread current, ref Arch.ExceptionRegisters pt_regs, uint cmd, UserPtr userBuf)
        {
            switch (cmd)
            {
            case BINDER_WRITE_READ:
                return(HandleWriteRead(current, userBuf, ref pt_regs));

            case BINDER_VERSION:
                if (userBuf.Write(current, BINDER_CURRENT_PROTOCOL_VERSION) != 0)
                {
                    return(-ErrorCode.EINVAL);
                }

                return(0);

            case BINDER_SET_IDLE_TIMEOUT:
            case BINDER_SET_MAX_THREADS:
            case BINDER_SET_IDLE_PRIORITY:
            case BINDER_SET_CONTEXT_MGR:
            case BINDER_THREAD_EXIT:
                // skipping
                return(0);

            default:
                return(-ErrorCode.EINVAL);
            }
        }
Example #3
0
        private int HandleWriteRead(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBwr, binder_write_read bwr)
        {
            var writeBuf  = bwr.write_buffer;
            var writeSize = bwr.write_size;
            var buf       = Globals.AllocateAlignedCompletionBuffer(MARSHAL_BUF_PAGES * Arch.ArchDefinition.PageSize);

            if (!buf.isValid)
            {
                return(-ErrorCode.ENOMEM);
            }

            var marshaler = new BinderIPCMarshaler(current, buf);

            if (bwr.write_consumed != 0)
            {
                Arch.Console.WriteLine("BinderINode::HandleWriteRead: write_consumed != 0");
                Utils.Panic();
            }

            var r = marshaler.Marshal(writeBuf, writeSize);

            if (r < 0)
            {
                Arch.Console.WriteLine("Marshaling error");
                Globals.CompletionQueueAllocator.FreePages(new Pointer(buf.Location), MARSHAL_BUF_PAGES);
                return(-1);
            }

            sys_binder_write_desc desc;

            desc.buffer_size         = marshaler.WriteCursor;
            desc.bwr_write_size      = writeSize;
            desc.write_buffer        = new Pointer(buf.Location);
            desc.patch_table_entries = marshaler.CurrentPatchEntry;
            desc.patch_table_offset  = marshaler.PatchTableOffset;
            desc.read_consumed       = 0;
            desc.write_consumed      = 0;

            var binder_cp = new BinderCompletion(current, userBwr, desc, buf);

            r = Arch.IPCStubs.linux_sys_binder_write_read_async(current.Parent.helperPid, current.impl._value.thread._value, desc);

            if (r < 0)
            {
                binder_cp.Dispose();
                return(r);
            }

            Globals.CompletionQueue.Enqueue(binder_cp);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return(0);
        }