From: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
To: Serge Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>,
Sukadev Bhattiprolu
<sukadev-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Cc: Linux Containers
<containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org>,
Paul Menage <menage-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH 2/4] The character devices layer changes
Date: Thu, 07 Feb 2008 15:59:04 +0300 [thread overview]
Message-ID: <47AB0098.8010003@openvz.org> (raw)
In-Reply-To: <47AAFFF2.9030804-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
These changes include the API for the control group
to map/remap/unmap the devices with their permissions
and one important thing.
The fact is that the struct cdev is cached in the inode
for faster access, so once we looked one up we go through
the fast path and omit the kobj_lookup() call. This is no
longer good when we restrict the access to cdevs. Another
problem is that different char devices may use one struct
cdev object, so having an access to one of them grants us
access to another, so we have to re-lookup the kobj map
each open.
Signed-off-by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
---
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 2c7a8b5..ddacab7 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -22,6 +22,8 @@
#include <linux/mutex.h>
#include <linux/backing-dev.h>
+#include <linux/devscontrol.h>
+
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
@@ -362,17 +364,31 @@ int chrdev_open(struct inode * inode, struct file * filp)
struct cdev *p;
struct cdev *new = NULL;
int ret = 0;
+ struct kobj_map *map;
+
+ map = task_cdev_map(current);
+ if (map == NULL)
+ map = cdev_map;
spin_lock(&cdev_lock);
p = inode->i_cdev;
- if (!p) {
+ if (!p || map != cdev_map) {
struct kobject *kobj;
int idx;
+ mode_t mode;
+
spin_unlock(&cdev_lock);
- kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
+ kobj = kobj_lookup(map, inode->i_rdev, &mode, &idx);
if (!kobj)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
+ BUG_ON(p != NULL && p != new);
+
+ if ((filp->f_mode & mode) != filp->f_mode) {
+ cdev_put(new);
+ return -EACCES;
+ }
+
spin_lock(&cdev_lock);
p = inode->i_cdev;
if (!p) {
@@ -461,6 +477,53 @@ int cdev_add(struct cdev *p, dev_t dev, unsigned count)
return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}
+#ifdef CONFIG_CGROUP_DEVS
+int cdev_add_to_map(struct kobj_map *map, dev_t dev, int all, mode_t mode)
+{
+ int tmp;
+ struct kobject *k;
+ struct cdev *c;
+
+ k = kobj_lookup(cdev_map, dev, NULL, &tmp);
+ if (k == NULL)
+ return -ENODEV;
+
+ c = container_of(k, struct cdev, kobj);
+ tmp = kobj_remap(map, dev, mode, all ? MINORMASK : 1, NULL,
+ exact_match, exact_lock, c);
+ if (tmp < 0) {
+ cdev_put(c);
+ return tmp;
+ }
+
+ return 0;
+}
+
+int cdev_del_from_map(struct kobj_map *map, dev_t dev, int all)
+{
+ int tmp;
+ struct kobject *k;
+ struct cdev *c;
+
+ k = kobj_lookup(cdev_map, dev, NULL, &tmp);
+ if (k == NULL)
+ return -ENODEV;
+
+ c = container_of(k, struct cdev, kobj);
+ kobj_unmap(map, dev, all ? MINORMASK : 1);
+
+ cdev_put(c);
+ cdev_put(c);
+ return 0;
+}
+
+void cdev_iterate_map(struct kobj_map *map,
+ int (*fn)(dev_t, int, mode_t, void *), void *x)
+{
+ kobj_map_iterate(map, fn, x);
+}
+#endif
+
static void cdev_unmap(dev_t dev, unsigned count)
{
kobj_unmap(cdev_map, dev, count);
@@ -540,9 +603,19 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
return NULL;
}
+struct kobj_map *cdev_map_init(void)
+{
+ return kobj_map_init(base_probe, &chrdevs_lock);
+}
+
+void cdev_map_fini(struct kobj_map *map)
+{
+ kobj_map_fini(map);
+}
+
void __init chrdev_init(void)
{
- cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
+ cdev_map = cdev_map_init();
bdi_init(&directly_mappable_cdev_bdi);
}
diff --git a/include/linux/cdev.h b/include/linux/cdev.h
index 1e29b13..fe0e560 100644
--- a/include/linux/cdev.h
+++ b/include/linux/cdev.h
@@ -9,6 +9,7 @@
struct file_operations;
struct inode;
struct module;
+struct kobj_map;
struct cdev {
struct kobject kobj;
@@ -33,5 +34,11 @@ void cd_forget(struct inode *);
extern struct backing_dev_info directly_mappable_cdev_bdi;
+int cdev_add_to_map(struct kobj_map *map, dev_t dev, int all, mode_t mode);
+int cdev_del_from_map(struct kobj_map *map, dev_t dev, int all);
+struct kobj_map *cdev_map_init(void);
+void cdev_map_fini(struct kobj_map *map);
+void cdev_iterate_map(struct kobj_map *,
+ int (*fn)(dev_t, int, mode_t, void *), void *);
#endif
#endif
next prev parent reply other threads:[~2008-02-07 12:59 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-07 12:56 [PATCH 0/4] Devices accessibility control group (v3, release candidate) Pavel Emelyanov
[not found] ` <47AAFFF2.9030804-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-02-07 12:57 ` [PATCH 1/4] Some changes in the kobject mapper Pavel Emelyanov
2008-02-07 12:59 ` Pavel Emelyanov [this message]
2008-02-07 12:59 ` [PATCH 3/4] The block devices layer changes Pavel Emelyanov
2008-02-07 13:01 ` [PATCH 4/4] The control group itself Pavel Emelyanov
[not found] ` <47AB013B.8060502-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-02-11 17:38 ` Serge E. Hallyn
[not found] ` <20080211173830.GA22160-6s5zFf/epYL1ENwx4SLHqw@public.gmane.org>
2008-02-12 10:28 ` Pavel Emelyanov
[not found] ` <47B174B2.5010500-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-02-12 17:21 ` Serge E. Hallyn
[not found] ` <20080212172134.GA12177-6s5zFf/epYLPQpwDFJZrxKsjOiXwFzmk@public.gmane.org>
2008-02-13 2:17 ` Paul Menage
[not found] ` <6599ad830802121817n7713fa85h51aedf4df74aa764-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-02-13 2:42 ` Paul Jackson
[not found] ` <20080212204215.2eca689f.pj-sJ/iWh9BUns@public.gmane.org>
2008-02-14 17:17 ` Serge E. Hallyn
2008-02-13 2:32 ` Paul Jackson
[not found] ` <20080212203215.fb636900.pj-sJ/iWh9BUns@public.gmane.org>
2008-02-14 17:18 ` Serge E. Hallyn
2008-02-12 7:42 ` sukadev-r/Jw6+rmf7HQT0dZR+AlfA
[not found] ` <20080212074217.GA15992-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2008-02-12 7:51 ` Pavel Emelyanov
2008-02-21 20:47 ` Paul Menage
[not found] ` <6599ad830802211247t21fdc4e4hfe637fcffd98ded7-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-02-22 8:12 ` Pavel Emelyanov
[not found] ` <47BE83FD.7060908-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-02-23 23:12 ` Paul Menage
[not found] ` <6599ad830802231512t20343cabq738df3039c8a1d1f-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2008-02-26 7:54 ` Pavel Emelyanov
2008-02-08 16:12 ` [PATCH 0/4] Devices accessibility control group (v3, release candidate) Serge E. Hallyn
-- strict thread matches above, loose matches on Subject: below --
2008-01-08 9:02 [PATCH 0/4] Devices accessibility control group (v2) Pavel Emelyanov
[not found] ` <47833C3A.8090106-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-01-08 9:12 ` [PATCH 2/4] The character devices layer changes Pavel Emelyanov
[not found] ` <47833E93.6010108-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-01-14 17:03 ` Serge E. Hallyn
[not found] ` <20080114170333.GA15077-6s5zFf/epYLPQpwDFJZrxKsjOiXwFzmk@public.gmane.org>
2008-01-15 8:05 ` Pavel Emelyanov
[not found] ` <478C6942.4050903-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
2008-01-15 14:54 ` Serge E. Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47AB0098.8010003@openvz.org \
--to=xemul-gefaqzzx7r8dnm+yrofe0a@public.gmane.org \
--cc=containers-qjLDD68F18O7TbgM5vRIOg@public.gmane.org \
--cc=menage-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
--cc=sukadev-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.