From 4ccb1a83d98615cebf9f8b01da7a13163447782c Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 5 Mar 2008 10:31:54 -0500 Subject: [PATCH] --- yaml --- r: 86942 b: refs/heads/master c: e0007529893c1c064be90bd21422ca0da4a0198e h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/s390/Kconfig | 4 - trunk/arch/s390/defconfig | 18 +- trunk/arch/s390/kernel/Makefile | 5 - trunk/arch/s390/kernel/early.c | 8 +- trunk/arch/s390/kernel/ipl.c | 1 - trunk/arch/s390/kernel/process.c | 4 - trunk/arch/s390/kernel/smp.c | 10 +- trunk/arch/s390/kernel/time.c | 2 + .../x86/kernel/cpu/cpufreq/e_powersaver.c | 8 +- trunk/drivers/ata/ahci.c | 14 +- trunk/drivers/ata/pata_hpt366.c | 6 +- trunk/drivers/ata/pata_hpt37x.c | 6 +- trunk/drivers/ata/pata_serverworks.c | 2 +- trunk/drivers/cpufreq/cpufreq.c | 20 +- trunk/drivers/cpufreq/cpufreq_stats.c | 2 +- trunk/drivers/s390/block/dasd_3990_erp.c | 6 +- trunk/drivers/s390/block/dasd_proc.c | 4 +- trunk/drivers/s390/char/sclp_vt220.c | 2 +- trunk/drivers/s390/crypto/ap_bus.c | 12 +- trunk/fs/super.c | 4 +- trunk/include/linux/security.h | 99 +++++++--- trunk/security/dummy.c | 23 ++- trunk/security/security.c | 23 ++- trunk/security/selinux/hooks.c | 175 ++++++++++-------- trunk/security/selinux/include/security.h | 5 + trunk/security/smack/smack_lsm.c | 9 +- 27 files changed, 253 insertions(+), 221 deletions(-) diff --git a/[refs] b/[refs] index f51f7a4793c8..af6812a6d251 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9af6b056a281c81ae6043e0f5b4e2cb323f5bb43 +refs/heads/master: e0007529893c1c064be90bd21422ca0da4a0198e diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 1831833c430e..9892827b6176 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -351,10 +351,6 @@ endchoice source "fs/Kconfig.binfmt" -config FORCE_MAX_ZONEORDER - int - default "9" - config PROCESS_DEBUG bool "Show crashed user process info" help diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 62f6b5a606dd..39921f3a9685 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.25-rc4 -# Wed Mar 5 11:22:59 2008 +# Linux kernel version: 2.6.24 +# Sat Feb 9 12:13:01 2008 # CONFIG_MMU=y CONFIG_ZONE_DMA=y @@ -43,15 +43,12 @@ CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NS=y # CONFIG_CPUSETS is not set -CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set +CONFIG_FAIR_USER_SCHED=y +# CONFIG_FAIR_CGROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set CONFIG_NAMESPACES=y CONFIG_UTS_NS=y @@ -88,9 +85,7 @@ CONFIG_SLAB=y # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y -CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -190,7 +185,6 @@ CONFIG_IPL=y CONFIG_IPL_VM=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m -CONFIG_FORCE_MAX_ZONEORDER=9 # CONFIG_PROCESS_DEBUG is not set CONFIG_PFAULT=y # CONFIG_SHARED_KERNEL is not set @@ -441,7 +435,6 @@ CONFIG_DASD_EER=y CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HAVE_IDE is not set # # SCSI device support @@ -600,7 +593,6 @@ CONFIG_S390_VMUR=m # # Sonics Silicon Backplane # -# CONFIG_MEMSTICK is not set # # File systems @@ -758,6 +750,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_FRAME_POINTER is not set +CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set @@ -766,7 +759,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_LATENCYTOP is not set CONFIG_SAMPLES=y # CONFIG_SAMPLE_KOBJECT is not set -# CONFIG_SAMPLE_KPROBES is not set # CONFIG_DEBUG_PAGEALLOC is not set # diff --git a/trunk/arch/s390/kernel/Makefile b/trunk/arch/s390/kernel/Makefile index 4d3e38392cb1..b3b650a93c7c 100644 --- a/trunk/arch/s390/kernel/Makefile +++ b/trunk/arch/s390/kernel/Makefile @@ -4,11 +4,6 @@ EXTRA_AFLAGS := -traditional -# -# Passing null pointers is ok for smp code, since we access the lowcore here. -# -CFLAGS_smp.o := -Wno-nonnull - obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o diff --git a/trunk/arch/s390/kernel/early.c b/trunk/arch/s390/kernel/early.c index 01832c440636..9f7b73b180f0 100644 --- a/trunk/arch/s390/kernel/early.c +++ b/trunk/arch/s390/kernel/early.c @@ -88,17 +88,13 @@ static noinline __init void create_kernel_nss(void) __cpcmd(defsys_cmd, NULL, 0, &response); - if (response != 0) { - kernel_nss_name[0] = '\0'; + if (response != 0) return; - } __cpcmd(savesys_cmd, NULL, 0, &response); - if (response != strlen(savesys_cmd)) { - kernel_nss_name[0] = '\0'; + if (response != strlen(savesys_cmd)) return; - } ipl_flags = IPL_NSS_VALID; } diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 375232c46c7a..60acdc266db1 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -704,7 +704,6 @@ void reipl_run(struct shutdown_trigger *trigger) default: break; } - disabled_wait((unsigned long) __builtin_return_address(0)); } static void __init reipl_probe(void) diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index ce203154d8ce..1c59ec161cf8 100644 --- a/trunk/arch/s390/kernel/process.c +++ b/trunk/arch/s390/kernel/process.c @@ -152,10 +152,6 @@ static void default_idle(void) local_mcck_disable(); if (test_thread_flag(TIF_MCCK_PENDING)) { local_mcck_enable(); - /* disable monitor call class 0 */ - __ctl_clear_bit(8, 15); - atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, - hcpu); local_irq_enable(); s390_handle_mcck(); return; diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8f894d380a62..818bd09c0260 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -629,8 +629,14 @@ static int __cpuinit smp_alloc_lowcore(int cpu) panic_stack = __get_free_page(GFP_KERNEL); if (!panic_stack || !async_stack) goto out; - memcpy(lowcore, &S390_lowcore, 512); - memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); + /* + * Only need to copy the first 512 bytes from address 0. But since + * the compiler emits a warning if src == NULL for memcpy use copy_page + * instead. Copies more than needed but this code is not performance + * critical. + */ + copy_page(lowcore, &S390_lowcore); + memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512); lowcore->async_stack = async_stack + ASYNC_SIZE; lowcore->panic_stack = panic_stack + PAGE_SIZE; diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index cb232c155360..76a5dd1b4ce9 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -209,6 +209,8 @@ static void stop_hz_timer(void) */ static void start_hz_timer(void) { + BUG_ON(!in_interrupt()); + if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) return; account_ticks(get_clock()); diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index c2f930d86640..39f8cb18296c 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/e_powersaver.c @@ -55,6 +55,7 @@ static int eps_set_state(struct eps_cpu_data *centaur, { struct cpufreq_freqs freqs; u32 lo, hi; + u8 current_multiplier, current_voltage; int err = 0; int i; @@ -94,10 +95,6 @@ static int eps_set_state(struct eps_cpu_data *centaur, rdmsr(MSR_IA32_PERF_STATUS, lo, hi); freqs.new = centaur->fsb * ((lo >> 8) & 0xff); -#ifdef DEBUG - { - u8 current_multiplier, current_voltage; - /* Print voltage and multiplier */ rdmsr(MSR_IA32_PERF_STATUS, lo, hi); current_voltage = lo & 0xff; @@ -106,8 +103,7 @@ static int eps_set_state(struct eps_cpu_data *centaur, current_multiplier = (lo >> 8) & 0xff; printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); - } -#endif + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return err; } diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 8a49835bd0f8..1db93b619074 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -186,7 +186,6 @@ enum { AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */ AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ - AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ /* ap->flags bits */ @@ -256,7 +255,6 @@ static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_p5wdh_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static int ahci_port_resume(struct ata_port *ap); -static void ahci_dev_config(struct ata_device *dev); static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, u32 opts); @@ -296,8 +294,6 @@ static const struct ata_port_operations ahci_ops = { .check_altstatus = ahci_check_status, .dev_select = ata_noop_dev_select, - .dev_config = ahci_dev_config, - .tf_read = ahci_tf_read, .qc_defer = sata_pmp_qc_defer_cmd_switch, @@ -429,7 +425,7 @@ static const struct ata_port_info ahci_port_info[] = { /* board_ahci_sb600 */ { AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | - AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), + AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ @@ -1180,14 +1176,6 @@ static void ahci_init_controller(struct ata_host *host) VPRINTK("HOST_CTL 0x%x\n", tmp); } -static void ahci_dev_config(struct ata_device *dev) -{ - struct ahci_host_priv *hpriv = dev->link->ap->host->private_data; - - if (hpriv->flags & AHCI_HFLAG_SECT255) - dev->max_sectors = 255; -} - static unsigned int ahci_dev_classify(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index a742efa0da2b..0713872cf65c 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -27,7 +27,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.2" +#define DRV_VERSION "0.6.1" struct hpt_clock { u8 xfer_speed; @@ -180,9 +180,9 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask) if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) - mask &= ~(0xF8 << ATA_SHIFT_UDMA); + mask &= ~(0x07 << ATA_SHIFT_UDMA); if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) - mask &= ~(0xF0 << ATA_SHIFT_UDMA); + mask &= ~(0x0F << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index 9a10878b2ad8..68eb34929cec 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.11" +#define DRV_VERSION "0.6.9" struct hpt_clock { u8 xfer_speed; @@ -281,7 +281,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask) if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~(0xE0 << ATA_SHIFT_UDMA); + mask &= ~(0x1F << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } @@ -297,7 +297,7 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) { if (adev->class == ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~(0xE0 << ATA_SHIFT_UDMA); + mask &= ~ (0x1F << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c index a589c0fa0dbb..9c523fbf529e 100644 --- a/trunk/drivers/ata/pata_serverworks.c +++ b/trunk/drivers/ata/pata_serverworks.c @@ -226,7 +226,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) { if (!strcmp(p, model_num)) - mask &= ~(0xE0 << ATA_SHIFT_UDMA); + mask &= ~(0x1F << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 35a26a3e5f68..89a29cd93783 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -671,13 +671,13 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf) { struct cpufreq_policy * policy = to_policy(kobj); struct freq_attr * fattr = to_attr(attr); - ssize_t ret = -EINVAL; + ssize_t ret; policy = cpufreq_cpu_get(policy->cpu); if (!policy) - goto no_policy; + return -EINVAL; if (lock_policy_rwsem_read(policy->cpu) < 0) - goto fail; + return -EINVAL; if (fattr->show) ret = fattr->show(policy, buf); @@ -685,9 +685,8 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf) ret = -EIO; unlock_policy_rwsem_read(policy->cpu); -fail: + cpufreq_cpu_put(policy); -no_policy: return ret; } @@ -696,13 +695,13 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr, { struct cpufreq_policy * policy = to_policy(kobj); struct freq_attr * fattr = to_attr(attr); - ssize_t ret = -EINVAL; + ssize_t ret; policy = cpufreq_cpu_get(policy->cpu); if (!policy) - goto no_policy; + return -EINVAL; if (lock_policy_rwsem_write(policy->cpu) < 0) - goto fail; + return -EINVAL; if (fattr->store) ret = fattr->store(policy, buf, count); @@ -710,9 +709,8 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr, ret = -EIO; unlock_policy_rwsem_write(policy->cpu); -fail: + cpufreq_cpu_put(policy); -no_policy: return ret; } @@ -1777,7 +1775,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __refdata cpufreq_cpu_notifier = +static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = { .notifier_call = cpufreq_cpu_callback, }; diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index 070421a5480e..1b8312b02006 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -323,7 +323,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block cpufreq_stat_cpu_notifier __refdata = +static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata = { .notifier_call = cpufreq_stat_cpu_callback, }; diff --git a/trunk/drivers/s390/block/dasd_3990_erp.c b/trunk/drivers/s390/block/dasd_3990_erp.c index b19db20a0bef..f69714a0e9e7 100644 --- a/trunk/drivers/s390/block/dasd_3990_erp.c +++ b/trunk/drivers/s390/block/dasd_3990_erp.c @@ -2310,8 +2310,10 @@ static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) { - if (cqr1->startdev != cqr2->startdev) - return 0; + /* check failed CCW */ + if (cqr1->irb.scsw.cpa != cqr2->irb.scsw.cpa) { + // return 0; /* CCW doesn't match */ + } if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons) return 0; diff --git a/trunk/drivers/s390/block/dasd_proc.c b/trunk/drivers/s390/block/dasd_proc.c index 556063e8f7a9..28a86f070048 100644 --- a/trunk/drivers/s390/block/dasd_proc.c +++ b/trunk/drivers/s390/block/dasd_proc.c @@ -62,10 +62,8 @@ dasd_devices_show(struct seq_file *m, void *v) return 0; if (device->block) block = device->block; - else { - dasd_put_device(device); + else return 0; - } /* Print device number. */ seq_printf(m, "%s", device->cdev->dev.bus_id); /* Print discipline string. */ diff --git a/trunk/drivers/s390/char/sclp_vt220.c b/trunk/drivers/s390/char/sclp_vt220.c index f7b258dfd52c..92f527201792 100644 --- a/trunk/drivers/s390/char/sclp_vt220.c +++ b/trunk/drivers/s390/char/sclp_vt220.c @@ -367,7 +367,7 @@ sclp_vt220_timeout(unsigned long data) sclp_vt220_emit_current(); } -#define BUFFER_MAX_DELAY HZ/20 +#define BUFFER_MAX_DELAY HZ/2 /* * Internal implementation of the write function. Write COUNT bytes of data diff --git a/trunk/drivers/s390/crypto/ap_bus.c b/trunk/drivers/s390/crypto/ap_bus.c index 7b0b81901297..d0c6fd3b1c19 100644 --- a/trunk/drivers/s390/crypto/ap_bus.c +++ b/trunk/drivers/s390/crypto/ap_bus.c @@ -490,12 +490,10 @@ static int ap_device_probe(struct device *dev) int rc; ap_dev->drv = ap_drv; + spin_lock_bh(&ap_device_lock); + list_add(&ap_dev->list, &ap_device_list); + spin_unlock_bh(&ap_device_lock); rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; - if (!rc) { - spin_lock_bh(&ap_device_lock); - list_add(&ap_dev->list, &ap_device_list); - spin_unlock_bh(&ap_device_lock); - } return rc; } @@ -534,11 +532,11 @@ static int ap_device_remove(struct device *dev) ap_flush_queue(ap_dev); del_timer_sync(&ap_dev->timeout); + if (ap_drv->remove) + ap_drv->remove(ap_dev); spin_lock_bh(&ap_device_lock); list_del_init(&ap_dev->list); spin_unlock_bh(&ap_device_lock); - if (ap_drv->remove) - ap_drv->remove(ap_dev); spin_lock_bh(&ap_dev->lock); atomic_sub(ap_dev->queue_count, &ap_poll_requests); spin_unlock_bh(&ap_dev->lock); diff --git a/trunk/fs/super.c b/trunk/fs/super.c index 88811f60c8de..010446d8c40a 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -870,12 +870,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void if (!mnt) goto out; - if (data) { + if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { secdata = alloc_secdata(); if (!secdata) goto out_mnt; - error = security_sb_copy_data(type, data, secdata); + error = security_sb_copy_data(data, secdata); if (error) goto out_free_secdata; } diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index fe52cdeab0a6..b07357ca2137 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -34,12 +34,6 @@ #include #include -/* only a char in selinux superblock security struct flags */ -#define FSCONTEXT_MNT 0x01 -#define CONTEXT_MNT 0x02 -#define ROOTCONTEXT_MNT 0x04 -#define DEFCONTEXT_MNT 0x08 - extern unsigned securebits; struct ctl_table; @@ -114,6 +108,32 @@ struct request_sock; #ifdef CONFIG_SECURITY +struct security_mnt_opts { + char **mnt_opts; + int *mnt_opts_flags; + int num_mnt_opts; +}; + +static inline void security_init_mnt_opts(struct security_mnt_opts *opts) +{ + opts->mnt_opts = NULL; + opts->mnt_opts_flags = NULL; + opts->num_mnt_opts = 0; +} + +static inline void security_free_mnt_opts(struct security_mnt_opts *opts) +{ + int i; + if (opts->mnt_opts) + for(i = 0; i < opts->num_mnt_opts; i++) + kfree(opts->mnt_opts[i]); + kfree(opts->mnt_opts); + opts->mnt_opts = NULL; + kfree(opts->mnt_opts_flags); + opts->mnt_opts_flags = NULL; + opts->num_mnt_opts = 0; +} + /** * struct security_operations - main security structure * @@ -262,19 +282,19 @@ struct request_sock; * @sb_get_mnt_opts: * Get the security relevant mount options used for a superblock * @sb the superblock to get security mount options from - * @mount_options array for pointers to mount options - * @mount_flags array of ints specifying what each mount options is - * @num_opts number of options in the arrays + * @opts binary data structure containing all lsm mount data * @sb_set_mnt_opts: * Set the security relevant mount options used for a superblock * @sb the superblock to set security mount options for - * @mount_options array for pointers to mount options - * @mount_flags array of ints specifying what each mount options is - * @num_opts number of options in the arrays + * @opts binary data structure containing all lsm mount data * @sb_clone_mnt_opts: * Copy all security options from a given superblock to another * @oldsb old superblock which contain information to clone * @newsb new superblock which needs filled in + * @sb_parse_opts_str: + * Parse a string of security data filling in the opts structure + * @options string containing all mount options known by the LSM + * @opts binary data structure usable by the LSM * * Security hooks for inode operations. * @@ -1238,8 +1258,7 @@ struct security_operations { int (*sb_alloc_security) (struct super_block * sb); void (*sb_free_security) (struct super_block * sb); - int (*sb_copy_data)(struct file_system_type *type, - void *orig, void *copy); + int (*sb_copy_data)(char *orig, char *copy); int (*sb_kern_mount) (struct super_block *sb, void *data); int (*sb_statfs) (struct dentry *dentry); int (*sb_mount) (char *dev_name, struct nameidata * nd, @@ -1257,12 +1276,12 @@ struct security_operations { void (*sb_post_pivotroot) (struct nameidata * old_nd, struct nameidata * new_nd); int (*sb_get_mnt_opts) (const struct super_block *sb, - char ***mount_options, int **flags, - int *num_opts); - int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options, - int *flags, int num_opts); + struct security_mnt_opts *opts); + int (*sb_set_mnt_opts) (struct super_block *sb, + struct security_mnt_opts *opts); void (*sb_clone_mnt_opts) (const struct super_block *oldsb, struct super_block *newsb); + int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); int (*inode_alloc_security) (struct inode *inode); void (*inode_free_security) (struct inode *inode); @@ -1507,7 +1526,7 @@ int security_bprm_check(struct linux_binprm *bprm); int security_bprm_secureexec(struct linux_binprm *bprm); int security_sb_alloc(struct super_block *sb); void security_sb_free(struct super_block *sb); -int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy); +int security_sb_copy_data(char *orig, char *copy); int security_sb_kern_mount(struct super_block *sb, void *data); int security_sb_statfs(struct dentry *dentry); int security_sb_mount(char *dev_name, struct nameidata *nd, @@ -1520,12 +1539,12 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); -int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, - int **flags, int *num_opts); -int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options, - int *flags, int num_opts); +int security_sb_get_mnt_opts(const struct super_block *sb, + struct security_mnt_opts *opts); +int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); void security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb); +int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); int security_inode_alloc(struct inode *inode); void security_inode_free(struct inode *inode); @@ -1635,6 +1654,16 @@ int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid); void security_release_secctx(char *secdata, u32 seclen); #else /* CONFIG_SECURITY */ +struct security_mnt_opts { +}; + +static inline void security_init_mnt_opts(struct security_mnt_opts *opts) +{ +} + +static inline void security_free_mnt_opts(struct security_mnt_opts *opts) +{ +} /* * This is the default capabilities functionality. Most of these functions @@ -1762,8 +1791,7 @@ static inline int security_sb_alloc (struct super_block *sb) static inline void security_sb_free (struct super_block *sb) { } -static inline int security_sb_copy_data (struct file_system_type *type, - void *orig, void *copy) +static inline int security_sb_copy_data (char *orig, char *copy) { return 0; } @@ -1819,6 +1847,27 @@ static inline int security_sb_pivotroot (struct nameidata *old_nd, static inline void security_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) { } +static inline int security_sb_get_mnt_opts(const struct super_block *sb, + struct security_mnt_opts *opts) +{ + security_init_mnt_opts(opts); + return 0; +} + +static inline int security_sb_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) +{ + return 0; +} + +static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb, + struct super_block *newsb) +{ } + +static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return 0; +} static inline int security_inode_alloc (struct inode *inode) { diff --git a/trunk/security/dummy.c b/trunk/security/dummy.c index 649326bf64ea..78d8f92310a4 100644 --- a/trunk/security/dummy.c +++ b/trunk/security/dummy.c @@ -181,8 +181,7 @@ static void dummy_sb_free_security (struct super_block *sb) return; } -static int dummy_sb_copy_data (struct file_system_type *type, - void *orig, void *copy) +static int dummy_sb_copy_data (char *orig, char *copy) { return 0; } @@ -245,19 +244,17 @@ static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata return; } -static int dummy_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, - int **flags, int *num_opts) +static int dummy_sb_get_mnt_opts(const struct super_block *sb, + struct security_mnt_opts *opts) { - *mount_options = NULL; - *flags = NULL; - *num_opts = 0; + security_init_mnt_opts(opts); return 0; } -static int dummy_sb_set_mnt_opts(struct super_block *sb, char **mount_options, - int *flags, int num_opts) +static int dummy_sb_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) { - if (unlikely(num_opts)) + if (unlikely(opts->num_mnt_opts)) return -EOPNOTSUPP; return 0; } @@ -268,6 +265,11 @@ static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb, return; } +static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return 0; +} + static int dummy_inode_alloc_security (struct inode *inode) { return 0; @@ -1028,6 +1030,7 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sb_get_mnt_opts); set_to_dummy_if_null(ops, sb_set_mnt_opts); set_to_dummy_if_null(ops, sb_clone_mnt_opts); + set_to_dummy_if_null(ops, sb_parse_opts_str); set_to_dummy_if_null(ops, inode_alloc_security); set_to_dummy_if_null(ops, inode_free_security); set_to_dummy_if_null(ops, inode_init_security); diff --git a/trunk/security/security.c b/trunk/security/security.c index d15e56cbaade..b1387a6b416d 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -244,10 +244,11 @@ void security_sb_free(struct super_block *sb) security_ops->sb_free_security(sb); } -int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy) +int security_sb_copy_data(char *orig, char *copy) { - return security_ops->sb_copy_data(type, orig, copy); + return security_ops->sb_copy_data(orig, copy); } +EXPORT_SYMBOL(security_sb_copy_data); int security_sb_kern_mount(struct super_block *sb, void *data) { @@ -306,24 +307,30 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_ } int security_sb_get_mnt_opts(const struct super_block *sb, - char ***mount_options, - int **flags, int *num_opts) + struct security_mnt_opts *opts) { - return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); + return security_ops->sb_get_mnt_opts(sb, opts); } int security_sb_set_mnt_opts(struct super_block *sb, - char **mount_options, - int *flags, int num_opts) + struct security_mnt_opts *opts) { - return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); + return security_ops->sb_set_mnt_opts(sb, opts); } +EXPORT_SYMBOL(security_sb_set_mnt_opts); void security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb) { security_ops->sb_clone_mnt_opts(oldsb, newsb); } +EXPORT_SYMBOL(security_sb_clone_mnt_opts); + +int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return security_ops->sb_parse_opts_str(options, opts); +} +EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode) { diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 75c2e99bfb81..4bf4807f2d44 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -443,8 +443,7 @@ static int sb_finish_set_opts(struct super_block *sb) * mount options, or whatever. */ static int selinux_get_mnt_opts(const struct super_block *sb, - char ***mount_options, int **mnt_opts_flags, - int *num_opts) + struct security_mnt_opts *opts) { int rc = 0, i; struct superblock_security_struct *sbsec = sb->s_security; @@ -452,9 +451,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, u32 len; char tmp; - *num_opts = 0; - *mount_options = NULL; - *mnt_opts_flags = NULL; + security_init_mnt_opts(opts); if (!sbsec->initialized) return -EINVAL; @@ -470,18 +467,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb, /* count the number of mount options for this sb */ for (i = 0; i < 8; i++) { if (tmp & 0x01) - (*num_opts)++; + opts->num_mnt_opts++; tmp >>= 1; } - *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC); - if (!*mount_options) { + opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); + if (!opts->mnt_opts) { rc = -ENOMEM; goto out_free; } - *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC); - if (!*mnt_opts_flags) { + opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); + if (!opts->mnt_opts_flags) { rc = -ENOMEM; goto out_free; } @@ -491,22 +488,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb, rc = security_sid_to_context(sbsec->sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = FSCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; } if (sbsec->flags & CONTEXT_MNT) { rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = CONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = CONTEXT_MNT; } if (sbsec->flags & DEFCONTEXT_MNT) { rc = security_sid_to_context(sbsec->def_sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; } if (sbsec->flags & ROOTCONTEXT_MNT) { struct inode *root = sbsec->sb->s_root->d_inode; @@ -515,24 +512,16 @@ static int selinux_get_mnt_opts(const struct super_block *sb, rc = security_sid_to_context(isec->sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; } - BUG_ON(i != *num_opts); + BUG_ON(i != opts->num_mnt_opts); return 0; out_free: - /* don't leak context string if security_sid_to_context had an error */ - if (*mount_options && i) - for (; i > 0; i--) - kfree((*mount_options)[i-1]); - kfree(*mount_options); - *mount_options = NULL; - kfree(*mnt_opts_flags); - *mnt_opts_flags = NULL; - *num_opts = 0; + security_free_mnt_opts(opts); return rc; } @@ -553,12 +542,13 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, return 1; return 0; } + /* * Allow filesystems with binary mount data to explicitly set mount point * labeling information. */ -static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, - int *flags, int num_opts) +static int selinux_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) { int rc = 0, i; struct task_security_struct *tsec = current->security; @@ -568,6 +558,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, struct inode_security_struct *root_isec = inode->i_security; u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; u32 defcontext_sid = 0; + char **mount_options = opts->mnt_opts; + int *flags = opts->mnt_opts_flags; + int num_opts = opts->num_mnt_opts; mutex_lock(&sbsec->lock); @@ -588,6 +581,21 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, goto out; } + /* + * Binary mount data FS will come through this function twice. Once + * from an explicit call and once from the generic calls from the vfs. + * Since the generic VFS calls will not contain any security mount data + * we need to skip the double mount verification. + * + * This does open a hole in which we will not notice if the first + * mount using this sb set explict options and a second mount using + * this sb does not set any security options. (The first options + * will be used for both mounts) + */ + if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) + && (num_opts == 0)) + goto out; + /* * parse the mount options, check if they are valid sids. * also check if someone is trying to mount the same sb more @@ -792,43 +800,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, mutex_unlock(&newsbsec->lock); } -/* - * string mount options parsing and call set the sbsec - */ -static int superblock_doinit(struct super_block *sb, void *data) +int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts) { + char *p; char *context = NULL, *defcontext = NULL; char *fscontext = NULL, *rootcontext = NULL; - int rc = 0; - char *p, *options = data; - /* selinux only know about a fixed number of mount options */ - char *mnt_opts[NUM_SEL_MNT_OPTS]; - int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0; - - if (!data) - goto out; + int rc, num_mnt_opts = 0; - /* with the nfs patch this will become a goto out; */ - if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) { - const char *name = sb->s_type->name; - /* NFS we understand. */ - if (!strcmp(name, "nfs")) { - struct nfs_mount_data *d = data; - - if (d->version != NFS_MOUNT_VERSION) - goto out; - - if (d->context[0]) { - context = kstrdup(d->context, GFP_KERNEL); - if (!context) { - rc = -ENOMEM; - goto out; - } - } - goto build_flags; - } else - goto out; - } + opts->num_mnt_opts = 0; /* Standard string-based options. */ while ((p = strsep(&options, "|")) != NULL) { @@ -901,26 +880,37 @@ static int superblock_doinit(struct super_block *sb, void *data) } } -build_flags: + rc = -ENOMEM; + opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC); + if (!opts->mnt_opts) + goto out_err; + + opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC); + if (!opts->mnt_opts_flags) { + kfree(opts->mnt_opts); + goto out_err; + } + if (fscontext) { - mnt_opts[num_mnt_opts] = fscontext; - mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = fscontext; + opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; } if (context) { - mnt_opts[num_mnt_opts] = context; - mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = context; + opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; } if (rootcontext) { - mnt_opts[num_mnt_opts] = rootcontext; - mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = rootcontext; + opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; } if (defcontext) { - mnt_opts[num_mnt_opts] = defcontext; - mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = defcontext; + opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; } -out: - rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts); + opts->num_mnt_opts = num_mnt_opts; + return 0; + out_err: kfree(context); kfree(defcontext); @@ -928,6 +918,33 @@ static int superblock_doinit(struct super_block *sb, void *data) kfree(rootcontext); return rc; } +/* + * string mount options parsing and call set the sbsec + */ +static int superblock_doinit(struct super_block *sb, void *data) +{ + int rc = 0; + char *options = data; + struct security_mnt_opts opts; + + security_init_mnt_opts(&opts); + + if (!data) + goto out; + + BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); + + rc = selinux_parse_opts_str(options, &opts); + if (rc) + goto out_err; + +out: + rc = selinux_set_mnt_opts(sb, &opts); + +out_err: + security_free_mnt_opts(&opts); + return rc; +} static inline u16 inode_mode_to_security_class(umode_t mode) { @@ -2253,7 +2270,7 @@ static inline void take_selinux_option(char **to, char *from, int *first, } } -static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy) +static int selinux_sb_copy_data(char *orig, char *copy) { int fnosec, fsec, rc = 0; char *in_save, *in_curr, *in_end; @@ -2263,12 +2280,6 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void in_curr = orig; sec_curr = copy; - /* Binary mount data: just copy */ - if (type->fs_flags & FS_BINARY_MOUNTDATA) { - copy_page(sec_curr, in_curr); - goto out; - } - nosec = (char *)get_zeroed_page(GFP_KERNEL); if (!nosec) { rc = -ENOMEM; @@ -5251,6 +5262,8 @@ static struct security_operations selinux_ops = { .sb_get_mnt_opts = selinux_get_mnt_opts, .sb_set_mnt_opts = selinux_set_mnt_opts, .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, + .sb_parse_opts_str = selinux_parse_opts_str, + .inode_alloc_security = selinux_inode_alloc_security, .inode_free_security = selinux_inode_free_security, diff --git a/trunk/security/selinux/include/security.h b/trunk/security/selinux/include/security.h index 837ce420d2f6..f7d2f03781f2 100644 --- a/trunk/security/selinux/include/security.h +++ b/trunk/security/selinux/include/security.h @@ -35,6 +35,11 @@ #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP #endif +#define CONTEXT_MNT 0x01 +#define FSCONTEXT_MNT 0x02 +#define ROOTCONTEXT_MNT 0x04 +#define DEFCONTEXT_MNT 0x08 + struct netlbl_lsm_secattr; extern int selinux_enabled; diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 770eb067e165..0241fd359675 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb) * Copy the Smack specific mount options out of the mount * options list. */ -static int smack_sb_copy_data(struct file_system_type *type, void *orig, - void *smackopts) +static int smack_sb_copy_data(char *orig, char *smackopts) { char *cp, *commap, *otheropts, *dp; - /* Binary mount data: just copy */ - if (type->fs_flags & FS_BINARY_MOUNTDATA) { - copy_page(smackopts, orig); - return 0; - } - otheropts = (char *)get_zeroed_page(GFP_KERNEL); if (otheropts == NULL) return -ENOMEM;