* Socket C/R additional features
@ 2009-08-24 17:28 Dan Smith
2009-08-24 17:28 ` [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) Dan Smith
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Dan Smith @ 2009-08-24 17:28 UTC (permalink / raw)
To: containers; +Cc: orenl, netdev
This set fixes the missing "goto out" as identified by Serge in the last
patch and attaches acks from Dave and Serge where appropriate.
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) 2009-08-24 17:28 Socket C/R additional features Dan Smith @ 2009-08-24 17:28 ` Dan Smith 2009-08-24 17:48 ` Dave Hansen 2009-08-24 17:28 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith 2009-08-24 17:28 ` [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) Dan Smith 2 siblings, 1 reply; 10+ messages in thread From: Dan Smith @ 2009-08-24 17:28 UTC (permalink / raw) To: containers; +Cc: orenl, netdev Fail on the TIMESTAMPING_* flags for the moment, with a TODO in place to handle them later. Also remove other explicit flag checks because they're no longer copied blindly into the socket object, so existing checks will be sufficient. Changes in v2: - Avoid removing the sock->sk_socket check before sync'ing the socket.flags - Rename sock_rst_flags() to sock_restore_flags() - Rebase on top of Oren's cleanup patch Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Dan Smith <danms@us.ibm.com> --- net/checkpoint.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 102 insertions(+), 11 deletions(-) diff --git a/net/checkpoint.c b/net/checkpoint.c index c64483e..fdbf8e7 100644 --- a/net/checkpoint.c +++ b/net/checkpoint.c @@ -178,10 +178,6 @@ static int sock_cptrst_verify(struct ckpt_hdr_socket *h) if (!ckpt_validate_errno(h->sock.err)) return -EINVAL; - /* None of our supported types use this flag */ - if (h->sock.flags & SOCK_DESTROY) - return -EINVAL; - return 0; } @@ -238,11 +234,97 @@ static int sock_cptrst_bufopts(int op, struct sock *sk, return 0; } +static int sock_restore_flags(struct socket *sock, + struct ckpt_hdr_socket *h) +{ + int ret; + int v = 1; + unsigned long sk_flags = h->sock.flags; + unsigned long sock_flags = h->socket.flags; + + if (test_and_clear_bit(SOCK_URGINLINE, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_KEEPOPEN, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_BROADCAST, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_BROADCAST, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_RCVTSTAMP, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_RCVTSTAMPNS, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_DBG, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_DEBUG, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_LOCALROUTE, &sk_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_DONTROUTE, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + if (test_and_clear_bit(SOCK_PASSCRED, &sock_flags)) { + ret = sock_setsockopt(sock, SOL_SOCKET, SO_PASSCRED, + (char *)&v, sizeof(v)); + if (ret) + return ret; + } + + /* TODO: Handle SOCK_TIMESTAMPING_* flags */ + if (test_bit(SOCK_TIMESTAMPING_TX_HARDWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_TX_SOFTWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_RX_HARDWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_RX_SOFTWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_SOFTWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_RAW_HARDWARE, &sk_flags) || + test_bit(SOCK_TIMESTAMPING_SYS_HARDWARE, &sk_flags)) { + ckpt_debug("SOF_TIMESTAMPING_* flags are not supported\n"); + return -ENOSYS; + } + + /* Anything that is still set in the flags that isn't part of + * our protocol's default set, indicates an error + */ + if (sk_flags & ~sock->sk->sk_flags) { + ckpt_debug("Unhandled sock flags: %lx\n", sk_flags); + return -EINVAL; + } + + return 0; +} + static int sock_cptrst(struct ckpt_ctx *ctx, struct sock *sk, struct ckpt_hdr_socket *h, int op) { if (sk->sk_socket) { - CKPT_COPY(op, h->socket.flags, sk->sk_socket->flags); CKPT_COPY(op, h->socket.state, sk->sk_socket->state); } @@ -259,12 +341,6 @@ static int sock_cptrst(struct ckpt_ctx *ctx, struct sock *sk, CKPT_COPY(op, h->sock.state, sk->sk_state); CKPT_COPY(op, h->sock.backlog, sk->sk_max_ack_backlog); - /* TODO: - * Break out setting each of the flags to use setsockopt() or - * perform proper security check - */ - CKPT_COPY(op, h->sock.flags, sk->sk_flags); - if (sock_cptrst_bufopts(op, sk, h)) return -EINVAL; @@ -298,6 +374,21 @@ static int sock_cptrst(struct ckpt_ctx *ctx, struct sock *sk, return -EINVAL; } + if (op == CKPT_CPT) { + h->sock.flags = sk->sk_flags; + h->socket.flags = sk->sk_socket->flags; + } else { + int ret; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sock_restore_flags(sk->sk_socket, h); + set_fs(old_fs); + if (ret) + return ret; + } + if ((h->socket.state == SS_CONNECTED) && (h->sock.state != TCP_ESTABLISHED)) { ckpt_debug("socket/sock in inconsistent state: %i/%i", -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) 2009-08-24 17:28 ` [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) Dan Smith @ 2009-08-24 17:48 ` Dave Hansen 2009-08-24 18:03 ` Dan Smith 0 siblings, 1 reply; 10+ messages in thread From: Dave Hansen @ 2009-08-24 17:48 UTC (permalink / raw) To: Dan Smith; +Cc: containers, netdev On Mon, 2009-08-24 at 10:28 -0700, Dan Smith wrote: > > +static int sock_restore_flags(struct socket *sock, > + struct ckpt_hdr_socket *h) > +{ > + int ret; > + int v = 1; > + unsigned long sk_flags = h->sock.flags; > + unsigned long sock_flags = h->socket.flags; > + > + if (test_and_clear_bit(SOCK_URGINLINE, &sk_flags)) { > + ret = sock_setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, > + (char *)&v, sizeof(v)); > + if (ret) > + return ret; > + } > + > + if (test_and_clear_bit(SOCK_KEEPOPEN, &sk_flags)) { > + ret = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, > + (char *)&v, sizeof(v)); > + if (ret) > + return ret; > + } Would it make more sense to do this programatically? cr_sock_restore_flag(struct socket *sock, unsigned long sck_flag, struct ckpt_hdr_socket *h, unsigned long sock_flag) { unsigned long sk_flags = h->sock.flags; unsigned long sock_flags = h->socket.flags; if (!test_and_clear_bit(sk, &sk_flags)) return 0; return sock_setsockopt(sock, sock_flag, SO_OOBINLINE, (char *)&v, sizeof(v)); } Then, each call becomes: ret = cr_sock_restore_flag(sock, cr_sock, SOCK_URGINLINE, SO_OOBINLINE); if (ret) return ret; ret = cr_sock_restore_flag(sock, cr_sock, SOCK_KEEPOPEN, SO_KEEPALIVE); if (ret) return ret; Or, you could spell the flags out in a (better named) structure: struct sock_flagpair { unsigned long sock_flag; unsigned long sk_flag; } struct sock_flagpair sock_flagpairs[] = { { SOCK_URGINLINE, SO_OOBINLINE }, { SOCK_KEEPOPEN, SO_KEEPALIVE}, ... }; And just walk through the array to do the restore: static int sock_restore_flags(struct socket *sock, struct ckpt_hdr_socket *h) { int i; for (i = 0; i < ARRAY_SIZE(sock_flagpairs); i++) { int ret; unsigned long sock_flag = sock_flagpairs[i].sock_flag; unsigned long sk_flag = sock_flagpairs[i].sk_flag; ret = cr_sock_restore_flag(sock, cr_sock, sock_flag, sk_flag); if (ret) break; } ... } -- Dave ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) 2009-08-24 17:48 ` Dave Hansen @ 2009-08-24 18:03 ` Dan Smith 0 siblings, 0 replies; 10+ messages in thread From: Dan Smith @ 2009-08-24 18:03 UTC (permalink / raw) To: Dave Hansen; +Cc: containers, netdev DH> Would it make more sense to do this programatically? If it pleases the court, sure :) -- Dan Smith IBM Linux Technology Center email: danms@us.ibm.com ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) 2009-08-24 17:28 Socket C/R additional features Dan Smith 2009-08-24 17:28 ` [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) Dan Smith @ 2009-08-24 17:28 ` Dan Smith 2009-08-25 5:53 ` Oren Laadan 2009-08-24 17:28 ` [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) Dan Smith 2 siblings, 1 reply; 10+ messages in thread From: Dan Smith @ 2009-08-24 17:28 UTC (permalink / raw) To: containers; +Cc: orenl, netdev, Serge Hallyn Make these helpers available to others. Changes in v2: - Avoid checking the groupinfo in ctx->realcred against the current in may_setgid() Cc: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Dan Smith <danms@us.ibm.com> --- include/linux/user.h | 9 +++++++++ kernel/user.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletions(-) diff --git a/include/linux/user.h b/include/linux/user.h index 68daf84..c231e9c 100644 --- a/include/linux/user.h +++ b/include/linux/user.h @@ -1 +1,10 @@ +#ifndef _LINUX_USER_H +#define _LINUX_USER_H + #include <asm/user.h> +#include <linux/sched.h> + +extern int may_setuid(struct user_namespace *ns, uid_t uid); +extern int may_setgid(gid_t gid); + +#endif diff --git a/kernel/user.c b/kernel/user.c index a535ed6..a78fde7 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -604,7 +604,7 @@ int checkpoint_user(struct ckpt_ctx *ctx, void *ptr) return do_checkpoint_user(ctx, (struct user_struct *) ptr); } -static int may_setuid(struct user_namespace *ns, uid_t uid) +int may_setuid(struct user_namespace *ns, uid_t uid) { /* * this next check will one day become @@ -631,6 +631,17 @@ static int may_setuid(struct user_namespace *ns, uid_t uid) return 0; } +int may_setgid(gid_t gid) +{ + if (capable(CAP_SETGID)) + return 1; + + if (in_egroup_p(gid)) + return 1; + + return 0; +} + static struct user_struct *do_restore_user(struct ckpt_ctx *ctx) { struct user_struct *u; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) 2009-08-24 17:28 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith @ 2009-08-25 5:53 ` Oren Laadan 0 siblings, 0 replies; 10+ messages in thread From: Oren Laadan @ 2009-08-25 5:53 UTC (permalink / raw) To: Dan Smith; +Cc: containers, netdev, Serge Hallyn Added, thanks. Dan Smith wrote: > Make these helpers available to others. > > Changes in v2: > - Avoid checking the groupinfo in ctx->realcred against the current in > may_setgid() > > Cc: Serge Hallyn <serue@us.ibm.com> > Signed-off-by: Dan Smith <danms@us.ibm.com> > --- > include/linux/user.h | 9 +++++++++ > kernel/user.c | 13 ++++++++++++- > 2 files changed, 21 insertions(+), 1 deletions(-) > > diff --git a/include/linux/user.h b/include/linux/user.h > index 68daf84..c231e9c 100644 > --- a/include/linux/user.h > +++ b/include/linux/user.h > @@ -1 +1,10 @@ > +#ifndef _LINUX_USER_H > +#define _LINUX_USER_H > + > #include <asm/user.h> > +#include <linux/sched.h> > + > +extern int may_setuid(struct user_namespace *ns, uid_t uid); > +extern int may_setgid(gid_t gid); > + > +#endif > diff --git a/kernel/user.c b/kernel/user.c > index a535ed6..a78fde7 100644 > --- a/kernel/user.c > +++ b/kernel/user.c > @@ -604,7 +604,7 @@ int checkpoint_user(struct ckpt_ctx *ctx, void *ptr) > return do_checkpoint_user(ctx, (struct user_struct *) ptr); > } > > -static int may_setuid(struct user_namespace *ns, uid_t uid) > +int may_setuid(struct user_namespace *ns, uid_t uid) > { > /* > * this next check will one day become > @@ -631,6 +631,17 @@ static int may_setuid(struct user_namespace *ns, uid_t uid) > return 0; > } > > +int may_setgid(gid_t gid) > +{ > + if (capable(CAP_SETGID)) > + return 1; > + > + if (in_egroup_p(gid)) > + return 1; > + > + return 0; > +} > + > static struct user_struct *do_restore_user(struct ckpt_ctx *ctx) > { > struct user_struct *u; ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) 2009-08-24 17:28 Socket C/R additional features Dan Smith 2009-08-24 17:28 ` [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) Dan Smith 2009-08-24 17:28 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith @ 2009-08-24 17:28 ` Dan Smith 2009-08-25 5:54 ` Oren Laadan 2 siblings, 1 reply; 10+ messages in thread From: Dan Smith @ 2009-08-24 17:28 UTC (permalink / raw) To: containers; +Cc: orenl, netdev This saves the uid/gid of the sk_peercred structure in the checkpoint stream. On restart, it uses may_setuid() and may_setgid() to determine if the uid/gid from the checkpoint stream may be used. Changes in v3: - Fix error path when may_setuid() or may_setgid() fail Changes in v2: - Adjust for may_setgid() change Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Dan Smith <danms@us.ibm.com> --- include/linux/checkpoint_hdr.h | 2 ++ net/unix/checkpoint.c | 30 +++++++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h index 4d5c22a..78f1f27 100644 --- a/include/linux/checkpoint_hdr.h +++ b/include/linux/checkpoint_hdr.h @@ -414,6 +414,8 @@ struct ckpt_hdr_socket_unix { struct ckpt_hdr h; __s32 this; __s32 peer; + __u32 peercred_uid; + __u32 peercred_gid; __u32 flags; __u32 laddr_len; __u32 raddr_len; diff --git a/net/unix/checkpoint.c b/net/unix/checkpoint.c index 81252e3..4aff931 100644 --- a/net/unix/checkpoint.c +++ b/net/unix/checkpoint.c @@ -3,6 +3,7 @@ #include <linux/fs_struct.h> #include <linux/checkpoint.h> #include <linux/checkpoint_hdr.h> +#include <linux/user.h> #include <net/af_unix.h> #include <net/tcp_states.h> @@ -94,6 +95,9 @@ int unix_checkpoint(struct ckpt_ctx *ctx, struct socket *sock) goto out; } + un->peercred_uid = sock->sk->sk_peercred.uid; + un->peercred_gid = sock->sk->sk_peercred.gid; + ret = ckpt_write_obj(ctx, (struct ckpt_hdr *) un); if (ret < 0) goto out; @@ -217,19 +221,6 @@ static int unix_join(struct ckpt_ctx *ctx, unix_sk(a)->peer = b; unix_sk(b)->peer = a; - /* TODO: - * Checkpoint the credentials, restore them here if the values match - * the restored creds or we may_setuid() - */ - - a->sk_peercred.pid = task_tgid_vnr(current); - a->sk_peercred.uid = ctx->realcred->uid; - 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; - if (!UNIX_ADDR_EMPTY(un->raddr_len)) addr = unix_makeaddr(&un->raddr, un->raddr_len); else if (!UNIX_ADDR_EMPTY(un->laddr_len)) @@ -295,6 +286,19 @@ static int unix_restore_connected(struct ckpt_ctx *ctx, goto out; } + this->sk_peercred.pid = task_tgid_vnr(current); + + if (may_setuid(ctx->realcred->user->user_ns, un->peercred_uid) && + may_setgid(un->peercred_gid)) { + this->sk_peercred.uid = un->peercred_uid; + this->sk_peercred.gid = un->peercred_gid; + } else { + ckpt_debug("peercred %i:%i would require setuid", + un->peercred_uid, un->peercred_gid); + ret = -EPERM; + goto out; + } + /* Prime the socket's buffer limit with the maximum. These will be * overwritten with the values in the checkpoint stream in a later * phase. -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) 2009-08-24 17:28 ` [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) Dan Smith @ 2009-08-25 5:54 ` Oren Laadan 0 siblings, 0 replies; 10+ messages in thread From: Oren Laadan @ 2009-08-25 5:54 UTC (permalink / raw) To: Dan Smith; +Cc: containers, netdev Added, thanks. Dan Smith wrote: > This saves the uid/gid of the sk_peercred structure in the checkpoint > stream. On restart, it uses may_setuid() and may_setgid() to determine > if the uid/gid from the checkpoint stream may be used. > > Changes in v3: > - Fix error path when may_setuid() or may_setgid() fail > > Changes in v2: > - Adjust for may_setgid() change > > Acked-by: Serge Hallyn <serue@us.ibm.com> > Signed-off-by: Dan Smith <danms@us.ibm.com> > --- > include/linux/checkpoint_hdr.h | 2 ++ > net/unix/checkpoint.c | 30 +++++++++++++++++------------- > 2 files changed, 19 insertions(+), 13 deletions(-) > > diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h > index 4d5c22a..78f1f27 100644 > --- a/include/linux/checkpoint_hdr.h > +++ b/include/linux/checkpoint_hdr.h > @@ -414,6 +414,8 @@ struct ckpt_hdr_socket_unix { > struct ckpt_hdr h; > __s32 this; > __s32 peer; > + __u32 peercred_uid; > + __u32 peercred_gid; > __u32 flags; > __u32 laddr_len; > __u32 raddr_len; > diff --git a/net/unix/checkpoint.c b/net/unix/checkpoint.c > index 81252e3..4aff931 100644 > --- a/net/unix/checkpoint.c > +++ b/net/unix/checkpoint.c > @@ -3,6 +3,7 @@ > #include <linux/fs_struct.h> > #include <linux/checkpoint.h> > #include <linux/checkpoint_hdr.h> > +#include <linux/user.h> > #include <net/af_unix.h> > #include <net/tcp_states.h> > > @@ -94,6 +95,9 @@ int unix_checkpoint(struct ckpt_ctx *ctx, struct socket *sock) > goto out; > } > > + un->peercred_uid = sock->sk->sk_peercred.uid; > + un->peercred_gid = sock->sk->sk_peercred.gid; > + > ret = ckpt_write_obj(ctx, (struct ckpt_hdr *) un); > if (ret < 0) > goto out; > @@ -217,19 +221,6 @@ static int unix_join(struct ckpt_ctx *ctx, > unix_sk(a)->peer = b; > unix_sk(b)->peer = a; > > - /* TODO: > - * Checkpoint the credentials, restore them here if the values match > - * the restored creds or we may_setuid() > - */ > - > - a->sk_peercred.pid = task_tgid_vnr(current); > - a->sk_peercred.uid = ctx->realcred->uid; > - 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; > - > if (!UNIX_ADDR_EMPTY(un->raddr_len)) > addr = unix_makeaddr(&un->raddr, un->raddr_len); > else if (!UNIX_ADDR_EMPTY(un->laddr_len)) > @@ -295,6 +286,19 @@ static int unix_restore_connected(struct ckpt_ctx *ctx, > goto out; > } > > + this->sk_peercred.pid = task_tgid_vnr(current); > + > + if (may_setuid(ctx->realcred->user->user_ns, un->peercred_uid) && > + may_setgid(un->peercred_gid)) { > + this->sk_peercred.uid = un->peercred_uid; > + this->sk_peercred.gid = un->peercred_gid; > + } else { > + ckpt_debug("peercred %i:%i would require setuid", > + un->peercred_uid, un->peercred_gid); > + ret = -EPERM; > + goto out; > + } > + > /* Prime the socket's buffer limit with the maximum. These will be > * overwritten with the values in the checkpoint stream in a later > * phase. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Socket C/R additional features @ 2009-08-18 19:57 Dan Smith 2009-08-18 19:57 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith 0 siblings, 1 reply; 10+ messages in thread From: Dan Smith @ 2009-08-18 19:57 UTC (permalink / raw) To: orenl; +Cc: containers, netdev This is an updated version of my previous patch set, with the fourth patch removed. This is rebased on current v17-dev and includes Serge's recommended changes to may_setgid(). ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) 2009-08-18 19:57 Socket C/R additional features Dan Smith @ 2009-08-18 19:57 ` Dan Smith 2009-08-20 1:31 ` Serge E. Hallyn 0 siblings, 1 reply; 10+ messages in thread From: Dan Smith @ 2009-08-18 19:57 UTC (permalink / raw) To: orenl; +Cc: containers, netdev, Serge Hallyn Make these helpers available to others. Changes in v2: - Avoid checking the groupinfo in ctx->realcred against the current in may_setgid() Cc: Serge Hallyn <serue@us.ibm.com> Signed-off-by: Dan Smith <danms@us.ibm.com> --- include/linux/user.h | 9 +++++++++ kernel/user.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletions(-) diff --git a/include/linux/user.h b/include/linux/user.h index 68daf84..c231e9c 100644 --- a/include/linux/user.h +++ b/include/linux/user.h @@ -1 +1,10 @@ +#ifndef _LINUX_USER_H +#define _LINUX_USER_H + #include <asm/user.h> +#include <linux/sched.h> + +extern int may_setuid(struct user_namespace *ns, uid_t uid); +extern int may_setgid(gid_t gid); + +#endif diff --git a/kernel/user.c b/kernel/user.c index a535ed6..a78fde7 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -604,7 +604,7 @@ int checkpoint_user(struct ckpt_ctx *ctx, void *ptr) return do_checkpoint_user(ctx, (struct user_struct *) ptr); } -static int may_setuid(struct user_namespace *ns, uid_t uid) +int may_setuid(struct user_namespace *ns, uid_t uid) { /* * this next check will one day become @@ -631,6 +631,17 @@ static int may_setuid(struct user_namespace *ns, uid_t uid) return 0; } +int may_setgid(gid_t gid) +{ + if (capable(CAP_SETGID)) + return 1; + + if (in_egroup_p(gid)) + return 1; + + return 0; +} + static struct user_struct *do_restore_user(struct ckpt_ctx *ctx) { struct user_struct *u; -- 1.6.2.5 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) 2009-08-18 19:57 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith @ 2009-08-20 1:31 ` Serge E. Hallyn 0 siblings, 0 replies; 10+ messages in thread From: Serge E. Hallyn @ 2009-08-20 1:31 UTC (permalink / raw) To: Dan Smith; +Cc: orenl, containers, netdev Quoting Dan Smith (danms@us.ibm.com): > Make these helpers available to others. > > Changes in v2: > - Avoid checking the groupinfo in ctx->realcred against the current in > may_setgid() > > Cc: Serge Hallyn <serue@us.ibm.com> Acked-by: Serge Hallyn <serue@us.ibm.com> > Signed-off-by: Dan Smith <danms@us.ibm.com> > --- > include/linux/user.h | 9 +++++++++ > kernel/user.c | 13 ++++++++++++- > 2 files changed, 21 insertions(+), 1 deletions(-) > > diff --git a/include/linux/user.h b/include/linux/user.h > index 68daf84..c231e9c 100644 > --- a/include/linux/user.h > +++ b/include/linux/user.h > @@ -1 +1,10 @@ > +#ifndef _LINUX_USER_H > +#define _LINUX_USER_H > + > #include <asm/user.h> > +#include <linux/sched.h> > + > +extern int may_setuid(struct user_namespace *ns, uid_t uid); > +extern int may_setgid(gid_t gid); > + > +#endif > diff --git a/kernel/user.c b/kernel/user.c > index a535ed6..a78fde7 100644 > --- a/kernel/user.c > +++ b/kernel/user.c > @@ -604,7 +604,7 @@ int checkpoint_user(struct ckpt_ctx *ctx, void *ptr) > return do_checkpoint_user(ctx, (struct user_struct *) ptr); > } > > -static int may_setuid(struct user_namespace *ns, uid_t uid) > +int may_setuid(struct user_namespace *ns, uid_t uid) > { > /* > * this next check will one day become > @@ -631,6 +631,17 @@ static int may_setuid(struct user_namespace *ns, uid_t uid) > return 0; > } > > +int may_setgid(gid_t gid) > +{ > + if (capable(CAP_SETGID)) > + return 1; > + > + if (in_egroup_p(gid)) > + return 1; > + > + return 0; > +} > + > static struct user_struct *do_restore_user(struct ckpt_ctx *ctx) > { > struct user_struct *u; > -- > 1.6.2.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-08-25 5:54 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-08-24 17:28 Socket C/R additional features Dan Smith 2009-08-24 17:28 ` [PATCH 1/3] Set socket flags on restore using sock_setsockopt() where possible (v2) Dan Smith 2009-08-24 17:48 ` Dave Hansen 2009-08-24 18:03 ` Dan Smith 2009-08-24 17:28 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith 2009-08-25 5:53 ` Oren Laadan 2009-08-24 17:28 ` [PATCH 3/3] Save and restore UNIX socket peer credentials (v2) Dan Smith 2009-08-25 5:54 ` Oren Laadan -- strict thread matches above, loose matches on Subject: below -- 2009-08-18 19:57 Socket C/R additional features Dan Smith 2009-08-18 19:57 ` [PATCH 2/3] Expose may_setuid() in user.h and add may_setgid() (v2) Dan Smith 2009-08-20 1:31 ` Serge E. Hallyn
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).