Skip to content

Commit

Permalink
coda: Restrict coda messages to the initial user namespace
Browse files Browse the repository at this point in the history
Remove the slight chance that uids and gids in coda messages will be
interpreted in the wrong user namespace.

- Only allow processes in the initial user namespace to open the coda
  character device to communicate with coda filesystems.
- Explicitly convert the uids in the coda header into the initial user
  namespace.
- In coda_vattr_to_attr make kuids and kgids from the initial user
  namespace uids and gids in struct coda_vattr that just came from
  userspace.
- In coda_iattr_to_vattr convert kuids and kgids into uids and gids
  in the intial user namespace and store them in struct coda_vattr for
  sending to coda userspace programs.

Nothing needs to be changed with mounts as coda does not support
being mounted in anything other than the initial user namespace.

Cc: Jan Harkes <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
  • Loading branch information
ebiederm committed Feb 13, 2013
1 parent 9fd973e commit d83f590
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 8 deletions.
8 changes: 4 additions & 4 deletions fs/coda/coda_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
if (attr->va_mode != (u_short) -1)
inode->i_mode = attr->va_mode | inode_type;
if (attr->va_uid != -1)
inode->i_uid = (uid_t) attr->va_uid;
inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid);
if (attr->va_gid != -1)
inode->i_gid = (gid_t) attr->va_gid;
inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid);
if (attr->va_nlink != -1)
set_nlink(inode, attr->va_nlink);
if (attr->va_size != -1)
Expand Down Expand Up @@ -171,10 +171,10 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)
vattr->va_mode = iattr->ia_mode;
}
if ( valid & ATTR_UID ) {
vattr->va_uid = (vuid_t) iattr->ia_uid;
vattr->va_uid = (vuid_t) from_kuid(&init_user_ns, iattr->ia_uid);
}
if ( valid & ATTR_GID ) {
vattr->va_gid = (vgid_t) iattr->ia_gid;
vattr->va_gid = (vgid_t) from_kgid(&init_user_ns, iattr->ia_gid);
}
if ( valid & ATTR_SIZE ) {
vattr->va_size = iattr->ia_size;
Expand Down
3 changes: 3 additions & 0 deletions fs/coda/psdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,9 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
if (task_active_pid_ns(current) != &init_pid_ns)
return -EINVAL;

if (current_user_ns() != &init_user_ns)
return -EINVAL;

idx = iminor(inode);
if (idx < 0 || idx >= MAX_CODADEVS)
return -ENODEV;
Expand Down
6 changes: 3 additions & 3 deletions fs/coda/upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void *alloc_upcall(int opcode, int size)
inp->ih.opcode = opcode;
inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns);
inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns);
inp->ih.uid = current_fsuid();
inp->ih.uid = from_kuid(&init_user_ns, current_fsuid());

return (void*)inp;
}
Expand Down Expand Up @@ -157,7 +157,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,
}

int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
vuid_t uid)
kuid_t uid)
{
union inputArgs *inp;
union outputArgs *outp;
Expand All @@ -166,7 +166,7 @@ int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
insize = SIZE(release);
UPARG(CODA_CLOSE);

inp->ih.uid = uid;
inp->ih.uid = from_kuid(&init_user_ns, uid);
inp->coda_close.VFid = *fid;
inp->coda_close.flags = flags;

Expand Down
2 changes: 1 addition & 1 deletion include/linux/coda_psdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,
const char *name, int length, int *type,
struct CodaFid *resfid);
int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
vuid_t uid);
kuid_t uid);
int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
struct file **f);
int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid,
Expand Down

0 comments on commit d83f590

Please sign in to comment.