From: Greg Kroah-Hartman Date: Sat, 19 Sep 2015 16:07:15 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v3.10.89~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d9b0f14b1c4e267cf2b62e122b5555fb6502e4fc;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches added patches: acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch drivercore-fix-unregistration-path-of-platform-devices.patch fs-create-and-use-seq_show_option-for-escaping.patch fs-set-the-size-of-empty-dirs-to-0.patch hpfs-update-ctime-and-mtime-on-directory-modification.patch --- diff --git a/queue-4.1/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch b/queue-4.1/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch new file mode 100644 index 00000000000..203da20f690 --- /dev/null +++ b/queue-4.1/acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch @@ -0,0 +1,139 @@ +From 5d0ddfebb93069061880fc57ee4ba7246bd1e1ee Mon Sep 17 00:00:00 2001 +From: Jiang Liu +Date: Fri, 21 Aug 2015 15:36:23 +0800 +Subject: ACPI, PCI: Penalize legacy IRQ used by ACPI SCI + +From: Jiang Liu + +commit 5d0ddfebb93069061880fc57ee4ba7246bd1e1ee upstream. + +Nick Meier reported a regression with HyperV that " + After rebooting the VM, the following messages are logged in syslog + when trying to load the tulip driver: + tulip: Linux Tulip drivers version 1.1.15 (Feb 27, 2007) + tulip: 0000:00:0a.0: PCI INT A: failed to register GSI + tulip: Cannot enable tulip board #0, aborting + tulip: probe of 0000:00:0a.0 failed with error -16 + Errors occur in 3.19.0 kernel + Works in 3.17 kernel. +" + +According to the ACPI dump file posted by Nick at +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072 + +The ACPI MADT table includes an interrupt source overridden entry for +ACPI SCI: +[236h 0566 1] Subtable Type : 02 +[237h 0567 1] Length : 0A +[238h 0568 1] Bus : 00 +[239h 0569 1] Source : 09 +[23Ah 0570 4] Interrupt : 00000009 +[23Eh 0574 2] Flags (decoded below) : 000D + Polarity : 1 + Trigger Mode : 3 + +And in DSDT table, we have _PRT method to define PCI interrupts, which +eventually goes to: + Name (PRSA, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared, ) + {3,4,5,7,9,10,11,12,14,15} + }) + Name (PRSB, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared, ) + {3,4,5,7,9,10,11,12,14,15} + }) + Name (PRSC, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared, ) + {3,4,5,7,9,10,11,12,14,15} + }) + Name (PRSD, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared, ) + {3,4,5,7,9,10,11,12,14,15} + }) + +According to the MADT and DSDT tables, IRQ 9 may be used for: + 1) ACPI SCI in level, high mode + 2) PCI legacy IRQ in level, low mode +So there's a conflict in polarity setting for IRQ 9. + +Prior to commit cd68f6bd53cf ("x86, irq, acpi: Get rid of special +handling of GSI for ACPI SCI"), ACPI SCI is handled specially and +there's no check for conflicts between ACPI SCI and PCI legagy IRQ. +And it seems that the HyperV hypervisor doesn't make use of the +polarity configuration in IOAPIC entry, so it just works. + +Commit cd68f6bd53cf gets rid of the specially handling of ACPI SCI, +and then the pin attribute checking code discloses the conflicts +between ACPI SCI and PCI legacy IRQ on HyperV virtual machine, +and rejects the request to assign IRQ9 to PCI devices. + +So penalize legacy IRQ used by ACPI SCI and mark it unusable if ACPI +SCI attributes conflict with PCI IRQ attributes. + +Please refer to following links for more information: +https://bugzilla.kernel.org/show_bug.cgi?id=101301 +https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1440072 + +Fixes: cd68f6bd53cf ("x86, irq, acpi: Get rid of special handling of GSI for ACPI SCI") +Reported-and-tested-by: Nick Meier +Acked-by: Thomas Gleixner +Signed-off-by: Jiang Liu +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/acpi/boot.c | 1 + + drivers/acpi/pci_link.c | 16 ++++++++++++++++ + include/linux/acpi.h | 2 +- + 3 files changed, 18 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -489,6 +489,7 @@ static void __init acpi_sci_ioapic_setup + polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK; + + mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); ++ acpi_penalize_sci_irq(bus_irq, trigger, polarity); + + /* + * stash over-ride to indicate we've been here +--- a/drivers/acpi/pci_link.c ++++ b/drivers/acpi/pci_link.c +@@ -826,6 +826,22 @@ void acpi_penalize_isa_irq(int irq, int + } + + /* ++ * Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict with ++ * PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be use for ++ * PCI IRQs. ++ */ ++void acpi_penalize_sci_irq(int irq, int trigger, int polarity) ++{ ++ if (irq >= 0 && irq < ARRAY_SIZE(acpi_irq_penalty)) { ++ if (trigger != ACPI_MADT_TRIGGER_LEVEL || ++ polarity != ACPI_MADT_POLARITY_ACTIVE_LOW) ++ acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_ALWAYS; ++ else ++ acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING; ++ } ++} ++ ++/* + * Over-ride default table to reserve additional IRQs for use by ISA + * e.g. acpi_irq_isa=5 + * Useful for telling ACPI how not to interfere with your ISA sound card. +--- a/include/linux/acpi.h ++++ b/include/linux/acpi.h +@@ -198,7 +198,7 @@ struct pci_dev; + + int acpi_pci_irq_enable (struct pci_dev *dev); + void acpi_penalize_isa_irq(int irq, int active); +- ++void acpi_penalize_sci_irq(int irq, int trigger, int polarity); + void acpi_pci_irq_disable (struct pci_dev *dev); + + extern int ec_read(u8 addr, u8 *val); diff --git a/queue-4.1/drivercore-fix-unregistration-path-of-platform-devices.patch b/queue-4.1/drivercore-fix-unregistration-path-of-platform-devices.patch new file mode 100644 index 00000000000..97d59609bf4 --- /dev/null +++ b/queue-4.1/drivercore-fix-unregistration-path-of-platform-devices.patch @@ -0,0 +1,67 @@ +From 7f5dcaf1fdf289767a126a0a5cc3ef39b5254b06 Mon Sep 17 00:00:00 2001 +From: Grant Likely +Date: Sun, 7 Jun 2015 15:20:11 +0100 +Subject: drivercore: Fix unregistration path of platform devices + +From: Grant Likely + +commit 7f5dcaf1fdf289767a126a0a5cc3ef39b5254b06 upstream. + +The unregister path of platform_device is broken. On registration, it +will register all resources with either a parent already set, or +type==IORESOURCE_{IO,MEM}. However, on unregister it will release +everything with type==IORESOURCE_{IO,MEM}, but ignore the others. There +are also cases where resources don't get registered in the first place, +like with devices created by of_platform_populate()*. + +Fix the unregister path to be symmetrical with the register path by +checking the parent pointer instead of the type field to decide which +resources to unregister. This is safe because the upshot of the +registration path algorithm is that registered resources have a parent +pointer, and non-registered resources do not. + +* It can be argued that of_platform_populate() should be registering + it's resources, and they argument has some merit. However, there are + quite a few platforms that end up broken if we try to do that due to + overlapping resources in the device tree. Until that is fixed, we need + to solve the immediate problem. + +Cc: Pantelis Antoniou +Cc: Wolfram Sang +Cc: Rob Herring +Cc: Greg Kroah-Hartman +Cc: Ricardo Ribalda Delgado +Signed-off-by: Grant Likely +Tested-by: Ricardo Ribalda Delgado +Tested-by: Wolfram Sang +Signed-off-by: Rob Herring +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/platform.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/base/platform.c ++++ b/drivers/base/platform.c +@@ -375,9 +375,7 @@ int platform_device_add(struct platform_ + + while (--i >= 0) { + struct resource *r = &pdev->resource[i]; +- unsigned long type = resource_type(r); +- +- if (type == IORESOURCE_MEM || type == IORESOURCE_IO) ++ if (r->parent) + release_resource(r); + } + +@@ -408,9 +406,7 @@ void platform_device_del(struct platform + + for (i = 0; i < pdev->num_resources; i++) { + struct resource *r = &pdev->resource[i]; +- unsigned long type = resource_type(r); +- +- if (type == IORESOURCE_MEM || type == IORESOURCE_IO) ++ if (r->parent) + release_resource(r); + } + } diff --git a/queue-4.1/fs-create-and-use-seq_show_option-for-escaping.patch b/queue-4.1/fs-create-and-use-seq_show_option-for-escaping.patch new file mode 100644 index 00000000000..558d116c2f9 --- /dev/null +++ b/queue-4.1/fs-create-and-use-seq_show_option-for-escaping.patch @@ -0,0 +1,345 @@ +From a068acf2ee77693e0bf39d6e07139ba704f461c3 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 4 Sep 2015 15:44:57 -0700 +Subject: fs: create and use seq_show_option for escaping + +From: Kees Cook + +commit a068acf2ee77693e0bf39d6e07139ba704f461c3 upstream. + +Many file systems that implement the show_options hook fail to correctly +escape their output which could lead to unescaped characters (e.g. new +lines) leaking into /proc/mounts and /proc/[pid]/mountinfo files. This +could lead to confusion, spoofed entries (resulting in things like +systemd issuing false d-bus "mount" notifications), and who knows what +else. This looks like it would only be the root user stepping on +themselves, but it's possible weird things could happen in containers or +in other situations with delegated mount privileges. + +Here's an example using overlay with setuid fusermount trusting the +contents of /proc/mounts (via the /etc/mtab symlink). Imagine the use +of "sudo" is something more sneaky: + + $ BASE="ovl" + $ MNT="$BASE/mnt" + $ LOW="$BASE/lower" + $ UP="$BASE/upper" + $ WORK="$BASE/work/ 0 0 + none /proc fuse.pwn user_id=1000" + $ mkdir -p "$LOW" "$UP" "$WORK" + $ sudo mount -t overlay -o "lowerdir=$LOW,upperdir=$UP,workdir=$WORK" none /mnt + $ cat /proc/mounts + none /root/ovl/mnt overlay rw,relatime,lowerdir=ovl/lower,upperdir=ovl/upper,workdir=ovl/work/ 0 0 + none /proc fuse.pwn user_id=1000 0 0 + $ fusermount -u /proc + $ cat /proc/mounts + cat: /proc/mounts: No such file or directory + +This fixes the problem by adding new seq_show_option and +seq_show_option_n helpers, and updating the vulnerable show_option +handlers to use them as needed. Some, like SELinux, need to be open +coded due to unusual existing escape mechanisms. + +[akpm@linux-foundation.org: add lost chunk, per Kees] +[keescook@chromium.org: seq_show_option should be using const parameters] +Signed-off-by: Kees Cook +Acked-by: Serge Hallyn +Acked-by: Jan Kara +Acked-by: Paul Moore +Cc: J. R. Okajima +Signed-off-by: Kees Cook +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/super.c | 2 +- + fs/cifs/cifsfs.c | 6 +++--- + fs/ext4/super.c | 4 ++-- + fs/gfs2/super.c | 6 +++--- + fs/hfs/super.c | 4 ++-- + fs/hfsplus/options.c | 4 ++-- + fs/hostfs/hostfs_kern.c | 2 +- + fs/ocfs2/super.c | 4 ++-- + fs/overlayfs/super.c | 6 +++--- + fs/reiserfs/super.c | 8 +++++--- + fs/xfs/xfs_super.c | 4 ++-- + include/linux/seq_file.h | 35 +++++++++++++++++++++++++++++++++++ + kernel/cgroup.c | 7 ++++--- + net/ceph/ceph_common.c | 7 +++++-- + security/selinux/hooks.c | 2 +- + 15 files changed, 71 insertions(+), 30 deletions(-) + +--- a/fs/ceph/super.c ++++ b/fs/ceph/super.c +@@ -466,7 +466,7 @@ static int ceph_show_options(struct seq_ + if (fsopt->max_readdir_bytes != CEPH_MAX_READDIR_BYTES_DEFAULT) + seq_printf(m, ",readdir_max_bytes=%d", fsopt->max_readdir_bytes); + if (strcmp(fsopt->snapdir_name, CEPH_SNAPDIRNAME_DEFAULT)) +- seq_printf(m, ",snapdirname=%s", fsopt->snapdir_name); ++ seq_show_option(m, "snapdirname", fsopt->snapdir_name); + + return 0; + } +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -394,17 +394,17 @@ cifs_show_options(struct seq_file *s, st + struct sockaddr *srcaddr; + srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; + +- seq_printf(s, ",vers=%s", tcon->ses->server->vals->version_string); ++ seq_show_option(s, "vers", tcon->ses->server->vals->version_string); + cifs_show_security(s, tcon->ses); + cifs_show_cache_flavor(s, cifs_sb); + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) + seq_puts(s, ",multiuser"); + else if (tcon->ses->user_name) +- seq_printf(s, ",username=%s", tcon->ses->user_name); ++ seq_show_option(s, "username", tcon->ses->user_name); + + if (tcon->ses->domainName) +- seq_printf(s, ",domain=%s", tcon->ses->domainName); ++ seq_show_option(s, "domain", tcon->ses->domainName); + + if (srcaddr->sa_family != AF_UNSPEC) { + struct sockaddr_in *saddr4; +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1738,10 +1738,10 @@ static inline void ext4_show_quota_optio + } + + if (sbi->s_qf_names[USRQUOTA]) +- seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); ++ seq_show_option(seq, "usrjquota", sbi->s_qf_names[USRQUOTA]); + + if (sbi->s_qf_names[GRPQUOTA]) +- seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); ++ seq_show_option(seq, "grpjquota", sbi->s_qf_names[GRPQUOTA]); + #endif + } + +--- a/fs/gfs2/super.c ++++ b/fs/gfs2/super.c +@@ -1334,11 +1334,11 @@ static int gfs2_show_options(struct seq_ + if (is_ancestor(root, sdp->sd_master_dir)) + seq_puts(s, ",meta"); + if (args->ar_lockproto[0]) +- seq_printf(s, ",lockproto=%s", args->ar_lockproto); ++ seq_show_option(s, "lockproto", args->ar_lockproto); + if (args->ar_locktable[0]) +- seq_printf(s, ",locktable=%s", args->ar_locktable); ++ seq_show_option(s, "locktable", args->ar_locktable); + if (args->ar_hostdata[0]) +- seq_printf(s, ",hostdata=%s", args->ar_hostdata); ++ seq_show_option(s, "hostdata", args->ar_hostdata); + if (args->ar_spectator) + seq_puts(s, ",spectator"); + if (args->ar_localflocks) +--- a/fs/hfs/super.c ++++ b/fs/hfs/super.c +@@ -135,9 +135,9 @@ static int hfs_show_options(struct seq_f + struct hfs_sb_info *sbi = HFS_SB(root->d_sb); + + if (sbi->s_creator != cpu_to_be32(0x3f3f3f3f)) +- seq_printf(seq, ",creator=%.4s", (char *)&sbi->s_creator); ++ seq_show_option_n(seq, "creator", (char *)&sbi->s_creator, 4); + if (sbi->s_type != cpu_to_be32(0x3f3f3f3f)) +- seq_printf(seq, ",type=%.4s", (char *)&sbi->s_type); ++ seq_show_option_n(seq, "type", (char *)&sbi->s_type, 4); + seq_printf(seq, ",uid=%u,gid=%u", + from_kuid_munged(&init_user_ns, sbi->s_uid), + from_kgid_munged(&init_user_ns, sbi->s_gid)); +--- a/fs/hfsplus/options.c ++++ b/fs/hfsplus/options.c +@@ -218,9 +218,9 @@ int hfsplus_show_options(struct seq_file + struct hfsplus_sb_info *sbi = HFSPLUS_SB(root->d_sb); + + if (sbi->creator != HFSPLUS_DEF_CR_TYPE) +- seq_printf(seq, ",creator=%.4s", (char *)&sbi->creator); ++ seq_show_option_n(seq, "creator", (char *)&sbi->creator, 4); + if (sbi->type != HFSPLUS_DEF_CR_TYPE) +- seq_printf(seq, ",type=%.4s", (char *)&sbi->type); ++ seq_show_option_n(seq, "type", (char *)&sbi->type, 4); + seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, + from_kuid_munged(&init_user_ns, sbi->uid), + from_kgid_munged(&init_user_ns, sbi->gid)); +--- a/fs/hostfs/hostfs_kern.c ++++ b/fs/hostfs/hostfs_kern.c +@@ -260,7 +260,7 @@ static int hostfs_show_options(struct se + size_t offset = strlen(root_ino) + 1; + + if (strlen(root_path) > offset) +- seq_printf(seq, ",%s", root_path + offset); ++ seq_show_option(seq, root_path + offset, NULL); + + if (append) + seq_puts(seq, ",append"); +--- a/fs/ocfs2/super.c ++++ b/fs/ocfs2/super.c +@@ -1550,8 +1550,8 @@ static int ocfs2_show_options(struct seq + seq_printf(s, ",localflocks,"); + + if (osb->osb_cluster_stack[0]) +- seq_printf(s, ",cluster_stack=%.*s", OCFS2_STACK_LABEL_LEN, +- osb->osb_cluster_stack); ++ seq_show_option_n(s, "cluster_stack", osb->osb_cluster_stack, ++ OCFS2_STACK_LABEL_LEN); + if (opts & OCFS2_MOUNT_USRQUOTA) + seq_printf(s, ",usrquota"); + if (opts & OCFS2_MOUNT_GRPQUOTA) +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -517,10 +517,10 @@ static int ovl_show_options(struct seq_f + struct super_block *sb = dentry->d_sb; + struct ovl_fs *ufs = sb->s_fs_info; + +- seq_printf(m, ",lowerdir=%s", ufs->config.lowerdir); ++ seq_show_option(m, "lowerdir", ufs->config.lowerdir); + if (ufs->config.upperdir) { +- seq_printf(m, ",upperdir=%s", ufs->config.upperdir); +- seq_printf(m, ",workdir=%s", ufs->config.workdir); ++ seq_show_option(m, "upperdir", ufs->config.upperdir); ++ seq_show_option(m, "workdir", ufs->config.workdir); + } + return 0; + } +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -714,18 +714,20 @@ static int reiserfs_show_options(struct + seq_puts(seq, ",acl"); + + if (REISERFS_SB(s)->s_jdev) +- seq_printf(seq, ",jdev=%s", REISERFS_SB(s)->s_jdev); ++ seq_show_option(seq, "jdev", REISERFS_SB(s)->s_jdev); + + if (journal->j_max_commit_age != journal->j_default_max_commit_age) + seq_printf(seq, ",commit=%d", journal->j_max_commit_age); + + #ifdef CONFIG_QUOTA + if (REISERFS_SB(s)->s_qf_names[USRQUOTA]) +- seq_printf(seq, ",usrjquota=%s", REISERFS_SB(s)->s_qf_names[USRQUOTA]); ++ seq_show_option(seq, "usrjquota", ++ REISERFS_SB(s)->s_qf_names[USRQUOTA]); + else if (opts & (1 << REISERFS_USRQUOTA)) + seq_puts(seq, ",usrquota"); + if (REISERFS_SB(s)->s_qf_names[GRPQUOTA]) +- seq_printf(seq, ",grpjquota=%s", REISERFS_SB(s)->s_qf_names[GRPQUOTA]); ++ seq_show_option(seq, "grpjquota", ++ REISERFS_SB(s)->s_qf_names[GRPQUOTA]); + else if (opts & (1 << REISERFS_GRPQUOTA)) + seq_puts(seq, ",grpquota"); + if (REISERFS_SB(s)->s_jquota_fmt) { +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -504,9 +504,9 @@ xfs_showargs( + seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10); + + if (mp->m_logname) +- seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname); ++ seq_show_option(m, MNTOPT_LOGDEV, mp->m_logname); + if (mp->m_rtname) +- seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname); ++ seq_show_option(m, MNTOPT_RTDEV, mp->m_rtname); + + if (mp->m_dalign > 0) + seq_printf(m, "," MNTOPT_SUNIT "=%d", +--- a/include/linux/seq_file.h ++++ b/include/linux/seq_file.h +@@ -148,6 +148,41 @@ static inline struct user_namespace *seq + #endif + } + ++/** ++ * seq_show_options - display mount options with appropriate escapes. ++ * @m: the seq_file handle ++ * @name: the mount option name ++ * @value: the mount option name's value, can be NULL ++ */ ++static inline void seq_show_option(struct seq_file *m, const char *name, ++ const char *value) ++{ ++ seq_putc(m, ','); ++ seq_escape(m, name, ",= \t\n\\"); ++ if (value) { ++ seq_putc(m, '='); ++ seq_escape(m, value, ", \t\n\\"); ++ } ++} ++ ++/** ++ * seq_show_option_n - display mount options with appropriate escapes ++ * where @value must be a specific length. ++ * @m: the seq_file handle ++ * @name: the mount option name ++ * @value: the mount option name's value, cannot be NULL ++ * @length: the length of @value to display ++ * ++ * This is a macro since this uses "length" to define the size of the ++ * stack buffer. ++ */ ++#define seq_show_option_n(m, name, value, length) { \ ++ char val_buf[length + 1]; \ ++ strncpy(val_buf, value, length); \ ++ val_buf[length] = '\0'; \ ++ seq_show_option(m, name, val_buf); \ ++} ++ + #define SEQ_START_TOKEN ((void *)1) + /* + * Helpers for iteration over list_head-s in seq_files +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -1319,7 +1319,7 @@ static int cgroup_show_options(struct se + + for_each_subsys(ss, ssid) + if (root->subsys_mask & (1 << ssid)) +- seq_printf(seq, ",%s", ss->name); ++ seq_show_option(seq, ss->name, NULL); + if (root->flags & CGRP_ROOT_NOPREFIX) + seq_puts(seq, ",noprefix"); + if (root->flags & CGRP_ROOT_XATTR) +@@ -1327,13 +1327,14 @@ static int cgroup_show_options(struct se + + spin_lock(&release_agent_path_lock); + if (strlen(root->release_agent_path)) +- seq_printf(seq, ",release_agent=%s", root->release_agent_path); ++ seq_show_option(seq, "release_agent", ++ root->release_agent_path); + spin_unlock(&release_agent_path_lock); + + if (test_bit(CGRP_CPUSET_CLONE_CHILDREN, &root->cgrp.flags)) + seq_puts(seq, ",clone_children"); + if (strlen(root->name)) +- seq_printf(seq, ",name=%s", root->name); ++ seq_show_option(seq, "name", root->name); + return 0; + } + +--- a/net/ceph/ceph_common.c ++++ b/net/ceph/ceph_common.c +@@ -495,8 +495,11 @@ int ceph_print_client_options(struct seq + struct ceph_options *opt = client->options; + size_t pos = m->count; + +- if (opt->name) +- seq_printf(m, "name=%s,", opt->name); ++ if (opt->name) { ++ seq_puts(m, "name="); ++ seq_escape(m, opt->name, ", \t\n\\"); ++ seq_putc(m, ','); ++ } + if (opt->key) + seq_puts(m, "secret=,"); + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -1095,7 +1095,7 @@ static void selinux_write_opts(struct se + seq_puts(m, prefix); + if (has_comma) + seq_putc(m, '\"'); +- seq_puts(m, opts->mnt_opts[i]); ++ seq_escape(m, opts->mnt_opts[i], "\"\n\\"); + if (has_comma) + seq_putc(m, '\"'); + } diff --git a/queue-4.1/fs-set-the-size-of-empty-dirs-to-0.patch b/queue-4.1/fs-set-the-size-of-empty-dirs-to-0.patch new file mode 100644 index 00000000000..82fa189cb1d --- /dev/null +++ b/queue-4.1/fs-set-the-size-of-empty-dirs-to-0.patch @@ -0,0 +1,36 @@ +From 4b75de8615050c1b0dd8d7794838c42f74ed36ba Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 12 Aug 2015 15:00:12 -0500 +Subject: fs: Set the size of empty dirs to 0. + +From: "Eric W. Biederman" + +commit 4b75de8615050c1b0dd8d7794838c42f74ed36ba upstream. + +Before the make_empty_dir_inode calls were introduce into proc, sysfs, +and sysctl those directories when stated reported an i_size of 0. +make_empty_dir_inode started reporting an i_size of 2. At least one +userspace application depended on stat returning i_size of 0. So +modify make_empty_dir_inode to cause an i_size of 0 to be reported for +these directories. + +Reported-by: Tejun Heo +Acked-by: Tejun Heo +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/libfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -1176,7 +1176,7 @@ void make_empty_dir_inode(struct inode * + inode->i_uid = GLOBAL_ROOT_UID; + inode->i_gid = GLOBAL_ROOT_GID; + inode->i_rdev = 0; +- inode->i_size = 2; ++ inode->i_size = 0; + inode->i_blkbits = PAGE_SHIFT; + inode->i_blocks = 0; + diff --git a/queue-4.1/hpfs-update-ctime-and-mtime-on-directory-modification.patch b/queue-4.1/hpfs-update-ctime-and-mtime-on-directory-modification.patch new file mode 100644 index 00000000000..3c4c6771196 --- /dev/null +++ b/queue-4.1/hpfs-update-ctime-and-mtime-on-directory-modification.patch @@ -0,0 +1,110 @@ +From f49a26e7718dd30b49e3541e3e25aecf5e7294e2 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Wed, 2 Sep 2015 22:51:53 +0200 +Subject: hpfs: update ctime and mtime on directory modification + +From: Mikulas Patocka + +commit f49a26e7718dd30b49e3541e3e25aecf5e7294e2 upstream. + +Update ctime and mtime when a directory is modified. (though OS/2 doesn't +update them anyway) + +Signed-off-by: Mikulas Patocka +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hpfs/namei.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +--- a/fs/hpfs/namei.c ++++ b/fs/hpfs/namei.c +@@ -8,6 +8,17 @@ + #include + #include "hpfs_fn.h" + ++static void hpfs_update_directory_times(struct inode *dir) ++{ ++ time_t t = get_seconds(); ++ if (t == dir->i_mtime.tv_sec && ++ t == dir->i_ctime.tv_sec) ++ return; ++ dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t; ++ dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0; ++ hpfs_write_inode_nolock(dir); ++} ++ + static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) + { + const unsigned char *name = dentry->d_name.name; +@@ -99,6 +110,7 @@ static int hpfs_mkdir(struct inode *dir, + result->i_mode = mode | S_IFDIR; + hpfs_write_inode_nolock(result); + } ++ hpfs_update_directory_times(dir); + d_instantiate(dentry, result); + hpfs_unlock(dir->i_sb); + return 0; +@@ -187,6 +199,7 @@ static int hpfs_create(struct inode *dir + result->i_mode = mode | S_IFREG; + hpfs_write_inode_nolock(result); + } ++ hpfs_update_directory_times(dir); + d_instantiate(dentry, result); + hpfs_unlock(dir->i_sb); + return 0; +@@ -262,6 +275,7 @@ static int hpfs_mknod(struct inode *dir, + insert_inode_hash(result); + + hpfs_write_inode_nolock(result); ++ hpfs_update_directory_times(dir); + d_instantiate(dentry, result); + brelse(bh); + hpfs_unlock(dir->i_sb); +@@ -340,6 +354,7 @@ static int hpfs_symlink(struct inode *di + insert_inode_hash(result); + + hpfs_write_inode_nolock(result); ++ hpfs_update_directory_times(dir); + d_instantiate(dentry, result); + hpfs_unlock(dir->i_sb); + return 0; +@@ -423,6 +438,8 @@ again: + out1: + hpfs_brelse4(&qbh); + out: ++ if (!err) ++ hpfs_update_directory_times(dir); + hpfs_unlock(dir->i_sb); + return err; + } +@@ -477,6 +494,8 @@ static int hpfs_rmdir(struct inode *dir, + out1: + hpfs_brelse4(&qbh); + out: ++ if (!err) ++ hpfs_update_directory_times(dir); + hpfs_unlock(dir->i_sb); + return err; + } +@@ -595,7 +614,7 @@ static int hpfs_rename(struct inode *old + goto end1; + } + +- end: ++end: + hpfs_i(i)->i_parent_dir = new_dir->i_ino; + if (S_ISDIR(i->i_mode)) { + inc_nlink(new_dir); +@@ -610,6 +629,10 @@ static int hpfs_rename(struct inode *old + brelse(bh); + } + end1: ++ if (!err) { ++ hpfs_update_directory_times(old_dir); ++ hpfs_update_directory_times(new_dir); ++ } + hpfs_unlock(i->i_sb); + return err; + } diff --git a/queue-4.1/series b/queue-4.1/series index 14512e97f31..aa067542615 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -95,3 +95,8 @@ arm-dts-fix-clock-frequency-of-display-timing0-for-exynos3250-rinato.patch arm-omap2-dra7-clockdomain-change-l4per2_7xx_clkdm-to-sw_wkup.patch arm-rockchip-fix-the-cpu-soft-reset.patch arm-dts-rockchip-fix-rk3288-watchdog-irq.patch +acpi-pci-penalize-legacy-irq-used-by-acpi-sci.patch +drivercore-fix-unregistration-path-of-platform-devices.patch +fs-set-the-size-of-empty-dirs-to-0.patch +hpfs-update-ctime-and-mtime-on-directory-modification.patch +fs-create-and-use-seq_show_option-for-escaping.patch