From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Dan Smith <danms@us.ibm.com>
Cc: containers@lists.osdl.org, Alexey Dobriyan <adobriyan@gmail.com>,
netdev@vger.kernel.org
Subject: Re: [PATCH 5/5] c/r: Add AF_UNIX support (v7)
Date: Tue, 4 Aug 2009 17:31:41 -0500 [thread overview]
Message-ID: <20090804223141.GA14254@us.ibm.com> (raw)
In-Reply-To: <1249331463-11887-6-git-send-email-danms@us.ibm.com>
Quoting Dan Smith (danms@us.ibm.com):
> +static int sock_read_buffer_sendmsg(struct ckpt_ctx *ctx, struct sock *sock)
> +{
> + struct msghdr msg;
> + struct kvec kvec;
> + int ret = 0;
> + int len;
> +
> + memset(&msg, 0, sizeof(msg));
> +
> + len = _ckpt_read_obj_type(ctx, NULL, 0, CKPT_HDR_SOCKET_BUFFER);
> + if (len < 0)
> + return len;
> +
> + if (len > SKB_MAX_ALLOC) {
> + ckpt_debug("Socket buffer too big (%i > %lu)",
> + len, SKB_MAX_ALLOC);
> + return -ENOSPC;
> + }
> +
> + kvec.iov_len = len;
> + kvec.iov_base = kmalloc(len, GFP_KERNEL);
> + if (!kvec.iov_base)
> + return -ENOMEM;
> +
> + ret = ckpt_kread(ctx, kvec.iov_base, len);
> + if (ret < 0)
> + goto out;
> +
> + ret = kernel_sendmsg(sock->sk_socket, &msg, &kvec, 1, len);
> + ckpt_debug("kernel_sendmsg(%i): %i\n", len, ret);
> + if ((ret > 0) && (ret != len))
> + ret = -ENOMEM;
> + out:
> + if (ret)
why only free iov_base if ret!=0?
> + kfree(kvec.iov_base);
> +
> + return ret;
> +}
> +
> +static struct ckpt_hdr_socket_queue *sock_read_buffer_hdr(struct ckpt_ctx *ctx,
> + uint32_t *bufsize)
> +{
> + struct ckpt_hdr_socket_queue *h;
> + int err = 0;
> +
> + h = ckpt_read_obj_type(ctx, sizeof(*h), CKPT_HDR_SOCKET_QUEUE);
> + if (IS_ERR(h))
> + return h;
> +
> + if (!bufsize) {
> + if (h->total_bytes != 0) {
> + ckpt_debug("Expected empty buffer, got %u\n",
> + h->total_bytes);
> + err = -EINVAL;
> + }
> + } else if (h->total_bytes > *bufsize) {
> + /* NB: We let CAP_NET_ADMIN override the system buffer limit
> + * as setsockopt() does
> + */
> + if (capable(CAP_NET_ADMIN))
> + *bufsize = h->total_bytes;
> + else {
> + ckpt_debug("Buffer total %u exceeds limit %u\n",
> + h->total_bytes, *bufsize);
> + err = -EINVAL;
> + }
> + }
> +
> + if (err) {
> + ckpt_hdr_put(ctx, h);
> + return ERR_PTR(err);
> + } else
> + return h;
> +}
> +
> +static int sock_unix_read_buffers(struct ckpt_ctx *ctx,
> + struct sock *sock,
> + uint32_t *bufsize)
> +{
> + uint8_t sock_shutdown;
> + struct ckpt_hdr_socket_queue *h;
> + int ret = 0;
> + int i;
> +
> + h = sock_read_buffer_hdr(ctx, bufsize);
> + if (IS_ERR(h))
> + return PTR_ERR(h);
> +
> + /* If peer is shutdown, unshutdown it for this process */
> + sock_shutdown = sock->sk_shutdown;
> + sock->sk_shutdown &= ~SHUTDOWN_MASK;
> +
> + for (i = 0; i < h->skb_count; i++) {
> + ret = sock_read_buffer_sendmsg(ctx, sock);
> + ckpt_debug("read_buffer_sendmsg(%i): %i\n", i, ret);
> + if (ret < 0)
> + break;
> +
> + if (ret > h->total_bytes) {
> + ckpt_debug("Buffers exceeded claim");
> + ret = -EINVAL;
> + break;
> + }
> +
> + h->total_bytes -= ret;
> + ret = 0;
> + }
> +
> + sock->sk_shutdown = sock_shutdown;
> + ckpt_hdr_put(ctx, h);
> +
> + return ret;
> +}
> +
> +static struct unix_address *sock_unix_makeaddr(struct sockaddr_un *sun_addr,
> + unsigned len)
> +{
> + struct unix_address *addr;
> +
> + if (len > sizeof(struct sockaddr_un))
> + return ERR_PTR(-EINVAL);
> +
> + addr = kmalloc(sizeof(*addr) + len, GFP_KERNEL);
> + if (!addr)
> + return ERR_PTR(-ENOMEM);
> +
> + memcpy(addr->name, sun_addr, len);
> + addr->len = len;
> + atomic_set(&addr->refcnt, 1);
> +
> + return addr;
> +}
> +
> +static int sock_unix_join(struct ckpt_ctx *ctx,
> + struct sock *a,
> + struct sock *b,
> + struct ckpt_hdr_socket_unix *un)
> +{
> + struct unix_address *addr = NULL;
> +
> + /* FIXME: Do we need to call some security hooks here? */
> +
> + sock_hold(a);
> + sock_hold(b);
> +
> + unix_sk(a)->peer = b;
> + unix_sk(b)->peer = a;
> +
> + a->sk_peercred.pid = task_tgid_vnr(current);
> + a->sk_peercred.uid = ctx->realcred->uid;
I don't know how much it matters, but of course root could
be restarting a set of tasks owned by several non-root uids,
and the peercred.uid's might need to be something other than
ctx->realcred->uid. Or not?
> + a->sk_peercred.gid = ctx->realcred->gid;
> +
> + b->sk_peercred.pid = a->sk_peercred.pid;
> + b->sk_peercred.uid = a->sk_peercred.uid;
> + b->sk_peercred.gid = a->sk_peercred.gid;
> +
-serge
next prev parent reply other threads:[~2009-08-04 22:31 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1249331463-11887-1-git-send-email-danms@us.ibm.com>
2009-08-03 20:31 ` [PATCH 3/5] Add common socket helpers to unify the security hooks Dan Smith
2009-08-04 19:20 ` Serge E. Hallyn
2009-08-04 19:43 ` Dan Smith
2009-08-04 19:58 ` Serge E. Hallyn
2009-08-03 20:31 ` [PATCH 5/5] c/r: Add AF_UNIX support (v7) Dan Smith
2009-08-04 19:57 ` Serge E. Hallyn
2009-08-04 20:52 ` Serge E. Hallyn
2009-08-04 21:02 ` Dan Smith
2009-08-04 21:17 ` Serge E. Hallyn
2009-08-04 22:24 ` Dan Smith
2009-08-04 22:31 ` Serge E. Hallyn [this message]
2009-08-04 22:47 ` Dan Smith
2009-08-05 13:29 ` Serge E. Hallyn
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=20090804223141.GA14254@us.ibm.com \
--to=serue@us.ibm.com \
--cc=adobriyan@gmail.com \
--cc=containers@lists.osdl.org \
--cc=danms@us.ibm.com \
--cc=netdev@vger.kernel.org \
/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).