]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/rtc/rtc-dev.c
[PATCH] rtc subsystem: add capability checks
[linux-2.6-omap-h63xx.git] / drivers / rtc / rtc-dev.c
index 07387c99df0dbb73b8eec88e1ece8c576ef49965..61a58259c93fe04ed5a502435763a921f3d57cc5 100644 (file)
@@ -214,6 +214,28 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
        struct rtc_wkalrm alarm;
        void __user *uarg = (void __user *) arg;
 
+       /* check that the calles has appropriate permissions
+        * for certain ioctls. doing this check here is useful
+        * to avoid duplicate code in each driver.
+        */
+       switch (cmd) {
+       case RTC_EPOCH_SET:
+       case RTC_SET_TIME:
+               if (!capable(CAP_SYS_TIME))
+                       return -EACCES;
+               break;
+
+       case RTC_IRQP_SET:
+               if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE))
+                       return -EACCES;
+               break;
+
+       case RTC_PIE_ON:
+               if (!capable(CAP_SYS_RESOURCE))
+                       return -EACCES;
+               break;
+       }
+
        /* avoid conflicting IRQ users */
        if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
                spin_lock(&rtc->irq_task_lock);
@@ -272,9 +294,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
                break;
 
        case RTC_SET_TIME:
-               if (!capable(CAP_SYS_TIME))
-                       return -EACCES;
-
                if (copy_from_user(&tm, uarg, sizeof(tm)))
                        return -EFAULT;
 
@@ -290,10 +309,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
                        err = -EINVAL;
                        break;
                }
-               if (!capable(CAP_SYS_TIME)) {
-                       err = -EACCES;
-                       break;
-               }
                rtc_epoch = arg;
                err = 0;
 #endif