From: David Herrmann Date: Thu, 21 May 2015 20:03:29 +0200 Subject: [PATCH] kdbus: skip mandatory items on negotiation The kdbus negotiation is used to figure out what items and flags an ioctl supports. It is highly impractical to pass in mandatory items when all we do is negotiation. Therefore, allow user-space to skip mandatory items if KDBUS_FLAG_NEGOTIATE is passed. Signed-off-by: David Herrmann Acked-by: Daniel Mack --- ipc/kdbus/handle.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ipc/kdbus/handle.c b/ipc/kdbus/handle.c index f72dbe513b4a..3f5d8085a297 100644 --- a/ipc/kdbus/handle.c +++ b/ipc/kdbus/handle.c @@ -71,10 +71,6 @@ static int kdbus_args_verify(struct kdbus_args *args) if (!KDBUS_ITEMS_END(item, args->items, args->items_size)) return -EINVAL; - for (i = 0; i < args->argc; ++i) - if (args->argv[i].mandatory && !args->argv[i].item) - return -EINVAL; - return 0; } @@ -149,7 +145,7 @@ static int kdbus_args_negotiate(struct kdbus_args *args) int __kdbus_args_parse(struct kdbus_args *args, void __user *argp, size_t type_size, size_t items_offset, void **out) { - int ret; + int ret, i; args->cmd = kdbus_memdup_user(argp, type_size, KDBUS_CMD_MAX_SIZE); if (IS_ERR(args->cmd)) @@ -173,6 +169,15 @@ int __kdbus_args_parse(struct kdbus_args *args, void __user *argp, if (ret < 0) goto error; + /* mandatory items must be given (but not on negotiation) */ + if (!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE)) { + for (i = 0; i < args->argc; ++i) + if (args->argv[i].mandatory && !args->argv[i].item) { + ret = -EINVAL; + goto error; + } + } + *out = args->cmd; return !!(args->cmd->flags & KDBUS_FLAG_NEGOTIATE);