diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 82caf98491fa..01fb34b378e0 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1528,10 +1528,11 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } static int fastrpc_init_process(struct fastrpc_file *fl, - struct fastrpc_ioctl_init *init) + struct fastrpc_ioctl_init_attrs *uproc) { int err = 0; struct fastrpc_ioctl_invoke_attrs ioctl; + struct fastrpc_ioctl_init *init = &uproc->init; struct smq_phy_page pages[1]; struct fastrpc_mmap *file = 0, *mem = 0; if (init->flags == FASTRPC_INIT_ATTACH) { @@ -1550,14 +1551,16 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (err) goto bail; } else if (init->flags == FASTRPC_INIT_CREATE) { - remote_arg_t ra[4]; - int fds[4]; + remote_arg_t ra[6]; + int fds[6]; int mflags = 0; struct { int pgid; int namelen; int filelen; int pageslen; + int attrs; + int siglen; } inbuf; inbuf.pgid = current->tgid; inbuf.namelen = strlen(current->comm) + 1; @@ -1593,8 +1596,20 @@ static int fastrpc_init_process(struct fastrpc_file *fl, ra[3].buf.len = 1 * sizeof(*pages); fds[3] = 0; + inbuf.attrs = uproc->attrs; + ra[4].buf.pv = (void *)&(inbuf.attrs); + ra[4].buf.len = sizeof(inbuf.attrs); + fds[4] = 0; + + inbuf.siglen = uproc->siglen; + ra[5].buf.pv = (void *)&(inbuf.siglen); + ra[5].buf.len = sizeof(inbuf.siglen); + fds[5] = 0; + ioctl.inv.handle = 1; ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0); + if (uproc->attrs) + ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0); ioctl.inv.pra = ra; ioctl.fds = fds; ioctl.attrs = 0; @@ -2237,7 +2252,7 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, struct fastrpc_ioctl_invoke_attrs inv; struct fastrpc_ioctl_mmap mmap; struct fastrpc_ioctl_munmap munmap; - struct fastrpc_ioctl_init init; + struct fastrpc_ioctl_init_attrs init; struct fastrpc_ioctl_perf perf; } p; void *param = (char *)ioctl_param; @@ -2333,8 +2348,14 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num, goto bail; break; case FASTRPC_IOCTL_INIT: - VERIFY(err, 0 == copy_from_user(&p.init, param, - sizeof(p.init))); + p.init.attrs = 0; + p.init.siglen = 0; + size = sizeof(struct fastrpc_ioctl_init); + /* fall through */ + case FASTRPC_IOCTL_INIT_ATTRS: + if (!size) + size = sizeof(struct fastrpc_ioctl_init_attrs); + VERIFY(err, 0 == copy_from_user(&p.init, param, size)); if (err) goto bail; VERIFY(err, 0 == fastrpc_init_process(fl, &p.init)); diff --git a/drivers/char/adsprpc_compat.c b/drivers/char/adsprpc_compat.c index a224ba7ed3e4..f7e84dd55606 100644 --- a/drivers/char/adsprpc_compat.c +++ b/drivers/char/adsprpc_compat.c @@ -34,6 +34,8 @@ _IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs) #define COMPAT_FASTRPC_IOCTL_GETPERF \ _IOWR('R', 9, struct compat_fastrpc_ioctl_perf) +#define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \ + _IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs) struct compat_remote_buf { compat_uptr_t pv; /* buffer pointer */ @@ -85,6 +87,12 @@ struct compat_fastrpc_ioctl_init { compat_int_t memfd; /* ION fd for the mem */ }; +struct compat_fastrpc_ioctl_init_attrs { + struct compat_fastrpc_ioctl_init init; + compat_int_t attrs; /* attributes to init process */ + compat_int_t siglen; /* test signature file length */ +}; + struct compat_fastrpc_ioctl_perf { /* kernel performance data */ compat_uptr_t data; compat_int_t numkeys; @@ -246,28 +254,41 @@ static int compat_get_fastrpc_ioctl_perf( } static int compat_get_fastrpc_ioctl_init( - struct compat_fastrpc_ioctl_init __user *init32, - struct fastrpc_ioctl_init __user *init) + struct compat_fastrpc_ioctl_init_attrs __user *init32, + struct fastrpc_ioctl_init_attrs __user *init, + unsigned int cmd) { compat_uint_t u; compat_uptr_t p; compat_int_t i; int err; - err = get_user(u, &init32->flags); - err |= put_user(u, &init->flags); - err |= get_user(p, &init32->file); - err |= put_user(p, &init->file); - err |= get_user(i, &init32->filelen); - err |= put_user(i, &init->filelen); - err |= get_user(i, &init32->filefd); - err |= put_user(i, &init->filefd); - err |= get_user(p, &init32->mem); - err |= put_user(p, &init->mem); - err |= get_user(i, &init32->memlen); - err |= put_user(i, &init->memlen); - err |= get_user(i, &init32->memfd); - err |= put_user(i, &init->memfd); + err = get_user(u, &init32->init.flags); + err |= put_user(u, &init->init.flags); + err |= get_user(p, &init32->init.file); + err |= put_user(p, &init->init.file); + err |= get_user(i, &init32->init.filelen); + err |= put_user(i, &init->init.filelen); + err |= get_user(i, &init32->init.filefd); + err |= put_user(i, &init->init.filefd); + err |= get_user(p, &init32->init.mem); + err |= put_user(p, &init->init.mem); + err |= get_user(i, &init32->init.memlen); + err |= put_user(i, &init->init.memlen); + err |= get_user(i, &init32->init.memfd); + err |= put_user(i, &init->init.memfd); + + err |= put_user(0, &init->attrs); + if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) { + err |= get_user(i, &init32->attrs); + err |= put_user(i, (compat_uptr_t *)&init->attrs); + } + + err |= put_user(0, &init->siglen); + if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) { + err |= get_user(i, &init32->siglen); + err |= put_user(i, (compat_uptr_t *)&init->siglen); + } return err; } @@ -340,9 +361,11 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, (unsigned long)unmap); } case COMPAT_FASTRPC_IOCTL_INIT: + /* fall through */ + case COMPAT_FASTRPC_IOCTL_INIT_ATTRS: { - struct compat_fastrpc_ioctl_init __user *init32; - struct fastrpc_ioctl_init __user *init; + struct compat_fastrpc_ioctl_init_attrs __user *init32; + struct fastrpc_ioctl_init_attrs __user *init; init32 = compat_ptr(arg); VERIFY(err, NULL != (init = compat_alloc_user_space( @@ -350,11 +373,11 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd, if (err) return -EFAULT; VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32, - init)); + init, cmd)); if (err) return err; - return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_INIT, - (unsigned long)init); + return filp->f_op->unlocked_ioctl(filp, + FASTRPC_IOCTL_INIT_ATTRS, (unsigned long)init); } case FASTRPC_IOCTL_GETINFO: { diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 9b24e2da489f..f686b0a1d6fa 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -26,6 +26,7 @@ _IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs) #define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t) #define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf) +#define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs) #define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp" #define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" @@ -158,6 +159,12 @@ struct fastrpc_ioctl_init { int32_t memfd; /* ION fd for the mem */ }; +struct fastrpc_ioctl_init_attrs { + struct fastrpc_ioctl_init init; + int attrs; + int siglen; +}; + struct fastrpc_ioctl_munmap { uintptr_t vaddrout; /* address to unmap */ ssize_t size; /* size */