Skip to content

Commit 7fd511f

Browse files
committed
nsfs: validate ioctls
Nsfs supports extensible and non-extensible ioctls. Validate both types to prevent confusion. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 2014c95 commit 7fd511f

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

fs/nsfs.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,49 @@ static int copy_ns_info_to_user(const struct mnt_namespace *mnt_ns,
152152
return 0;
153153
}
154154

155+
static bool nsfs_ioctl_valid(unsigned int cmd)
156+
{
157+
switch (cmd) {
158+
case NS_GET_USERNS:
159+
case NS_GET_PARENT:
160+
case NS_GET_NSTYPE:
161+
case NS_GET_OWNER_UID:
162+
case NS_GET_MNTNS_ID:
163+
case NS_GET_PID_FROM_PIDNS:
164+
case NS_GET_TGID_FROM_PIDNS:
165+
case NS_GET_PID_IN_PIDNS:
166+
case NS_GET_TGID_IN_PIDNS:
167+
return (_IOC_TYPE(cmd) == _IOC_TYPE(cmd));
168+
}
169+
170+
/* Extensible ioctls require some extra handling. */
171+
switch (_IOC_NR(cmd)) {
172+
case _IOC_NR(NS_MNT_GET_INFO):
173+
case _IOC_NR(NS_MNT_GET_NEXT):
174+
case _IOC_NR(NS_MNT_GET_PREV):
175+
return (_IOC_TYPE(cmd) == _IOC_TYPE(cmd));
176+
}
177+
178+
return false;
179+
}
180+
155181
static long ns_ioctl(struct file *filp, unsigned int ioctl,
156182
unsigned long arg)
157183
{
158184
struct user_namespace *user_ns;
159185
struct pid_namespace *pid_ns;
160186
struct task_struct *tsk;
161-
struct ns_common *ns = get_proc_ns(file_inode(filp));
187+
struct ns_common *ns;
162188
struct mnt_namespace *mnt_ns;
163189
bool previous = false;
164190
uid_t __user *argp;
165191
uid_t uid;
166192
int ret;
167193

194+
if (!nsfs_ioctl_valid(ioctl))
195+
return -ENOIOCTLCMD;
196+
197+
ns = get_proc_ns(file_inode(filp));
168198
switch (ioctl) {
169199
case NS_GET_USERNS:
170200
return open_related_ns(ns, ns_get_owner);

0 commit comments

Comments
 (0)