diff options
-rw-r--r-- | drivers/rtc/class.c | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-dev.c | 29 | ||||
-rw-r--r-- | drivers/rtc/rtc-sa1100.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-vr41xx.c | 8 | ||||
-rw-r--r-- | include/linux/rtc.h | 1 |
5 files changed, 24 insertions, 19 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 413c7d54ea10..5396beec30d0 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -69,6 +69,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->id = id; rtc->ops = ops; rtc->owner = owner; + rtc->max_user_freq = 64; rtc->class_dev.dev = dev; rtc->class_dev.class = rtc_class; rtc->class_dev.release = rtc_device_release; diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 07387c99df0d..61a58259c93f 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -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 diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index a997529f8926..ab486fbc828d 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -229,8 +229,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, spin_unlock_irq(&sa1100_rtc_lock); return 0; case RTC_PIE_ON: - if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) - return -EACCES; spin_lock_irq(&sa1100_rtc_lock); OSMR1 = TIMER_FREQ/rtc_freq + OSCR; OIER |= OIER_E1; @@ -242,8 +240,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, case RTC_IRQP_SET: if (arg < 1 || arg > TIMER_FREQ) return -EINVAL; - if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) - return -EACCES; rtc_freq = arg; return 0; } diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 277596c302e3..33e029207e26 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -81,7 +81,6 @@ MODULE_LICENSE("GPL"); #define RTC_FREQUENCY 32768 #define MAX_PERIODIC_RATE 6553 -#define MAX_USER_PERIODIC_RATE 64 static void __iomem *rtc1_base; static void __iomem *rtc2_base; @@ -240,9 +239,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long if (arg > MAX_PERIODIC_RATE) return -EINVAL; - if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) - return -EACCES; - periodic_frequency = arg; count = RTC_FREQUENCY; @@ -263,10 +259,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long /* Doesn't support before 1900 */ if (arg < 1900) return -EINVAL; - - if (capable(CAP_SYS_TIME) == 0) - return -EACCES; - epoch = arg; break; default: diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 43310760fe73..c12cbc1b83c5 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -155,6 +155,7 @@ struct rtc_device struct rtc_task *irq_task; spinlock_t irq_task_lock; int irq_freq; + int max_user_freq; #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL struct work_struct uie_task; struct timer_list uie_timer; |