Commit 388a910d authored by Trond Myklebust's avatar Trond Myklebust

RPC: remove broken_suid mount option

Remove broken_suid mount option (retry RPC after dropping privileges
upon EACCES): no longer used and questionable w.r.t. security.
Signed-off-by: default avatarFrank van Maarseveen <frankvm@frankvm.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent a9ed1ac1
......@@ -368,7 +368,6 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
clnt->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
clnt->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
clnt->cl_droppriv = (server->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0;
clnt->cl_chatty = 1;
return clnt;
......@@ -540,7 +539,6 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
{ NFS_MOUNT_NOCTO, ",nocto", "" },
{ NFS_MOUNT_NOAC, ",noac", "" },
{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
{ NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },
{ 0, NULL, NULL }
};
struct proc_nfs_info *nfs_infop;
......
......@@ -124,7 +124,6 @@ enum {
Opt_soft, Opt_hard, Opt_intr,
Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
Opt_broken_suid,
/* Error token */
Opt_err
};
......@@ -159,7 +158,6 @@ static match_table_t __initdata tokens = {
{Opt_udp, "udp"},
{Opt_tcp, "proto=tcp"},
{Opt_tcp, "tcp"},
{Opt_broken_suid, "broken_suid"},
{Opt_err, NULL}
};
......@@ -268,9 +266,6 @@ static int __init root_nfs_parse(char *name, char *buf)
case Opt_tcp:
nfs_data.flags |= NFS_MOUNT_TCP;
break;
case Opt_broken_suid:
nfs_data.flags |= NFS_MOUNT_BROKEN_SUID;
break;
default :
return 0;
}
......
......@@ -103,7 +103,7 @@ struct rpc_credops {
void (*crdestroy)(struct rpc_cred *);
int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
u32 * (*crmarshal)(struct rpc_task *, u32 *, int);
u32 * (*crmarshal)(struct rpc_task *, u32 *);
int (*crrefresh)(struct rpc_task *);
u32 * (*crvalidate)(struct rpc_task *, u32 *);
int (*crwrap_req)(struct rpc_task *, kxdrproc_t,
......
......@@ -51,7 +51,6 @@ struct rpc_clnt {
cl_intr : 1,/* interruptible */
cl_chatty : 1,/* be verbose */
cl_autobind : 1,/* use getport() */
cl_droppriv : 1,/* enable NFS suid hack */
cl_oneshot : 1,/* dispose after use */
cl_dead : 1;/* abandoned */
......
......@@ -53,9 +53,8 @@ struct rpc_task {
struct rpc_message tk_msg; /* RPC call info */
__u32 * tk_buffer; /* XDR buffer */
size_t tk_bufsize;
__u8 tk_garb_retry,
tk_cred_retry,
tk_suid_retry;
__u8 tk_garb_retry;
__u8 tk_cred_retry;
unsigned long tk_cookie; /* Cookie for batching tasks */
......@@ -118,9 +117,7 @@ typedef void (*rpc_action)(struct rpc_task *);
*/
#define RPC_TASK_ASYNC 0x0001 /* is an async task */
#define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */
#define RPC_TASK_SETUID 0x0004 /* is setuid process */
#define RPC_TASK_CHILD 0x0008 /* is child of other task */
#define RPC_CALL_REALUID 0x0010 /* try using real uid */
#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
#define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
......@@ -129,7 +126,6 @@ typedef void (*rpc_action)(struct rpc_task *);
#define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */
#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
#define RPC_IS_SETUID(t) ((t)->tk_flags & RPC_TASK_SETUID)
#define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD)
#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
......
......@@ -318,8 +318,7 @@ rpcauth_marshcred(struct rpc_task *task, u32 *p)
dprintk("RPC: %4d marshaling %s cred %p\n",
task->tk_pid, auth->au_ops->au_name, cred);
return cred->cr_ops->crmarshal(task, p,
task->tk_flags & RPC_CALL_REALUID);
return cred->cr_ops->crmarshal(task, p);
}
u32 *
......
......@@ -811,7 +811,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags)
* Maybe we should keep a cached credential for performance reasons.
*/
static u32 *
gss_marshal(struct rpc_task *task, u32 *p, int ruid)
gss_marshal(struct rpc_task *task, u32 *p)
{
struct rpc_cred *cred = task->tk_msg.rpc_cred;
struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
......
......@@ -64,7 +64,7 @@ nul_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
* Marshal credential.
*/
static u32 *
nul_marshal(struct rpc_task *task, u32 *p, int ruid)
nul_marshal(struct rpc_task *task, u32 *p)
{
*p++ = htonl(RPC_AUTH_NULL);
*p++ = 0;
......
......@@ -19,8 +19,6 @@
struct unx_cred {
struct rpc_cred uc_base;
gid_t uc_gid;
uid_t uc_puid; /* process uid */
gid_t uc_pgid; /* process gid */
gid_t uc_gids[NFS_NGROUPS];
};
#define uc_uid uc_base.cr_uid
......@@ -80,8 +78,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
atomic_set(&cred->uc_count, 1);
cred->uc_flags = RPCAUTH_CRED_UPTODATE;
if (flags & RPC_TASK_ROOTCREDS) {
cred->uc_uid = cred->uc_puid = 0;
cred->uc_gid = cred->uc_pgid = 0;
cred->uc_uid = 0;
cred->uc_gid = 0;
cred->uc_gids[0] = NOGROUP;
} else {
int groups = acred->group_info->ngroups;
......@@ -90,8 +88,6 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
cred->uc_uid = acred->uid;
cred->uc_gid = acred->gid;
cred->uc_puid = current->uid;
cred->uc_pgid = current->gid;
for (i = 0; i < groups; i++)
cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
if (i < NFS_NGROUPS)
......@@ -123,9 +119,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
int groups;
if (cred->uc_uid != acred->uid
|| cred->uc_gid != acred->gid
|| cred->uc_puid != current->uid
|| cred->uc_pgid != current->gid)
|| cred->uc_gid != acred->gid)
return 0;
groups = acred->group_info->ngroups;
......@@ -136,8 +130,8 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
return 0;
return 1;
}
return (cred->uc_uid == 0 && cred->uc_puid == 0
&& cred->uc_gid == 0 && cred->uc_pgid == 0
return (cred->uc_uid == 0
&& cred->uc_gid == 0
&& cred->uc_gids[0] == (gid_t) NOGROUP);
}
......@@ -146,7 +140,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
* Maybe we should keep a cached credential for performance reasons.
*/
static u32 *
unx_marshal(struct rpc_task *task, u32 *p, int ruid)
unx_marshal(struct rpc_task *task, u32 *p)
{
struct rpc_clnt *clnt = task->tk_client;
struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred;
......@@ -162,14 +156,8 @@ unx_marshal(struct rpc_task *task, u32 *p, int ruid)
*/
p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
/* Note: we don't use real uid if it involves raising privilege */
if (ruid && cred->uc_puid != 0 && cred->uc_pgid != 0) {
*p++ = htonl((u32) cred->uc_puid);
*p++ = htonl((u32) cred->uc_pgid);
} else {
*p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid);
}
*p++ = htonl((u32) cred->uc_uid);
*p++ = htonl((u32) cred->uc_gid);
hold = p++;
for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
*p++ = htonl((u32) cred->uc_gids[i]);
......
......@@ -870,21 +870,6 @@ call_decode(struct rpc_task *task)
goto out_retry;
}
/*
* The following is an NFS-specific hack to cater for setuid
* processes whose uid is mapped to nobody on the server.
*/
if (task->tk_client->cl_droppriv &&
(ntohl(*p) == NFSERR_ACCES || ntohl(*p) == NFSERR_PERM)) {
if (RPC_IS_SETUID(task) && task->tk_suid_retry) {
dprintk("RPC: %4d retry squashed uid\n", task->tk_pid);
task->tk_flags ^= RPC_CALL_REALUID;
task->tk_action = call_bind;
task->tk_suid_retry--;
goto out_retry;
}
}
task->tk_action = NULL;
if (decode)
......
......@@ -749,13 +749,10 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call
task->tk_client = clnt;
task->tk_flags = flags;
task->tk_exit = callback;
if (current->uid != current->fsuid || current->gid != current->fsgid)
task->tk_flags |= RPC_TASK_SETUID;
/* Initialize retry counters */
task->tk_garb_retry = 2;
task->tk_cred_retry = 2;
task->tk_suid_retry = 1;
task->tk_priority = RPC_PRIORITY_NORMAL;
task->tk_cookie = (unsigned long)current;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment