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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).