From: Greg Kroah-Hartman Date: Tue, 4 Mar 2014 18:23:20 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.10.33~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8ea1bd02356aac8f8e4cdf23b8a0ef0daa43ff98;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: quota-fix-race-between-dqput-and-dquot_scan_active.patch selinux-bigendian-problems-with-filename-trans-rules.patch --- diff --git a/queue-3.4/quota-fix-race-between-dqput-and-dquot_scan_active.patch b/queue-3.4/quota-fix-race-between-dqput-and-dquot_scan_active.patch new file mode 100644 index 00000000000..ce99cfdbc8d --- /dev/null +++ b/queue-3.4/quota-fix-race-between-dqput-and-dquot_scan_active.patch @@ -0,0 +1,66 @@ +From 1362f4ea20fa63688ba6026e586d9746ff13a846 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 20 Feb 2014 17:02:27 +0100 +Subject: quota: Fix race between dqput() and dquot_scan_active() + +From: Jan Kara + +commit 1362f4ea20fa63688ba6026e586d9746ff13a846 upstream. + +Currently last dqput() can race with dquot_scan_active() causing it to +call callback for an already deactivated dquot. The race is as follows: + +CPU1 CPU2 + dqput() + spin_lock(&dq_list_lock); + if (atomic_read(&dquot->dq_count) > 1) { + - not taken + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + spin_unlock(&dq_list_lock); + ->release_dquot(dquot); + if (atomic_read(&dquot->dq_count) > 1) + - not taken + dquot_scan_active() + spin_lock(&dq_list_lock); + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + - not taken + atomic_inc(&dquot->dq_count); + spin_unlock(&dq_list_lock); + - proceeds to release dquot + ret = fn(dquot, priv); + - called for inactive dquot + +Fix the problem by making sure possible ->release_dquot() is finished by +the time we call the callback and new calls to it will notice reference +dquot_scan_active() has taken and bail out. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/quota/dquot.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -580,9 +580,17 @@ int dquot_scan_active(struct super_block + dqstats_inc(DQST_LOOKUPS); + dqput(old_dquot); + old_dquot = dquot; +- ret = fn(dquot, priv); +- if (ret < 0) +- goto out; ++ /* ++ * ->release_dquot() can be racing with us. Our reference ++ * protects us from new calls to it so just wait for any ++ * outstanding call and recheck the DQ_ACTIVE_B after that. ++ */ ++ wait_on_dquot(dquot); ++ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ++ ret = fn(dquot, priv); ++ if (ret < 0) ++ goto out; ++ } + spin_lock(&dq_list_lock); + /* We are safe to continue now because our dquot could not + * be moved out of the inuse list while we hold the reference */ diff --git a/queue-3.4/selinux-bigendian-problems-with-filename-trans-rules.patch b/queue-3.4/selinux-bigendian-problems-with-filename-trans-rules.patch new file mode 100644 index 00000000000..bf9da0e187b --- /dev/null +++ b/queue-3.4/selinux-bigendian-problems-with-filename-trans-rules.patch @@ -0,0 +1,42 @@ +From 9085a6422900092886da8c404e1c5340c4ff1cbf Mon Sep 17 00:00:00 2001 +From: Eric Paris +Date: Thu, 20 Feb 2014 10:56:45 -0500 +Subject: SELinux: bigendian problems with filename trans rules + +From: Eric Paris + +commit 9085a6422900092886da8c404e1c5340c4ff1cbf upstream. + +When writing policy via /sys/fs/selinux/policy I wrote the type and class +of filename trans rules in CPU endian instead of little endian. On +x86_64 this works just fine, but it means that on big endian arch's like +ppc64 and s390 userspace reads the policy and converts it from +le32_to_cpu. So the values are all screwed up. Write the values in le +format like it should have been to start. + +Signed-off-by: Eric Paris +Acked-by: Stephen Smalley +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/ss/policydb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/security/selinux/ss/policydb.c ++++ b/security/selinux/ss/policydb.c +@@ -3214,10 +3214,10 @@ static int filename_write_helper(void *k + if (rc) + return rc; + +- buf[0] = ft->stype; +- buf[1] = ft->ttype; +- buf[2] = ft->tclass; +- buf[3] = otype->otype; ++ buf[0] = cpu_to_le32(ft->stype); ++ buf[1] = cpu_to_le32(ft->ttype); ++ buf[2] = cpu_to_le32(ft->tclass); ++ buf[3] = cpu_to_le32(otype->otype); + + rc = put_entry(buf, sizeof(u32), 4, fp); + if (rc) diff --git a/queue-3.4/series b/queue-3.4/series index 529977e7eb1..7e76dbf6e3f 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -36,3 +36,5 @@ usb-ftdi_sio-add-cressi-leonardo-pid.patch hwmon-max1668-fix-writing-the-minimum-temperature.patch workqueue-ensure-task-is-valid-across-kthread_stop.patch perf-fix-hotplug-splat.patch +selinux-bigendian-problems-with-filename-trans-rules.patch +quota-fix-race-between-dqput-and-dquot_scan_active.patch