Commit 110d693d authored by Alessandro Zummo's avatar Alessandro Zummo Committed by Linus Torvalds

[PATCH] rtc subsystem: add capability checks

Centralize CAP_SYS_XXX checks to avoid duplicate code and missing checks in
the drivers.
Signed-off-by: default avatarAlessandro Zummo <a.zummo@towertech.it>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 56f10c63
...@@ -69,6 +69,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, ...@@ -69,6 +69,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
rtc->id = id; rtc->id = id;
rtc->ops = ops; rtc->ops = ops;
rtc->owner = owner; rtc->owner = owner;
rtc->max_user_freq = 64;
rtc->class_dev.dev = dev; rtc->class_dev.dev = dev;
rtc->class_dev.class = rtc_class; rtc->class_dev.class = rtc_class;
rtc->class_dev.release = rtc_device_release; rtc->class_dev.release = rtc_device_release;
......
...@@ -214,6 +214,28 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, ...@@ -214,6 +214,28 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
struct rtc_wkalrm alarm; struct rtc_wkalrm alarm;
void __user *uarg = (void __user *) arg; 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 */ /* avoid conflicting IRQ users */
if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
spin_lock(&rtc->irq_task_lock); spin_lock(&rtc->irq_task_lock);
...@@ -272,9 +294,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, ...@@ -272,9 +294,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
break; break;
case RTC_SET_TIME: case RTC_SET_TIME:
if (!capable(CAP_SYS_TIME))
return -EACCES;
if (copy_from_user(&tm, uarg, sizeof(tm))) if (copy_from_user(&tm, uarg, sizeof(tm)))
return -EFAULT; return -EFAULT;
...@@ -290,10 +309,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, ...@@ -290,10 +309,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
err = -EINVAL; err = -EINVAL;
break; break;
} }
if (!capable(CAP_SYS_TIME)) {
err = -EACCES;
break;
}
rtc_epoch = arg; rtc_epoch = arg;
err = 0; err = 0;
#endif #endif
......
...@@ -229,8 +229,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, ...@@ -229,8 +229,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
spin_unlock_irq(&sa1100_rtc_lock); spin_unlock_irq(&sa1100_rtc_lock);
return 0; return 0;
case RTC_PIE_ON: case RTC_PIE_ON:
if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
return -EACCES;
spin_lock_irq(&sa1100_rtc_lock); spin_lock_irq(&sa1100_rtc_lock);
OSMR1 = TIMER_FREQ/rtc_freq + OSCR; OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
OIER |= OIER_E1; OIER |= OIER_E1;
...@@ -242,8 +240,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, ...@@ -242,8 +240,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
case RTC_IRQP_SET: case RTC_IRQP_SET:
if (arg < 1 || arg > TIMER_FREQ) if (arg < 1 || arg > TIMER_FREQ)
return -EINVAL; return -EINVAL;
if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
return -EACCES;
rtc_freq = arg; rtc_freq = arg;
return 0; return 0;
} }
......
...@@ -81,7 +81,6 @@ MODULE_LICENSE("GPL"); ...@@ -81,7 +81,6 @@ MODULE_LICENSE("GPL");
#define RTC_FREQUENCY 32768 #define RTC_FREQUENCY 32768
#define MAX_PERIODIC_RATE 6553 #define MAX_PERIODIC_RATE 6553
#define MAX_USER_PERIODIC_RATE 64
static void __iomem *rtc1_base; static void __iomem *rtc1_base;
static void __iomem *rtc2_base; static void __iomem *rtc2_base;
...@@ -240,9 +239,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ...@@ -240,9 +239,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
if (arg > MAX_PERIODIC_RATE) if (arg > MAX_PERIODIC_RATE)
return -EINVAL; return -EINVAL;
if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0)
return -EACCES;
periodic_frequency = arg; periodic_frequency = arg;
count = RTC_FREQUENCY; count = RTC_FREQUENCY;
...@@ -263,10 +259,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ...@@ -263,10 +259,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
/* Doesn't support before 1900 */ /* Doesn't support before 1900 */
if (arg < 1900) if (arg < 1900)
return -EINVAL; return -EINVAL;
if (capable(CAP_SYS_TIME) == 0)
return -EACCES;
epoch = arg; epoch = arg;
break; break;
default: default:
......
...@@ -155,6 +155,7 @@ struct rtc_device ...@@ -155,6 +155,7 @@ struct rtc_device
struct rtc_task *irq_task; struct rtc_task *irq_task;
spinlock_t irq_task_lock; spinlock_t irq_task_lock;
int irq_freq; int irq_freq;
int max_user_freq;
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
struct work_struct uie_task; struct work_struct uie_task;
struct timer_list uie_timer; struct timer_list uie_timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment