[PATCH] rtc subsystem: add capability checks
Centralize CAP_SYS_XXX checks to avoid duplicate code and missing checks in the drivers. Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: Richard Purdie <rpurdie@rpsys.net> Cc: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
56f10c634e
commit
110d693d58
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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");
|
||||||
|
|
||||||
#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
|
||||||
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
|
||||||
/* 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
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue