diff options
Diffstat (limited to 'net/sunrpc/auth_gss/auth_gss.c')
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 911ef008b701..6ea29f4ed6c0 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -255,7 +255,7 @@ err: | |||
255 | 255 | ||
256 | struct gss_upcall_msg { | 256 | struct gss_upcall_msg { |
257 | atomic_t count; | 257 | atomic_t count; |
258 | uid_t uid; | 258 | kuid_t uid; |
259 | struct rpc_pipe_msg msg; | 259 | struct rpc_pipe_msg msg; |
260 | struct list_head list; | 260 | struct list_head list; |
261 | struct gss_auth *auth; | 261 | struct gss_auth *auth; |
@@ -302,11 +302,11 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | static struct gss_upcall_msg * | 304 | static struct gss_upcall_msg * |
305 | __gss_find_upcall(struct rpc_pipe *pipe, uid_t uid) | 305 | __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid) |
306 | { | 306 | { |
307 | struct gss_upcall_msg *pos; | 307 | struct gss_upcall_msg *pos; |
308 | list_for_each_entry(pos, &pipe->in_downcall, list) { | 308 | list_for_each_entry(pos, &pipe->in_downcall, list) { |
309 | if (pos->uid != uid) | 309 | if (!uid_eq(pos->uid, uid)) |
310 | continue; | 310 | continue; |
311 | atomic_inc(&pos->count); | 311 | atomic_inc(&pos->count); |
312 | dprintk("RPC: %s found msg %p\n", __func__, pos); | 312 | dprintk("RPC: %s found msg %p\n", __func__, pos); |
@@ -394,8 +394,11 @@ gss_upcall_callback(struct rpc_task *task) | |||
394 | 394 | ||
395 | static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) | 395 | static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) |
396 | { | 396 | { |
397 | gss_msg->msg.data = &gss_msg->uid; | 397 | uid_t uid = from_kuid(&init_user_ns, gss_msg->uid); |
398 | gss_msg->msg.len = sizeof(gss_msg->uid); | 398 | memcpy(gss_msg->databuf, &uid, sizeof(uid)); |
399 | gss_msg->msg.data = gss_msg->databuf; | ||
400 | gss_msg->msg.len = sizeof(uid); | ||
401 | BUG_ON(sizeof(uid) > UPCALL_BUF_LEN); | ||
399 | } | 402 | } |
400 | 403 | ||
401 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | 404 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, |
@@ -408,7 +411,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | |||
408 | 411 | ||
409 | gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", | 412 | gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", |
410 | mech->gm_name, | 413 | mech->gm_name, |
411 | gss_msg->uid); | 414 | from_kuid(&init_user_ns, gss_msg->uid)); |
412 | p += gss_msg->msg.len; | 415 | p += gss_msg->msg.len; |
413 | if (clnt->cl_principal) { | 416 | if (clnt->cl_principal) { |
414 | len = sprintf(p, "target=%s ", clnt->cl_principal); | 417 | len = sprintf(p, "target=%s ", clnt->cl_principal); |
@@ -444,7 +447,7 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg, | |||
444 | 447 | ||
445 | static struct gss_upcall_msg * | 448 | static struct gss_upcall_msg * |
446 | gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, | 449 | gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, |
447 | uid_t uid, const char *service_name) | 450 | kuid_t uid, const char *service_name) |
448 | { | 451 | { |
449 | struct gss_upcall_msg *gss_msg; | 452 | struct gss_upcall_msg *gss_msg; |
450 | int vers; | 453 | int vers; |
@@ -474,7 +477,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
474 | struct gss_cred *gss_cred = container_of(cred, | 477 | struct gss_cred *gss_cred = container_of(cred, |
475 | struct gss_cred, gc_base); | 478 | struct gss_cred, gc_base); |
476 | struct gss_upcall_msg *gss_new, *gss_msg; | 479 | struct gss_upcall_msg *gss_new, *gss_msg; |
477 | uid_t uid = cred->cr_uid; | 480 | kuid_t uid = cred->cr_uid; |
478 | 481 | ||
479 | gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); | 482 | gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); |
480 | if (IS_ERR(gss_new)) | 483 | if (IS_ERR(gss_new)) |
@@ -516,7 +519,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
516 | int err = 0; | 519 | int err = 0; |
517 | 520 | ||
518 | dprintk("RPC: %5u %s for uid %u\n", | 521 | dprintk("RPC: %5u %s for uid %u\n", |
519 | task->tk_pid, __func__, cred->cr_uid); | 522 | task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid)); |
520 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); | 523 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); |
521 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 524 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
522 | /* XXX: warning on the first, under the assumption we | 525 | /* XXX: warning on the first, under the assumption we |
@@ -548,7 +551,8 @@ gss_refresh_upcall(struct rpc_task *task) | |||
548 | gss_release_msg(gss_msg); | 551 | gss_release_msg(gss_msg); |
549 | out: | 552 | out: |
550 | dprintk("RPC: %5u %s for uid %u result %d\n", | 553 | dprintk("RPC: %5u %s for uid %u result %d\n", |
551 | task->tk_pid, __func__, cred->cr_uid, err); | 554 | task->tk_pid, __func__, |
555 | from_kuid(&init_user_ns, cred->cr_uid), err); | ||
552 | return err; | 556 | return err; |
553 | } | 557 | } |
554 | 558 | ||
@@ -561,7 +565,8 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | |||
561 | DEFINE_WAIT(wait); | 565 | DEFINE_WAIT(wait); |
562 | int err = 0; | 566 | int err = 0; |
563 | 567 | ||
564 | dprintk("RPC: %s for uid %u\n", __func__, cred->cr_uid); | 568 | dprintk("RPC: %s for uid %u\n", |
569 | __func__, from_kuid(&init_user_ns, cred->cr_uid)); | ||
565 | retry: | 570 | retry: |
566 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); | 571 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); |
567 | if (PTR_ERR(gss_msg) == -EAGAIN) { | 572 | if (PTR_ERR(gss_msg) == -EAGAIN) { |
@@ -603,7 +608,7 @@ out_intr: | |||
603 | gss_release_msg(gss_msg); | 608 | gss_release_msg(gss_msg); |
604 | out: | 609 | out: |
605 | dprintk("RPC: %s for uid %u result %d\n", | 610 | dprintk("RPC: %s for uid %u result %d\n", |
606 | __func__, cred->cr_uid, err); | 611 | __func__, from_kuid(&init_user_ns, cred->cr_uid), err); |
607 | return err; | 612 | return err; |
608 | } | 613 | } |
609 | 614 | ||
@@ -617,7 +622,8 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
617 | struct gss_upcall_msg *gss_msg; | 622 | struct gss_upcall_msg *gss_msg; |
618 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; | 623 | struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; |
619 | struct gss_cl_ctx *ctx; | 624 | struct gss_cl_ctx *ctx; |
620 | uid_t uid; | 625 | uid_t id; |
626 | kuid_t uid; | ||
621 | ssize_t err = -EFBIG; | 627 | ssize_t err = -EFBIG; |
622 | 628 | ||
623 | if (mlen > MSG_BUF_MAXSIZE) | 629 | if (mlen > MSG_BUF_MAXSIZE) |
@@ -632,12 +638,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
632 | goto err; | 638 | goto err; |
633 | 639 | ||
634 | end = (const void *)((char *)buf + mlen); | 640 | end = (const void *)((char *)buf + mlen); |
635 | p = simple_get_bytes(buf, end, &uid, sizeof(uid)); | 641 | p = simple_get_bytes(buf, end, &id, sizeof(id)); |
636 | if (IS_ERR(p)) { | 642 | if (IS_ERR(p)) { |
637 | err = PTR_ERR(p); | 643 | err = PTR_ERR(p); |
638 | goto err; | 644 | goto err; |
639 | } | 645 | } |
640 | 646 | ||
647 | uid = make_kuid(&init_user_ns, id); | ||
648 | if (!uid_valid(uid)) { | ||
649 | err = -EINVAL; | ||
650 | goto err; | ||
651 | } | ||
652 | |||
641 | err = -ENOMEM; | 653 | err = -ENOMEM; |
642 | ctx = gss_alloc_context(); | 654 | ctx = gss_alloc_context(); |
643 | if (ctx == NULL) | 655 | if (ctx == NULL) |
@@ -1058,7 +1070,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
1058 | int err = -ENOMEM; | 1070 | int err = -ENOMEM; |
1059 | 1071 | ||
1060 | dprintk("RPC: %s for uid %d, flavor %d\n", | 1072 | dprintk("RPC: %s for uid %d, flavor %d\n", |
1061 | __func__, acred->uid, auth->au_flavor); | 1073 | __func__, from_kuid(&init_user_ns, acred->uid), |
1074 | auth->au_flavor); | ||
1062 | 1075 | ||
1063 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) | 1076 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) |
1064 | goto out_err; | 1077 | goto out_err; |
@@ -1114,7 +1127,7 @@ out: | |||
1114 | } | 1127 | } |
1115 | if (gss_cred->gc_principal != NULL) | 1128 | if (gss_cred->gc_principal != NULL) |
1116 | return 0; | 1129 | return 0; |
1117 | return rc->cr_uid == acred->uid; | 1130 | return uid_eq(rc->cr_uid, acred->uid); |
1118 | } | 1131 | } |
1119 | 1132 | ||
1120 | /* | 1133 | /* |