From a5dc67e6467be571d5f7832cc65d47bbb9a9ffab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 14 Jan 2010 07:33:22 -0800 Subject: [PATCH] start .31 queue --- ...r-into-separate-add-remove-functions.patch | 178 ++++++++++++++++++ .../hwmon-adt7462-fix-pin-28-monitoring.patch | 31 +++ ...tion-leak-with-print-fatal-signals-1.patch | 50 +++++ ...ilter-ebtables-enforce-cap_net_admin.patch | 45 +++++ ...-out-of-bounds-read-in-update_nl_seq.patch | 58 ++++++ ...-for-filesystems-different-from-ext4.patch | 38 ++++ queue-2.6.31/series | 6 + 7 files changed, 406 insertions(+) create mode 100644 queue-2.6.31/fasync-split-fasync_helper-into-separate-add-remove-functions.patch create mode 100644 queue-2.6.31/hwmon-adt7462-fix-pin-28-monitoring.patch create mode 100644 queue-2.6.31/kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch create mode 100644 queue-2.6.31/netfilter-ebtables-enforce-cap_net_admin.patch create mode 100644 queue-2.6.31/netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch create mode 100644 queue-2.6.31/quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch create mode 100644 queue-2.6.31/series diff --git a/queue-2.6.31/fasync-split-fasync_helper-into-separate-add-remove-functions.patch b/queue-2.6.31/fasync-split-fasync_helper-into-separate-add-remove-functions.patch new file mode 100644 index 00000000000..623bdc49b2b --- /dev/null +++ b/queue-2.6.31/fasync-split-fasync_helper-into-separate-add-remove-functions.patch @@ -0,0 +1,178 @@ +From 53281b6d34d44308372d16acb7fb5327609f68b6 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Wed, 16 Dec 2009 08:23:37 -0800 +Subject: fasync: split 'fasync_helper()' into separate add/remove functions + +From: Linus Torvalds + +commit 53281b6d34d44308372d16acb7fb5327609f68b6 upstream. + +Yes, the add and remove cases do share the same basic loop and the +locking, but the compiler can inline and then CSE some of the end result +anyway. And splitting it up makes the code way easier to follow, +and makes it clearer exactly what the semantics are. + +In particular, we must make sure that the FASYNC flag in file->f_flags +exactly matches the state of "is this file on any fasync list", since +not only is that flag visible to user space (F_GETFL), but we also use +that flag to check whether we need to remove any fasync entries on file +close. + +We got that wrong for the case of a mixed use of file locking (which +tries to remove any fasync entries for file leases) and fasync. + +Splitting the function up also makes it possible to do some future +optimizations without making the function even messier. In particular, +since the FASYNC flag has to match the state of "is this on a list", we +can do the following future optimizations: + + - on remove, we don't even need to get the locks and traverse the list + if FASYNC isn't set, since we can know a priori that there is no + point (this is effectively the same optimization that we already do + in __fput() wrt removing fasync on file close) + + - on add, we can use the FASYNC flag to decide whether we are changing + an existing entry or need to allocate a new one. + +but this is just the cleanup + fix for the FASYNC flag. + +Acked-by: Al Viro +Tested-by: Tavis Ormandy +Cc: Jeff Dike +Cc: Matt Mackall +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fcntl.c | 102 +++++++++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 66 insertions(+), 36 deletions(-) + +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -526,60 +526,90 @@ static DEFINE_RWLOCK(fasync_lock); + static struct kmem_cache *fasync_cache __read_mostly; + + /* +- * fasync_helper() is used by almost all character device drivers +- * to set up the fasync queue. It returns negative on error, 0 if it did +- * no changes and positive if it added/deleted the entry. ++ * Remove a fasync entry. If successfully removed, return ++ * positive and clear the FASYNC flag. If no entry exists, ++ * do nothing and return 0. ++ * ++ * NOTE! It is very important that the FASYNC flag always ++ * match the state "is the filp on a fasync list". ++ * ++ * We always take the 'filp->f_lock', in since fasync_lock ++ * needs to be irq-safe. + */ +-int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) ++static int fasync_remove_entry(struct file *filp, struct fasync_struct **fapp) + { + struct fasync_struct *fa, **fp; +- struct fasync_struct *new = NULL; + int result = 0; + +- if (on) { +- new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); +- if (!new) +- return -ENOMEM; ++ spin_lock(&filp->f_lock); ++ write_lock_irq(&fasync_lock); ++ for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { ++ if (fa->fa_file != filp) ++ continue; ++ *fp = fa->fa_next; ++ kmem_cache_free(fasync_cache, fa); ++ filp->f_flags &= ~FASYNC; ++ result = 1; ++ break; + } ++ write_unlock_irq(&fasync_lock); ++ spin_unlock(&filp->f_lock); ++ return result; ++} ++ ++/* ++ * Add a fasync entry. Return negative on error, positive if ++ * added, and zero if did nothing but change an existing one. ++ * ++ * NOTE! It is very important that the FASYNC flag always ++ * match the state "is the filp on a fasync list". ++ */ ++static int fasync_add_entry(int fd, struct file *filp, struct fasync_struct **fapp) ++{ ++ struct fasync_struct *new, *fa, **fp; ++ int result = 0; ++ ++ new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); ++ if (!new) ++ return -ENOMEM; + +- /* +- * We need to take f_lock first since it's not an IRQ-safe +- * lock. +- */ + spin_lock(&filp->f_lock); + write_lock_irq(&fasync_lock); + for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) { +- if (fa->fa_file == filp) { +- if(on) { +- fa->fa_fd = fd; +- kmem_cache_free(fasync_cache, new); +- } else { +- *fp = fa->fa_next; +- kmem_cache_free(fasync_cache, fa); +- result = 1; +- } +- goto out; +- } ++ if (fa->fa_file != filp) ++ continue; ++ fa->fa_fd = fd; ++ kmem_cache_free(fasync_cache, new); ++ goto out; + } + +- if (on) { +- new->magic = FASYNC_MAGIC; +- new->fa_file = filp; +- new->fa_fd = fd; +- new->fa_next = *fapp; +- *fapp = new; +- result = 1; +- } ++ new->magic = FASYNC_MAGIC; ++ new->fa_file = filp; ++ new->fa_fd = fd; ++ new->fa_next = *fapp; ++ *fapp = new; ++ result = 1; ++ filp->f_flags |= FASYNC; ++ + out: +- if (on) +- filp->f_flags |= FASYNC; +- else +- filp->f_flags &= ~FASYNC; + write_unlock_irq(&fasync_lock); + spin_unlock(&filp->f_lock); + return result; + } + ++/* ++ * fasync_helper() is used by almost all character device drivers ++ * to set up the fasync queue, and for regular files by the file ++ * lease code. It returns negative on error, 0 if it did no changes ++ * and positive if it added/deleted the entry. ++ */ ++int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) ++{ ++ if (!on) ++ return fasync_remove_entry(filp, fapp); ++ return fasync_add_entry(fd, filp, fapp); ++} ++ + EXPORT_SYMBOL(fasync_helper); + + void __kill_fasync(struct fasync_struct *fa, int sig, int band) diff --git a/queue-2.6.31/hwmon-adt7462-fix-pin-28-monitoring.patch b/queue-2.6.31/hwmon-adt7462-fix-pin-28-monitoring.patch new file mode 100644 index 00000000000..9dc562a431f --- /dev/null +++ b/queue-2.6.31/hwmon-adt7462-fix-pin-28-monitoring.patch @@ -0,0 +1,31 @@ +From bb595c923bc51dff9cdd112de18deb57ac7945d2 Mon Sep 17 00:00:00 2001 +From: Roger Blofeld +Date: Sun, 10 Jan 2010 20:52:32 +0100 +Subject: hwmon: (adt7462) Fix pin 28 monitoring + +From: Roger Blofeld + +commit bb595c923bc51dff9cdd112de18deb57ac7945d2 upstream. + +The ADT7462_PIN28_VOLT value is a 4-bit field, so the corresponding +shift must be 4. + +Signed-off-by: Roger Blofeld +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/adt7462.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/adt7462.c ++++ b/drivers/hwmon/adt7462.c +@@ -97,7 +97,7 @@ I2C_CLIENT_INSMOD_1(adt7462); + #define ADT7462_PIN24_SHIFT 6 + #define ADT7462_PIN26_VOLT_INPUT 0x08 + #define ADT7462_PIN25_VOLT_INPUT 0x20 +-#define ADT7462_PIN28_SHIFT 6 /* cfg3 */ ++#define ADT7462_PIN28_SHIFT 4 /* cfg3 */ + #define ADT7462_PIN28_VOLT 0x5 + + #define ADT7462_REG_ALARM1 0xB8 diff --git a/queue-2.6.31/kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch b/queue-2.6.31/kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch new file mode 100644 index 00000000000..5ea9fee0a0a --- /dev/null +++ b/queue-2.6.31/kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch @@ -0,0 +1,50 @@ +From b45c6e76bc2c72f6426c14bed64fdcbc9bf37cb0 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Fri, 8 Jan 2010 14:42:52 -0800 +Subject: kernel/signal.c: fix kernel information leak with print-fatal-signals=1 + +From: Andi Kleen + +commit b45c6e76bc2c72f6426c14bed64fdcbc9bf37cb0 upstream. + +When print-fatal-signals is enabled it's possible to dump any memory +reachable by the kernel to the log by simply jumping to that address from +user space. + +Or crash the system if there's some hardware with read side effects. + +The fatal signals handler will dump 16 bytes at the execution address, +which is fully controlled by ring 3. + +In addition when something jumps to a unmapped address there will be up to +16 additional useless page faults, which might be potentially slow (and at +least is not very efficient) + +Fortunately this option is off by default and only there on i386. + +But fix it by checking for kernel addresses and also stopping when there's +a page fault. + +Signed-off-by: Andi Kleen +Cc: Ingo Molnar +Cc: Oleg Nesterov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -939,7 +939,8 @@ static void print_fatal_signal(struct pt + for (i = 0; i < 16; i++) { + unsigned char insn; + +- __get_user(insn, (unsigned char *)(regs->ip + i)); ++ if (get_user(insn, (unsigned char *)(regs->ip + i))) ++ break; + printk("%02x ", insn); + } + } diff --git a/queue-2.6.31/netfilter-ebtables-enforce-cap_net_admin.patch b/queue-2.6.31/netfilter-ebtables-enforce-cap_net_admin.patch new file mode 100644 index 00000000000..bc3ba1f6ba3 --- /dev/null +++ b/queue-2.6.31/netfilter-ebtables-enforce-cap_net_admin.patch @@ -0,0 +1,45 @@ +From dce766af541f6605fa9889892c0280bab31c66ab Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Fri, 8 Jan 2010 17:31:24 +0100 +Subject: netfilter: ebtables: enforce CAP_NET_ADMIN + +From: Florian Westphal + +commit dce766af541f6605fa9889892c0280bab31c66ab upstream. + +normal users are currently allowed to set/modify ebtables rules. +Restrict it to processes with CAP_NET_ADMIN. + +Note that this cannot be reproduced with unmodified ebtables binary +because it uses SOCK_RAW. + +Signed-off-by: Florian Westphal +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -1405,6 +1405,9 @@ static int do_ebt_set_ctl(struct sock *s + { + int ret; + ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ + switch(cmd) { + case EBT_SO_SET_ENTRIES: + ret = do_replace(sock_net(sk), user, len); +@@ -1424,6 +1427,9 @@ static int do_ebt_get_ctl(struct sock *s + struct ebt_replace tmp; + struct ebt_table *t; + ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + diff --git a/queue-2.6.31/netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch b/queue-2.6.31/netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch new file mode 100644 index 00000000000..c6cb552aaec --- /dev/null +++ b/queue-2.6.31/netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch @@ -0,0 +1,58 @@ +From aaff23a95aea5f000895f50d90e91f1e2f727002 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Thu, 7 Jan 2010 18:33:18 +0100 +Subject: netfilter: nf_ct_ftp: fix out of bounds read in update_nl_seq() + +From: Patrick McHardy + +commit aaff23a95aea5f000895f50d90e91f1e2f727002 upstream. + +As noticed by Dan Carpenter , update_nl_seq() +currently contains an out of bounds read of the seq_aft_nl array +when looking for the oldest sequence number position. + +Fix it to only compare valid positions. + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_conntrack_ftp.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +--- a/net/netfilter/nf_conntrack_ftp.c ++++ b/net/netfilter/nf_conntrack_ftp.c +@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn + struct nf_ct_ftp_master *info, int dir, + struct sk_buff *skb) + { +- unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; ++ unsigned int i, oldest; + + /* Look for oldest: if we find exact match, we're done. */ + for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { + if (info->seq_aft_nl[dir][i] == nl_seq) + return; +- +- if (oldest == info->seq_aft_nl_num[dir] || +- before(info->seq_aft_nl[dir][i], +- info->seq_aft_nl[dir][oldest])) +- oldest = i; + } + + if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { + info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; +- } else if (oldest != NUM_SEQ_TO_REMEMBER && +- after(nl_seq, info->seq_aft_nl[dir][oldest])) { +- info->seq_aft_nl[dir][oldest] = nl_seq; ++ } else { ++ if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1])) ++ oldest = 0; ++ else ++ oldest = 1; ++ ++ if (after(nl_seq, info->seq_aft_nl[dir][oldest])) ++ info->seq_aft_nl[dir][oldest] = nl_seq; + } + } + diff --git a/queue-2.6.31/quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch b/queue-2.6.31/quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch new file mode 100644 index 00000000000..c4c09663d1a --- /dev/null +++ b/queue-2.6.31/quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch @@ -0,0 +1,38 @@ +From 05b5d898235401c489c68e1f3bc5706a29ad5713 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 6 Jan 2010 18:03:36 +0100 +Subject: quota: Fix dquot_transfer for filesystems different from ext4 + +From: Jan Kara + +commit 05b5d898235401c489c68e1f3bc5706a29ad5713 upstream. + +Commit fd8fbfc1 modified the way we find amount of reserved space +belonging to an inode. The amount of reserved space is checked +from dquot_transfer and thus inode_reserved_space gets called +even for filesystems that don't provide get_reserved_space callback +which results in a BUG. + +Fix the problem by checking get_reserved_space callback and return 0 if +the filesystem does not provide it. + +CC: Dmitry Monakhov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/quota/dquot.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -1425,6 +1425,9 @@ static void inode_sub_rsv_space(struct i + static qsize_t inode_get_rsv_space(struct inode *inode) + { + qsize_t ret; ++ ++ if (!inode->i_sb->dq_op->get_reserved_space) ++ return 0; + spin_lock(&inode->i_lock); + ret = *inode_reserved_space(inode); + spin_unlock(&inode->i_lock); diff --git a/queue-2.6.31/series b/queue-2.6.31/series new file mode 100644 index 00000000000..44ca58476e8 --- /dev/null +++ b/queue-2.6.31/series @@ -0,0 +1,6 @@ +fasync-split-fasync_helper-into-separate-add-remove-functions.patch +hwmon-adt7462-fix-pin-28-monitoring.patch +kernel-signal.c-fix-kernel-information-leak-with-print-fatal-signals-1.patch +netfilter-ebtables-enforce-cap_net_admin.patch +netfilter-nf_ct_ftp-fix-out-of-bounds-read-in-update_nl_seq.patch +quota-fix-dquot_transfer-for-filesystems-different-from-ext4.patch -- 2.47.3