From pjones@redhat.com Sat Jun 25 09:19:56 2005 Subject: /sys/block/hda/sample.sh From: Peter Jones To: gregkh@suse.de Date: Sat, 25 Jun 2005 11:57:46 -0400 Message-Id: <1119715067.22239.1.camel@localhost.localdomain> Greg, here's a patch. I'm thinking maybe the selinux context should be a config option or a sysctl, but if distros care it's easy to patch it to the right thing or just replace it at runtime. From: Peter Jones Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 34 ++++++++++++++++++++++++++++++++++ drivers/block/genhd.c | 25 +++++++++++++++++++++++++ fs/partitions/check.c | 27 +++++++++++++++++++++++++++ include/linux/device.h | 1 + 4 files changed, 87 insertions(+) --- gregkh-2.6.orig/drivers/block/genhd.c 2005-08-17 09:53:44.000000000 -0700 +++ gregkh-2.6/drivers/block/genhd.c 2005-08-17 09:59:14.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include #define MAX_PROBE_HASH 255 /* random */ @@ -382,6 +383,25 @@ static ssize_t disk_stats_read(struct ge jiffies_to_msecs(disk_stat_read(disk, io_ticks)), jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); } +static ssize_t disk_sample_read(struct gendisk * disk, char *page) +{ + char buf[BDEVNAME_SIZE]; + const char * context = "system_u:object_r:fixed_disk_device_t"; + struct vfsmount *mnt; + int n; + + n = sprintf(page, "#!/bin/sh\nmknod "); + + mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL); + if (!IS_ERR(mnt)) { + mntput(mnt); + n += sprintf(page+n, "-Z %s ", context); + } + n += sprintf(page+n, "/dev/%s b %d %d\n", disk_name(disk, 0, buf), + disk->major, disk->first_minor); + + return n; +} static struct disk_attribute disk_attr_dev = { .attr = {.name = "dev", .mode = S_IRUGO }, .show = disk_dev_read @@ -402,6 +422,10 @@ static struct disk_attribute disk_attr_s .attr = {.name = "stat", .mode = S_IRUGO }, .show = disk_stats_read }; +static struct disk_attribute disk_attr_sample = { + .attr = {.name = "sample.sh", .mode = S_IRUSR | S_IXUSR | S_IRUGO }, + .show = disk_sample_read +}; static struct attribute * default_attrs[] = { &disk_attr_dev.attr, @@ -409,6 +433,7 @@ static struct attribute * default_attrs[ &disk_attr_removable.attr, &disk_attr_size.attr, &disk_attr_stat.attr, + &disk_attr_sample.attr, NULL, }; --- gregkh-2.6.orig/fs/partitions/check.c 2005-08-17 09:53:44.000000000 -0700 +++ gregkh-2.6/fs/partitions/check.c 2005-08-17 09:59:14.000000000 -0700 @@ -36,6 +36,8 @@ #include "ultrix.h" #include "efi.h" +#include + #ifdef CONFIG_BLK_DEV_MD extern void md_autodetect_dev(dev_t dev); #endif @@ -229,6 +231,26 @@ static ssize_t part_stat_read(struct hd_ p->reads, (unsigned long long)p->read_sectors, p->writes, (unsigned long long)p->write_sectors); } +static ssize_t part_sample_read(struct hd_struct * p, char *page) +{ + struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); + char buf[BDEVNAME_SIZE]; + const char * context = "system_u:object_r:fixed_disk_device_t"; + struct vfsmount *mnt; + int n; + + n = sprintf(page, "#!/bin/sh\nmknod "); + + mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL); + if (!IS_ERR(mnt)) { + mntput(mnt); + n += sprintf(page+n, "-Z %s ", context); + } + n += sprintf(page+n, "/dev/%s b %d %d\n", disk_name(disk, p->partno, buf), + disk->major, disk->first_minor + p->partno); + + return n; +} static struct part_attribute part_attr_dev = { .attr = {.name = "dev", .mode = S_IRUGO }, .show = part_dev_read @@ -245,12 +267,17 @@ static struct part_attribute part_attr_s .attr = {.name = "stat", .mode = S_IRUGO }, .show = part_stat_read }; +static struct part_attribute part_attr_sample = { + .attr = {.name = "sample.sh", .mode = S_IRUSR | S_IXUSR | S_IRUGO }, + .show = part_sample_read +}; static struct attribute * default_attrs[] = { &part_attr_dev.attr, &part_attr_start.attr, &part_attr_size.attr, &part_attr_stat.attr, + &part_attr_sample.attr, NULL, }; --- gregkh-2.6.orig/drivers/base/class.c 2005-08-17 09:59:12.000000000 -0700 +++ gregkh-2.6/drivers/base/class.c 2005-08-17 09:59:14.000000000 -0700 @@ -17,6 +17,7 @@ #include #include #include +#include #include "base.h" #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) @@ -445,6 +446,24 @@ static ssize_t show_dev(struct class_dev return print_dev_t(buf, class_dev->devt); } +static ssize_t show_sample(struct class_device *class_dev, char *buf) +{ + const char * context = "system_u:object_r:fixed_disk_device_t"; + struct vfsmount *mnt; + int n; + + n = sprintf(buf, "#!/bin/sh\nmknod "); + + mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL); + if (!IS_ERR(mnt)) { + mntput(mnt); + n += sprintf(buf+n, "-Z %s ", context); + } + n += sprintf(buf+n, "/dev/%s c %d %d\n", kobject_name(&class_dev->kobj), + MAJOR(class_dev->devt), MINOR(class_dev->devt)); + + return n; +} void class_device_initialize(struct class_device *class_dev) { kobj_set_kset_s(class_dev, class_obj_subsys); @@ -497,6 +516,21 @@ int class_device_add(struct class_device attr->store = NULL; class_device_create_file(class_dev, attr); class_dev->devt_attr = attr; + + attr = kmalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) { + error = -ENOMEM; + kobject_del(&class_dev->kobj); + goto register_done; + } + memset(attr, sizeof(*attr), 0x00); + attr->attr.name = "sample.sh"; + attr->attr.mode = S_IRUSR | S_IXUSR | S_IRUGO; + attr->attr.owner = parent->owner; + attr->show = show_sample; + attr->store = NULL; + class_device_create_file(class_dev, attr); + class_dev->sample_attr = attr; } class_device_add_attrs(class_dev); --- gregkh-2.6.orig/include/linux/device.h 2005-08-17 09:53:44.000000000 -0700 +++ gregkh-2.6/include/linux/device.h 2005-08-17 09:59:14.000000000 -0700 @@ -198,6 +198,7 @@ struct class_device { struct class * class; /* required */ dev_t devt; /* dev_t, creates the sysfs "dev" */ struct class_device_attribute *devt_attr; + struct class_device_attribute *sample_attr; struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */