]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
v2.6.17.10 release v2.6.17.10
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Aug 2006 19:45:53 +0000 (12:45 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Aug 2006 19:45:53 +0000 (12:45 -0700)
releases/2.6.17.10/elv_unregister-fix-possible-crash-on-module-unload.patch [new file with mode: 0644]
releases/2.6.17.10/fix-possible-udf-deadlock-and-memory-corruption.patch [new file with mode: 0644]
releases/2.6.17.10/fix-sctp-privilege-elevation.patch [new file with mode: 0644]
releases/2.6.17.10/series [new file with mode: 0644]

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 (file)
index 0000000..5539266
--- /dev/null
@@ -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 <oleg@tv-sign.ru>
+To: Andrew Morton <akpm@osdl.org>
+Cc: Jens Axboe <axboe@suse.de>, linux-kernel@vger.kernel.org, Greg KH <greg@kroah.com>
+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 <oleg@tv-sign.ru>
+Acked-by: Jens Axboe <axboe@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..bb57e35
--- /dev/null
@@ -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 <jack@suse.cz>
+To: Greg KH <greg@kroah.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>, vendor-sec@lst.de,
+       security@kernel.org, Jan Kara <jack@suse.cz>
+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 <jack@suse.cz>
+
+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 <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..295d5fa
--- /dev/null
@@ -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 <sri@us.ibm.com>
+To: Greg KH <greg@kroah.com>
+Cc: Chris Wright <chrisw@sous-sol.org>, 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 <sri@us.ibm.com>
+
+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 <sri@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ 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 (file)
index 0000000..1b56a45
--- /dev/null
@@ -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