autofs: use AUTOFS_DEV_IOCTL_SIZE
[sfrench/cifs-2.6.git] / fs / autofs4 / dev-ioctl.c
index dd9f1bebb5a3a980b55e5d0fb758c93e4f694722..b8b66d55266dc1819f85b10aeb088626df30b55a 100644 (file)
@@ -97,13 +97,13 @@ static struct autofs_dev_ioctl *
 {
        struct autofs_dev_ioctl tmp, *res;
 
-       if (copy_from_user(&tmp, in, sizeof(tmp)))
+       if (copy_from_user(&tmp, in, AUTOFS_DEV_IOCTL_SIZE))
                return ERR_PTR(-EFAULT);
 
-       if (tmp.size < sizeof(tmp))
+       if (tmp.size < AUTOFS_DEV_IOCTL_SIZE)
                return ERR_PTR(-EINVAL);
 
-       if (tmp.size > (PATH_MAX + sizeof(tmp)))
+       if (tmp.size > AUTOFS_DEV_IOCTL_SIZE + PATH_MAX)
                return ERR_PTR(-ENAMETOOLONG);
 
        res = memdup_user(in, tmp.size);
@@ -133,8 +133,8 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
                goto out;
        }
 
-       if (param->size > sizeof(*param)) {
-               err = invalid_str(param->path, param->size - sizeof(*param));
+       if (param->size > AUTOFS_DEV_IOCTL_SIZE) {
+               err = invalid_str(param->path, param->size - AUTOFS_DEV_IOCTL_SIZE);
                if (err) {
                        pr_warn(
                          "path string terminator missing for cmd(0x%08x)\n",
@@ -451,7 +451,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
        dev_t devid;
        int err = -ENOENT;
 
-       if (param->size <= sizeof(*param)) {
+       if (param->size <= AUTOFS_DEV_IOCTL_SIZE) {
                err = -EINVAL;
                goto out;
        }
@@ -539,7 +539,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
        unsigned int devid, magic;
        int err = -ENOENT;
 
-       if (param->size <= sizeof(*param)) {
+       if (param->size <= AUTOFS_DEV_IOCTL_SIZE) {
                err = -EINVAL;
                goto out;
        }
@@ -628,10 +628,6 @@ static int _autofs_dev_ioctl(unsigned int command,
        ioctl_fn fn = NULL;
        int err = 0;
 
-       /* only root can play with this */
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
        cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
        cmd = _IOC_NR(command);
 
@@ -640,6 +636,14 @@ static int _autofs_dev_ioctl(unsigned int command,
                return -ENOTTY;
        }
 
+       /* Only root can use ioctls other than AUTOFS_DEV_IOCTL_VERSION_CMD
+        * and AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
+        */
+       if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD &&
+           cmd != AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD &&
+           !capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
        /* Copy the parameters into kernel space. */
        param = copy_dev_ioctl(user);
        if (IS_ERR(param))
@@ -733,7 +737,8 @@ static const struct file_operations _dev_ioctl_fops = {
 static struct miscdevice _autofs_dev_ioctl_misc = {
        .minor          = AUTOFS_MINOR,
        .name           = AUTOFS_DEVICE_NAME,
-       .fops           = &_dev_ioctl_fops
+       .fops           = &_dev_ioctl_fops,
+       .mode           = 0644,
 };
 
 MODULE_ALIAS_MISCDEV(AUTOFS_MINOR);