diff options
author | Alessandro Zummo <alessandro.zummo@towertech.it> | 2006-06-25 08:48:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:01:14 -0400 |
commit | 110d693d5898649da606cd6e5f6af4d7f70a405f (patch) | |
tree | a46b06a383d8a9eda59d7c7e17e8694798769800 | |
parent | 56f10c634e145d75e45b56a73f59fb6dff1caa8e (diff) |
[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>
-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, | |||
69 | rtc->id = id; | 69 | rtc->id = id; |
70 | rtc->ops = ops; | 70 | rtc->ops = ops; |
71 | rtc->owner = owner; | 71 | rtc->owner = owner; |
72 | rtc->max_user_freq = 64; | ||
72 | rtc->class_dev.dev = dev; | 73 | rtc->class_dev.dev = dev; |
73 | rtc->class_dev.class = rtc_class; | 74 | rtc->class_dev.class = rtc_class; |
74 | rtc->class_dev.release = rtc_device_release; | 75 | 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, | |||
214 | struct rtc_wkalrm alarm; | 214 | struct rtc_wkalrm alarm; |
215 | void __user *uarg = (void __user *) arg; | 215 | void __user *uarg = (void __user *) arg; |
216 | 216 | ||
217 | /* check that the calles has appropriate permissions | ||
218 | * for certain ioctls. doing this check here is useful | ||
219 | * to avoid duplicate code in each driver. | ||
220 | */ | ||
221 | switch (cmd) { | ||
222 | case RTC_EPOCH_SET: | ||
223 | case RTC_SET_TIME: | ||
224 | if (!capable(CAP_SYS_TIME)) | ||
225 | return -EACCES; | ||
226 | break; | ||
227 | |||
228 | case RTC_IRQP_SET: | ||
229 | if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) | ||
230 | return -EACCES; | ||
231 | break; | ||
232 | |||
233 | case RTC_PIE_ON: | ||
234 | if (!capable(CAP_SYS_RESOURCE)) | ||
235 | return -EACCES; | ||
236 | break; | ||
237 | } | ||
238 | |||
217 | /* avoid conflicting IRQ users */ | 239 | /* avoid conflicting IRQ users */ |
218 | if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { | 240 | if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { |
219 | spin_lock(&rtc->irq_task_lock); | 241 | spin_lock(&rtc->irq_task_lock); |
@@ -272,9 +294,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
272 | break; | 294 | break; |
273 | 295 | ||
274 | case RTC_SET_TIME: | 296 | case RTC_SET_TIME: |
275 | if (!capable(CAP_SYS_TIME)) | ||
276 | return -EACCES; | ||
277 | |||
278 | if (copy_from_user(&tm, uarg, sizeof(tm))) | 297 | if (copy_from_user(&tm, uarg, sizeof(tm))) |
279 | return -EFAULT; | 298 | return -EFAULT; |
280 | 299 | ||
@@ -290,10 +309,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
290 | err = -EINVAL; | 309 | err = -EINVAL; |
291 | break; | 310 | break; |
292 | } | 311 | } |
293 | if (!capable(CAP_SYS_TIME)) { | ||
294 | err = -EACCES; | ||
295 | break; | ||
296 | } | ||
297 | rtc_epoch = arg; | 312 | rtc_epoch = arg; |
298 | err = 0; | 313 | err = 0; |
299 | #endif | 314 | #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, | |||
229 | spin_unlock_irq(&sa1100_rtc_lock); | 229 | spin_unlock_irq(&sa1100_rtc_lock); |
230 | return 0; | 230 | return 0; |
231 | case RTC_PIE_ON: | 231 | case RTC_PIE_ON: |
232 | if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE)) | ||
233 | return -EACCES; | ||
234 | spin_lock_irq(&sa1100_rtc_lock); | 232 | spin_lock_irq(&sa1100_rtc_lock); |
235 | OSMR1 = TIMER_FREQ/rtc_freq + OSCR; | 233 | OSMR1 = TIMER_FREQ/rtc_freq + OSCR; |
236 | OIER |= OIER_E1; | 234 | OIER |= OIER_E1; |
@@ -242,8 +240,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
242 | case RTC_IRQP_SET: | 240 | case RTC_IRQP_SET: |
243 | if (arg < 1 || arg > TIMER_FREQ) | 241 | if (arg < 1 || arg > TIMER_FREQ) |
244 | return -EINVAL; | 242 | return -EINVAL; |
245 | if ((arg > 64) && (!capable(CAP_SYS_RESOURCE))) | ||
246 | return -EACCES; | ||
247 | rtc_freq = arg; | 243 | rtc_freq = arg; |
248 | return 0; | 244 | return 0; |
249 | } | 245 | } |
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"); | |||
81 | 81 | ||
82 | #define RTC_FREQUENCY 32768 | 82 | #define RTC_FREQUENCY 32768 |
83 | #define MAX_PERIODIC_RATE 6553 | 83 | #define MAX_PERIODIC_RATE 6553 |
84 | #define MAX_USER_PERIODIC_RATE 64 | ||
85 | 84 | ||
86 | static void __iomem *rtc1_base; | 85 | static void __iomem *rtc1_base; |
87 | static void __iomem *rtc2_base; | 86 | static void __iomem *rtc2_base; |
@@ -240,9 +239,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
240 | if (arg > MAX_PERIODIC_RATE) | 239 | if (arg > MAX_PERIODIC_RATE) |
241 | return -EINVAL; | 240 | return -EINVAL; |
242 | 241 | ||
243 | if (arg > MAX_USER_PERIODIC_RATE && capable(CAP_SYS_RESOURCE) == 0) | ||
244 | return -EACCES; | ||
245 | |||
246 | periodic_frequency = arg; | 242 | periodic_frequency = arg; |
247 | 243 | ||
248 | count = RTC_FREQUENCY; | 244 | count = RTC_FREQUENCY; |
@@ -263,10 +259,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
263 | /* Doesn't support before 1900 */ | 259 | /* Doesn't support before 1900 */ |
264 | if (arg < 1900) | 260 | if (arg < 1900) |
265 | return -EINVAL; | 261 | return -EINVAL; |
266 | |||
267 | if (capable(CAP_SYS_TIME) == 0) | ||
268 | return -EACCES; | ||
269 | |||
270 | epoch = arg; | 262 | epoch = arg; |
271 | break; | 263 | break; |
272 | default: | 264 | 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 | |||
155 | struct rtc_task *irq_task; | 155 | struct rtc_task *irq_task; |
156 | spinlock_t irq_task_lock; | 156 | spinlock_t irq_task_lock; |
157 | int irq_freq; | 157 | int irq_freq; |
158 | int max_user_freq; | ||
158 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 159 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
159 | struct work_struct uie_task; | 160 | struct work_struct uie_task; |
160 | struct timer_list uie_timer; | 161 | struct timer_list uie_timer; |