From: Jakub Kicinski <kuba@kernel.org>
To: Li Li <dualli@chromium.org>
Cc: dualli@google.com, corbet@lwn.net, davem@davemloft.net,
edumazet@google.com, pabeni@redhat.com, donald.hunter@gmail.com,
gregkh@linuxfoundation.org, arve@android.com, tkjos@android.com,
maco@android.com, joel@joelfernandes.org, brauner@kernel.org,
cmllamas@google.com, surenb@google.com, arnd@arndb.de,
masahiroy@kernel.org, bagasdotme@gmail.com, horms@kernel.org,
linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
netdev@vger.kernel.org, hridya@google.com, smoreland@google.com,
kernel-team@android.com
Subject: Re: [PATCH net-next v8 2/2] binder: report txn errors via generic netlink
Date: Wed, 4 Dec 2024 18:35:50 -0800 [thread overview]
Message-ID: <20241204183550.6e9d703f@kernel.org> (raw)
In-Reply-To: <20241113193239.2113577-3-dualli@chromium.org>
On Wed, 13 Nov 2024 11:32:39 -0800 Li Li wrote:
> +/**
> + * binder_find_proc() - set binder report flags
> + * @pid: the target process
> + */
> +static struct binder_proc *binder_find_proc(int pid)
> +{
> + struct binder_proc *proc;
> +
> + mutex_lock(&binder_procs_lock);
> + hlist_for_each_entry(proc, &binder_procs, proc_node) {
> + if (proc->pid == pid) {
> + mutex_unlock(&binder_procs_lock);
> + return proc;
> + }
> + }
> + mutex_unlock(&binder_procs_lock);
> +
> + return NULL;
> +}
> +
> +/**
> + * binder_genl_set_report() - set binder report flags
> + * @context: the binder context to set the flags
> + * @pid: the target process
> + * @flags: the flags to set
> + *
> + * If pid is 0, the flags are applied to the whole binder context.
> + * Otherwise, the flags are applied to the specific process only.
> + */
> +static int binder_genl_set_report(struct binder_context *context, u32 pid,
> + u32 flags)
> +{
> + struct binder_proc *proc;
> +
> + if (flags != (flags & (BINDER_GENL_FLAG_OVERRIDE
> + | BINDER_GENL_FLAG_FAILED
> + | BINDER_GENL_FLAG_DELAYED
> + | BINDER_GENL_FLAG_SPAM))) {
> + pr_err("Invalid binder report flags: %u\n", flags);
> + return -EINVAL;
no need, netlink already checks that only bits from the flags are used:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+ [BINDER_GENL_A_CMD_FLAGS] = NLA_POLICY_MASK(NLA_U32, 0xf),
> + }
> +
> + if (!pid) {
> + /* Set the global flags for the whole binder context */
> + context->report_flags = flags;
> + } else {
> + /* Set the per-process flags */
> + proc = binder_find_proc(pid);
> + if (!proc) {
> + pr_err("Invalid binder report pid %u\n", pid);
> + return -EINVAL;
> + }
> +
> + proc->report_flags = flags;
> + }
> +
> + return 0;
> +}
> +static void binder_genl_send_report(struct binder_context *context, u32 err,
> + u32 pid, u32 tid, u32 to_pid, u32 to_tid,
> + u32 reply,
> + struct binder_transaction_data *tr)
> +{
> + int payload;
> + int ret;
> + struct sk_buff *skb;
> + void *hdr;
> +
> + trace_binder_send_report(context->name, err, pid, tid, to_pid, to_tid,
> + reply, tr);
> +
> + payload = nla_total_size(strlen(context->name) + 1) +
> + nla_total_size(sizeof(u32)) * (BINDER_GENL_A_REPORT_MAX - 1);
> + skb = genlmsg_new(payload + GENL_HDRLEN, GFP_KERNEL);
genlmsg_new() adds the GENL_HDRLEN already
> + if (!skb) {
> + pr_err("Failed to alloc binder genl message\n");
> + return;
> + }
> +
> + hdr = genlmsg_put(skb, 0, atomic_inc_return(&context->report_seq),
> + &binder_genl_nl_family, 0, BINDER_GENL_CMD_REPORT);
> + if (!hdr)
> + goto free_skb;
> +
> + if (nla_put_string(skb, BINDER_GENL_A_REPORT_CONTEXT, context->name) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_ERR, err) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_FROM_PID, pid) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_FROM_TID, tid) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_TO_PID, to_pid) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_TO_TID, to_tid) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_REPLY, reply) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_FLAGS, tr->flags) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_CODE, tr->code) ||
> + nla_put_u32(skb, BINDER_GENL_A_REPORT_DATA_SIZE, tr->data_size))
> + goto cancel_skb;
> +
> + genlmsg_end(skb, hdr);
> +
> + ret = genlmsg_unicast(&init_net, skb, context->report_portid);
> + if (ret < 0)
> + pr_err("Failed to send binder genl message to %d: %d\n",
> + context->report_portid, ret);
> + return;
> +
> +cancel_skb:
> + pr_err("Failed to add report attributes to binder genl message\n");
> + genlmsg_cancel(skb, hdr);
> +free_skb:
> + pr_err("Free binder genl report message on error\n");
> + nlmsg_free(skb);
> +}
> +/**
> + * binder_genl_nl_set_doit() - .doit handler for BINDER_GENL_CMD_SET
> + * @skb: the metadata struct passed from netlink driver
> + * @info: the generic netlink struct passed from netlink driver
> + *
> + * Implements the .doit function to process binder genl commands.
> + */
> +int binder_genl_nl_set_doit(struct sk_buff *skb, struct genl_info *info)
> +{
> + int payload;
> + int portid;
> + u32 pid;
> + u32 flags;
> + void *hdr;
> + struct binder_device *device;
> + struct binder_context *context = NULL;
> +
> + if (GENL_REQ_ATTR_CHECK(info, BINDER_GENL_A_CMD_CONTEXT) ||
> + GENL_REQ_ATTR_CHECK(info, BINDER_GENL_A_CMD_PID) ||
> + GENL_REQ_ATTR_CHECK(info, BINDER_GENL_A_CMD_FLAGS))
> + return -EINVAL;
> +
> + hlist_for_each_entry(device, &binder_devices, hlist) {
> + if (!nla_strcmp(info->attrs[BINDER_GENL_A_CMD_CONTEXT],
> + device->context.name)) {
> + context = &device->context;
> + break;
> + }
> + }
> +
> + if (!context) {
> + NL_SET_ERR_MSG(info->extack, "Unknown binder context\n");
> + return -EINVAL;
> + }
> +
> + portid = nlmsg_hdr(skb)->nlmsg_pid;
> + pid = nla_get_u32(info->attrs[BINDER_GENL_A_CMD_PID]);
> + flags = nla_get_u32(info->attrs[BINDER_GENL_A_CMD_FLAGS]);
> +
> + if (context->report_portid && context->report_portid != portid) {
> + NL_SET_ERR_MSG_FMT(info->extack,
> + "No permission to set flags from %d\n",
> + portid);
> + return -EPERM;
> + }
> +
> + if (binder_genl_set_report(context, pid, flags) < 0) {
> + pr_err("Failed to set report flags %u for %u\n", flags, pid);
> + return -EINVAL;
> + }
> +
> + payload = nla_total_size(sizeof(pid)) + nla_total_size(sizeof(flags));
> + skb = genlmsg_new(payload + GENL_HDRLEN, GFP_KERNEL);
> + if (!skb) {
> + pr_err("Failed to alloc binder genl reply message\n");
> + return -ENOMEM;
no need for error messages on allocation failures, kernel will print an
OOM report
> + }
> +
> + hdr = genlmsg_iput(skb, info);
> + if (!hdr)
> + goto free_skb;
> +
> + if (nla_put_string(skb, BINDER_GENL_A_CMD_CONTEXT, context->name) ||
Have you counted strlen(context->name) to payload?
TBH for small messages counting payload size is probably an overkill,
you can use NLMSG_GOODSIZE as the size of the skb.
> + nla_put_u32(skb, BINDER_GENL_A_CMD_PID, pid) ||
> + nla_put_u32(skb, BINDER_GENL_A_CMD_FLAGS, flags))
> + goto cancel_skb;
> +
> + genlmsg_end(skb, hdr);
> +
> + if (genlmsg_reply(skb, info)) {
> + pr_err("Failed to send binder genl reply message\n");
> + return -EFAULT;
> + }
> +
> + if (!context->report_portid)
> + context->report_portid = portid;
Is there any locking required?
> + return 0;
> +
> +cancel_skb:
> + pr_err("Failed to add reply attributes to binder genl message\n");
> + genlmsg_cancel(skb, hdr);
> +free_skb:
> + pr_err("Free binder genl reply message on error\n");
> + nlmsg_free(skb);
> + return -EMSGSIZE;
> +}
next prev parent reply other threads:[~2024-12-05 2:35 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-13 19:32 [PATCH net-next v8 0/2] binder: report txn errors via generic netlink Li Li
2024-11-13 19:32 ` [PATCH net-next v8 1/2] tools: ynl-gen: allow uapi headers in sub-dirs Li Li
2024-11-13 19:32 ` [PATCH net-next v8 2/2] binder: report txn errors via generic netlink Li Li
2024-11-17 7:23 ` kernel test robot
2024-12-05 2:35 ` Jakub Kicinski [this message]
2024-12-05 12:01 ` Li Li
2024-12-06 0:33 ` Jakub Kicinski
2024-11-19 2:37 ` [PATCH net-next v8 0/2] " Jakub Kicinski
2024-11-19 2:50 ` patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241204183550.6e9d703f@kernel.org \
--to=kuba@kernel.org \
--cc=arnd@arndb.de \
--cc=arve@android.com \
--cc=bagasdotme@gmail.com \
--cc=brauner@kernel.org \
--cc=cmllamas@google.com \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=dualli@chromium.org \
--cc=dualli@google.com \
--cc=edumazet@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=horms@kernel.org \
--cc=hridya@google.com \
--cc=joel@joelfernandes.org \
--cc=kernel-team@android.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maco@android.com \
--cc=masahiroy@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=smoreland@google.com \
--cc=surenb@google.com \
--cc=tkjos@android.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.