Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+22 −7
Original line number Diff line number Diff line
@@ -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
+0 −4
Original line number Diff line number Diff line
@@ -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;
	}
+0 −8
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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;