From: Greg Kroah-Hartman Date: Tue, 22 Aug 2006 19:45:53 +0000 (-0700) Subject: v2.6.17.10 release X-Git-Tag: v2.6.17.10^0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=047336f0f4f30b92f59d61f5a89531282e5c08fa;p=thirdparty%2Fkernel%2Fstable-queue.git v2.6.17.10 release --- diff --git a/releases/2.6.17.10/elv_unregister-fix-possible-crash-on-module-unload.patch b/releases/2.6.17.10/elv_unregister-fix-possible-crash-on-module-unload.patch new file mode 100644 index 00000000000..55392660db2 --- /dev/null +++ b/releases/2.6.17.10/elv_unregister-fix-possible-crash-on-module-unload.patch @@ -0,0 +1,32 @@ +From oleg@tv-sign.ru Tue Aug 22 05:58:10 2006 +Date: Tue, 22 Aug 2006 21:22:13 +0400 +From: Oleg Nesterov +To: Andrew Morton +Cc: Jens Axboe , linux-kernel@vger.kernel.org, Greg KH +Subject: [PATCH] elv_unregister: fix possible crash on module unload +Message-ID: <20060822172213.GA401@oleg> +Content-Disposition: inline + +An exiting task or process which didn't do I/O yet have no io context, +elv_unregister() should check it is not NULL. + +Signed-off-by: Oleg Nesterov +Acked-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/elevator.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- linux-2.6.17.9.orig/block/elevator.c ++++ linux-2.6.17.9/block/elevator.c +@@ -766,7 +766,8 @@ void elv_unregister(struct elevator_type + read_lock(&tasklist_lock); + do_each_thread(g, p) { + task_lock(p); +- e->ops.trim(p->io_context); ++ if (p->io_context) ++ e->ops.trim(p->io_context); + task_unlock(p); + } while_each_thread(g, p); + read_unlock(&tasklist_lock); diff --git a/releases/2.6.17.10/fix-possible-udf-deadlock-and-memory-corruption.patch b/releases/2.6.17.10/fix-possible-udf-deadlock-and-memory-corruption.patch new file mode 100644 index 00000000000..bb57e35c24d --- /dev/null +++ b/releases/2.6.17.10/fix-possible-udf-deadlock-and-memory-corruption.patch @@ -0,0 +1,116 @@ +From jack+f-150806@ucw.cz Tue Aug 15 04:55:08 2006 +Date: Tue, 15 Aug 2006 13:56:26 +0200 +From: Jan Kara +To: Greg KH +Cc: Alan Cox , vendor-sec@lst.de, + security@kernel.org, Jan Kara +Subject: Fix possible UDF deadlock and memory corruption (CVE-2006-4145) +Message-ID: <20060815115626.GF23663@atrey.karlin.mff.cuni.cz> +Content-Disposition: inline + +From: Jan Kara + +UDF code is not really ready to handle extents larger that 1GB. This is +the easy way to forbid creating those. + +Also truncation code did not count with the case when there are no +extents in the file and we are extending the file. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/udf/super.c | 2 - + fs/udf/truncate.c | 64 ++++++++++++++++++++++++++++++++---------------------- + 2 files changed, 40 insertions(+), 26 deletions(-) + +--- linux-2.6.17.9.orig/fs/udf/super.c ++++ linux-2.6.17.9/fs/udf/super.c +@@ -1653,7 +1653,7 @@ static int udf_fill_super(struct super_b + iput(inode); + goto error_out; + } +- sb->s_maxbytes = MAX_LFS_FILESIZE; ++ sb->s_maxbytes = 1<<30; + return 0; + + error_out: +--- linux-2.6.17.9.orig/fs/udf/truncate.c ++++ linux-2.6.17.9/fs/udf/truncate.c +@@ -239,37 +239,51 @@ void udf_truncate_extents(struct inode * + { + if (offset) + { +- extoffset -= adsize; +- etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); +- if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) +- { +- extoffset -= adsize; +- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); +- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); ++ /* ++ * OK, there is not extent covering inode->i_size and ++ * no extent above inode->i_size => truncate is ++ * extending the file by 'offset'. ++ */ ++ if ((!bh && extoffset == udf_file_entry_alloc_offset(inode)) || ++ (bh && extoffset == sizeof(struct allocExtDesc))) { ++ /* File has no extents at all! */ ++ memset(&eloc, 0x00, sizeof(kernel_lb_addr)); ++ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; ++ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); + } +- else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) +- { +- kernel_lb_addr neloc = { 0, 0 }; ++ else { + extoffset -= adsize; +- nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | +- ((elen + offset + inode->i_sb->s_blocksize - 1) & +- ~(inode->i_sb->s_blocksize - 1)); +- udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); +- udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); +- } +- else +- { +- if (elen & (inode->i_sb->s_blocksize - 1)) ++ etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1); ++ if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) + { + extoffset -= adsize; +- elen = EXT_RECORDED_ALLOCATED | +- ((elen + inode->i_sb->s_blocksize - 1) & ++ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset); ++ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0); ++ } ++ else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) ++ { ++ kernel_lb_addr neloc = { 0, 0 }; ++ extoffset -= adsize; ++ nelen = EXT_NOT_RECORDED_NOT_ALLOCATED | ++ ((elen + offset + inode->i_sb->s_blocksize - 1) & + ~(inode->i_sb->s_blocksize - 1)); +- udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); ++ udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1); ++ udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1); ++ } ++ else ++ { ++ if (elen & (inode->i_sb->s_blocksize - 1)) ++ { ++ extoffset -= adsize; ++ elen = EXT_RECORDED_ALLOCATED | ++ ((elen + inode->i_sb->s_blocksize - 1) & ++ ~(inode->i_sb->s_blocksize - 1)); ++ udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1); ++ } ++ memset(&eloc, 0x00, sizeof(kernel_lb_addr)); ++ elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; ++ udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); + } +- memset(&eloc, 0x00, sizeof(kernel_lb_addr)); +- elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset; +- udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1); + } + } + } diff --git a/releases/2.6.17.10/fix-sctp-privilege-elevation.patch b/releases/2.6.17.10/fix-sctp-privilege-elevation.patch new file mode 100644 index 00000000000..295d5fac178 --- /dev/null +++ b/releases/2.6.17.10/fix-sctp-privilege-elevation.patch @@ -0,0 +1,181 @@ +From chrisw@sous-sol.org Tue Aug 22 11:48:38 2006 +Date: Tue, 22 Aug 2006 11:50:39 -0700 +From: Sridhar Samudrala +To: Greg KH +Cc: Chris Wright , David_Marcus@McAfee.com, security@kernel.org, sri@us.ibm.com, Wei_Wang@McAfee.com, Zheng_Bu@McAfee.com, Anthony_Bettini@McAfee.com, vendor-sec@lst.de +Subject: Fix sctp privilege elevation (CVE-2006-3745) +Message-ID: <20060822185039.GF10348@sequoia.sous-sol.org> +Content-Disposition: inline + +From: Sridhar Samudrala + +sctp_make_abort_user() now takes the msg_len along with the msg +so that we don't have to recalculate the bytes in iovec. +It also uses memcpy_fromiovec() so that we don't go beyond the +length allocated. + +It is good to have this fix even if verify_iovec() is fixed to +return error on overflow. + +Signed-off-by: Sridhar Samudrala +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/sctp/sctp.h | 13 ------------- + include/net/sctp/sm.h | 3 +-- + net/sctp/sm_make_chunk.c | 30 +++++++++--------------------- + net/sctp/sm_statefuns.c | 20 ++++---------------- + net/sctp/socket.c | 10 +++++++++- + 5 files changed, 23 insertions(+), 53 deletions(-) + +--- linux-2.6.17.9.orig/include/net/sctp/sctp.h ++++ linux-2.6.17.9/include/net/sctp/sctp.h +@@ -405,19 +405,6 @@ static inline int sctp_list_single_entry + return ((head->next != head) && (head->next == head->prev)); + } + +-/* Calculate the size (in bytes) occupied by the data of an iovec. */ +-static inline size_t get_user_iov_size(struct iovec *iov, int iovlen) +-{ +- size_t retval = 0; +- +- for (; iovlen > 0; --iovlen) { +- retval += iov->iov_len; +- iov++; +- } +- +- return retval; +-} +- + /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ + static inline __s32 sctp_jitter(__u32 rto) + { +--- linux-2.6.17.9.orig/include/net/sctp/sm.h ++++ linux-2.6.17.9/include/net/sctp/sm.h +@@ -221,8 +221,7 @@ struct sctp_chunk *sctp_make_abort_no_da + const struct sctp_chunk *, + __u32 tsn); + struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *, +- const struct sctp_chunk *, +- const struct msghdr *); ++ const struct msghdr *, size_t msg_len); + struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *, + const struct sctp_chunk *, + const __u8 *, +--- linux-2.6.17.9.orig/net/sctp/sm_make_chunk.c ++++ linux-2.6.17.9/net/sctp/sm_make_chunk.c +@@ -806,38 +806,26 @@ no_mem: + + /* Helper to create ABORT with a SCTP_ERROR_USER_ABORT error. */ + struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc, +- const struct sctp_chunk *chunk, +- const struct msghdr *msg) ++ const struct msghdr *msg, ++ size_t paylen) + { + struct sctp_chunk *retval; +- void *payload = NULL, *payoff; +- size_t paylen = 0; +- struct iovec *iov = NULL; +- int iovlen = 0; +- +- if (msg) { +- iov = msg->msg_iov; +- iovlen = msg->msg_iovlen; +- paylen = get_user_iov_size(iov, iovlen); +- } ++ void *payload = NULL; ++ int err; + +- retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen); ++ retval = sctp_make_abort(asoc, NULL, sizeof(sctp_errhdr_t) + paylen); + if (!retval) + goto err_chunk; + + if (paylen) { + /* Put the msg_iov together into payload. */ +- payload = kmalloc(paylen, GFP_ATOMIC); ++ payload = kmalloc(paylen, GFP_KERNEL); + if (!payload) + goto err_payload; +- payoff = payload; + +- for (; iovlen > 0; --iovlen) { +- if (copy_from_user(payoff, iov->iov_base,iov->iov_len)) +- goto err_copy; +- payoff += iov->iov_len; +- iov++; +- } ++ err = memcpy_fromiovec(payload, msg->msg_iov, paylen); ++ if (err < 0) ++ goto err_copy; + } + + sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen); +--- linux-2.6.17.9.orig/net/sctp/sm_statefuns.c ++++ linux-2.6.17.9/net/sctp/sm_statefuns.c +@@ -4026,18 +4026,12 @@ sctp_disposition_t sctp_sf_do_9_1_prm_ab + * from its upper layer, but retransmits data to the far end + * if necessary to fill gaps. + */ +- struct msghdr *msg = arg; +- struct sctp_chunk *abort; ++ struct sctp_chunk *abort = arg; + sctp_disposition_t retval; + + retval = SCTP_DISPOSITION_CONSUME; + +- /* Generate ABORT chunk to send the peer. */ +- abort = sctp_make_abort_user(asoc, NULL, msg); +- if (!abort) +- retval = SCTP_DISPOSITION_NOMEM; +- else +- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); ++ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + + /* Even if we can't send the ABORT due to low memory delete the + * TCB. This is a departure from our typical NOMEM handling. +@@ -4161,8 +4155,7 @@ sctp_disposition_t sctp_sf_cookie_wait_p + void *arg, + sctp_cmd_seq_t *commands) + { +- struct msghdr *msg = arg; +- struct sctp_chunk *abort; ++ struct sctp_chunk *abort = arg; + sctp_disposition_t retval; + + /* Stop T1-init timer */ +@@ -4170,12 +4163,7 @@ sctp_disposition_t sctp_sf_cookie_wait_p + SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); + retval = SCTP_DISPOSITION_CONSUME; + +- /* Generate ABORT chunk to send the peer */ +- abort = sctp_make_abort_user(asoc, NULL, msg); +- if (!abort) +- retval = SCTP_DISPOSITION_NOMEM; +- else +- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); ++ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + + sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, + SCTP_STATE(SCTP_STATE_CLOSED)); +--- linux-2.6.17.9.orig/net/sctp/socket.c ++++ linux-2.6.17.9/net/sctp/socket.c +@@ -1477,8 +1477,16 @@ SCTP_STATIC int sctp_sendmsg(struct kioc + goto out_unlock; + } + if (sinfo_flags & SCTP_ABORT) { ++ struct sctp_chunk *chunk; ++ ++ chunk = sctp_make_abort_user(asoc, msg, msg_len); ++ if (!chunk) { ++ err = -ENOMEM; ++ goto out_unlock; ++ } ++ + SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc); +- sctp_primitive_ABORT(asoc, msg); ++ sctp_primitive_ABORT(asoc, chunk); + err = 0; + goto out_unlock; + } diff --git a/releases/2.6.17.10/series b/releases/2.6.17.10/series new file mode 100644 index 00000000000..1b56a452d97 --- /dev/null +++ b/releases/2.6.17.10/series @@ -0,0 +1,3 @@ +fix-sctp-privilege-elevation.patch +fix-possible-udf-deadlock-and-memory-corruption.patch +elv_unregister-fix-possible-crash-on-module-unload.patch