[bugzilla/el5] Backport fixes for CVE-2011-2379, CVE-2011-2380, CVE-2011-2381, CVE-2011-2978 and CVE-2011-2976.

Xavier Bachelot xavierb at fedoraproject.org
Sun Oct 23 13:50:48 UTC 2011


commit a722fd3b7f7413de29eca8792c6e546e9d220dca
Author: Xavier Bachelot <xavier at bachelot.org>
Date:   Fri Sep 16 01:58:12 2011 +0200

    Backport fixes for CVE-2011-2379, CVE-2011-2380, CVE-2011-2381, CVE-2011-2978 and CVE-2011-2976.

 bugzilla-3.2.10-CVE-2011-2379.patch |  240 +++++++++++++++++++++++++++++++++++
 bugzilla-3.2.10-CVE-2011-2380.patch |   28 ++++
 bugzilla-3.2.10-CVE-2011-2381.patch |   27 ++++
 bugzilla-3.2.10-CVE-2011-2976.patch |   96 ++++++++++++++
 bugzilla-3.2.10-CVE-2011-2978.patch |   13 ++
 bugzilla.spec                       |   23 +++-
 6 files changed, 424 insertions(+), 3 deletions(-)
---
diff --git a/bugzilla-3.2.10-CVE-2011-2379.patch b/bugzilla-3.2.10-CVE-2011-2379.patch
new file mode 100644
index 0000000..047ddba
--- /dev/null
+++ b/bugzilla-3.2.10-CVE-2011-2379.patch
@@ -0,0 +1,240 @@
+=== modified file 'Bugzilla/Attachment/PatchReader.pm'
+--- Bugzilla/Attachment/PatchReader.pm	2008-06-29 22:35:28 +0000
++++ Bugzilla/Attachment/PatchReader.pm	2011-07-07 06:04:15 +0000
+@@ -37,6 +37,7 @@
+         $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
+         # Actually print out the patch.
+         print $cgi->header(-type => 'text/plain',
++                           -x_content_type_options => "nosniff",
+                            -expires => '+3M');
+         disable_utf8();
+         $reader->iterate_string('Attachment ' . $attachment->id, $attachment->data);
+@@ -118,6 +119,7 @@
+         $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
+         # Actually print out the patch.
+         print $cgi->header(-type => 'text/plain',
++                           -x_content_type_options => "nosniff",
+                            -expires => '+3M');
+         disable_utf8();
+     }
+
+=== modified file 'attachment.cgi'
+--- attachment.cgi	2009-09-30 08:53:25 +0000
++++ attachment.cgi	2011-07-21 06:21:26 +0000
+@@ -71,10 +71,13 @@
+ 
+ # Determine whether to use the action specified by the user or the default.
+ my $action = $cgi->param('action') || 'view';
++my $format = $cgi->param('format') || '';
+ 
+ # You must use the appropriate urlbase/sslbase param when doing anything
+-# but viewing an attachment.
+-if ($action ne 'view') {
++# but viewing an attachment, or a raw diff.
++if ($action ne 'view'
++    && (($action !~ /^(?:interdiff|diff)$/) || $format ne 'raw'))
++{
+     my $urlbase = Bugzilla->params->{'urlbase'};
+     my $sslbase = Bugzilla->params->{'sslbase'};
+     my $path_regexp = $sslbase ? qr/^(\Q$urlbase\E|\Q$sslbase\E)/ : qr/^\Q$urlbase\E/;
+@@ -172,7 +175,8 @@
+     # non-natural, so use the original value from $cgi in our exception
+     # message here.
+     detaint_natural($attach_id)
+-     || ThrowUserError("invalid_attach_id", { attach_id => $cgi->param($param) });
++      || ThrowUserError("invalid_attach_id",
++                        { attach_id => scalar $cgi->param($param) });
+   
+     # Make sure the attachment exists in the database.
+     my $attachment = Bugzilla::Attachment->get($attach_id)
+@@ -249,53 +253,71 @@
+                         { bug_id => $bugid });
+ }
+ 
+-################################################################################
+-# Functions
+-################################################################################
++# Gets the attachment object(s) generated by validateID, while ensuring
++# attachbase and token authentication is used when required.
++sub get_attachment {
++    my @field_names = @_ ? @_ : qw(id);
+ 
+-# Display an attachment.
+-sub view {
+-    my $attachment;
++    my %attachments;
+ 
+     if (use_attachbase()) {
+-        $attachment = validateID(undef, 1);
+-        # Replace %bugid% by the ID of the bug the attachment belongs to, if present.
++        # Load each attachment, and ensure they are all from the same bug
++        my $bug_id = 0;
++        foreach my $field_name (@field_names) {
++            my $attachment = validateID($field_name, 1);
++            if (!$bug_id) {
++                $bug_id = $attachment->bug_id;
++            } elsif ($attachment->bug_id != $bug_id) {
++                ThrowUserError('attachment_bug_id_mismatch');
++            }
++            $attachments{$field_name} = $attachment;
++        }
+         my $attachbase = Bugzilla->params->{'attachment_base'};
+-        my $bug_id = $attachment->bug_id;
+         $attachbase =~ s/%bugid%/$bug_id/;
+-        my $path = 'attachment.cgi?id=' . $attachment->id;
+-        # The user is allowed to override the content type of the attachment.
+-        if (defined $cgi->param('content_type')) {
+-            $path .= '&content_type=' . url_quote($cgi->param('content_type'));
+-        }
++        my @args = map { $_ . '=' . $attachments{$_}->id } @field_names;
++        my $cgi_params = $cgi->canonicalise_query(@field_names, 't',
++            'Bugzilla_login', 'Bugzilla_password');
++        push(@args, $cgi_params) if $cgi_params;
++        my $path = 'attachment.cgi?' . join('&', @args);
+ 
+         # Make sure the attachment is served from the correct server.
+         if ($cgi->self_url !~ /^\Q$attachbase\E/) {
+             # We couldn't call Bugzilla->login earlier as we first had to make sure
+             # we were not going to request credentials on the alternate host.
+             Bugzilla->login();
+-            if (attachmentIsPublic($attachment)) {
++            if (all_attachments_are_public(\%attachments)) {
+                 # No need for a token; redirect to attachment base.
+                 print $cgi->redirect(-location => $attachbase . $path);
+                 exit;
+             } else {
+                 # Make sure the user can view the attachment.
+-                check_can_access($attachment);
++                foreach my $field_name (@field_names) {
++                    check_can_access($attachments{$field_name});
++                }
+                 # Create a token and redirect.
+-                my $token = url_quote(issue_session_token($attachment->id));
++                my $token = url_quote(issue_session_token(pack_token_data(\%attachments)));
+                 print $cgi->redirect(-location => $attachbase . "$path&t=$token");
+                 exit;
+             }
+         } else {
+             # No need to validate the token for public attachments. We cannot request
+             # credentials as we are on the alternate host.
+-            if (!attachmentIsPublic($attachment)) {
++            if (!all_attachments_are_public(\%attachments)) {
+                 my $token = $cgi->param('t');
+-                my ($userid, undef, $token_attach_id) = Bugzilla::Token::GetTokenData($token);
+-                unless ($userid
+-                        && detaint_natural($token_attach_id)
+-                        && ($token_attach_id == $attachment->id))
+-                {
++                my ($userid, undef, $token_data) = Bugzilla::Token::GetTokenData($token);
++                my %token_data = unpack_token_data($token_data);
++                my $valid_token = 1;
++                foreach my $field_name (@field_names) {
++                    my $token_id = $token_data{$field_name};
++                    if (!$token_id
++                        || !detaint_natural($token_id)
++                        || $attachments{$field_name}->id != $token_id)
++                    {
++                        $valid_token = 0;
++                        last;
++                    }
++                }
++                unless ($userid && $valid_token) {
+                     # Not a valid token.
+                     print $cgi->redirect('-location' => correct_urlbase() . $path);
+                     exit;
+@@ -309,8 +331,48 @@
+     } else {
+         # No alternate host is used. Request credentials if required.
+         Bugzilla->login();
+-        $attachment = validateID();
+-    }
++        foreach my $field_name (@field_names) {
++            $attachments{$field_name} = validateID($field_name);
++        }
++    }
++
++    return wantarray
++        ? map { $attachments{$_} } @field_names
++        : $attachments{$field_names[0]};
++}
++
++sub all_attachments_are_public {
++    my $attachments = shift;
++    foreach my $field_name (keys %$attachments) {
++        if (!attachmentIsPublic($attachments->{$field_name})) {
++            return 0;
++        }
++    }
++    return 1;
++}
++
++sub pack_token_data {
++    my $attachments = shift;
++    return join(' ', map { $_ . '=' . $attachments->{$_}->id } keys %$attachments);
++}
++
++sub unpack_token_data {
++    my @token_data = split(/ /, shift || '');
++    my %data;
++    foreach my $token (@token_data) {
++        my ($field_name, $attach_id) = split('=', $token);
++        $data{$field_name} = $attach_id;
++    }
++    return %data;
++}
++
++################################################################################
++# Functions
++################################################################################
++
++# Display an attachment.
++sub view {
++    my $attachment = get_attachment();
+ 
+     # At this point, Bugzilla->login has been called if it had to.
+     my $contenttype = $attachment->contenttype;
+@@ -345,9 +407,14 @@
+ 
+ sub interdiff {
+     # Retrieve and validate parameters
+-    my $old_attachment = validateID('oldid');
+-    my $new_attachment = validateID('newid');
+     my $format = validateFormat('html', 'raw');
++    my($old_attachment, $new_attachment);
++    if ($format eq 'raw') {
++        ($old_attachment, $new_attachment) = get_attachment('oldid', 'newid');
++    } else {
++        $old_attachment = validateID('oldid');
++        $new_attachment = validateID('newid');
++    }
+     my $context = validateContext();
+ 
+     Bugzilla::Attachment::PatchReader::process_interdiff(
+@@ -356,8 +423,8 @@
+ 
+ sub diff {
+     # Retrieve and validate parameters
+-    my $attachment = validateID();
+     my $format = validateFormat('html', 'raw');
++    my $attachment = $format eq 'raw' ? get_attachment() : validateID();
+     my $context = validateContext();
+ 
+     # If it is not a patch, view normally.
+
+=== modified file 'contrib/fixperms.pl' (properties changed: -x to +x)
+=== modified file 'template/en/default/global/user-error.html.tmpl'
+--- template/en/default/global/user-error.html.tmpl	2010-11-02 23:12:13 +0000
++++ template/en/default/global/user-error.html.tmpl	2011-07-07 06:04:15 +0000
+@@ -102,6 +102,11 @@
+     [% terms.Bug %] aliases cannot be longer than 20 characters.
+     Please choose a shorter alias.
+ 
++  [% ELSIF error == "attachment_bug_id_mismatch" %]
++    [% title = "Invalid Attachments" %]
++    You tried to perform an action on attachments from different [% terms.bugs %].
++    This operation requires all attachments to be from the same [% terms.bug %].
++
+   [% ELSIF error == "auth_cant_create_account" %]
+     [% title = "Can't create accounts" %]
+     This site is using an authentication scheme which does not permit
+
diff --git a/bugzilla-3.2.10-CVE-2011-2380.patch b/bugzilla-3.2.10-CVE-2011-2380.patch
new file mode 100644
index 0000000..af94665
--- /dev/null
+++ b/bugzilla-3.2.10-CVE-2011-2380.patch
@@ -0,0 +1,28 @@
+=== modified file 'Bugzilla/Bug.pm'
+--- Bugzilla/Bug.pm	2010-10-28 15:27:58 +0000
++++ Bugzilla/Bug.pm	2011-08-01 21:28:07 +0000
+@@ -1403,7 +1403,7 @@
+             || ThrowUserError("invalid_group_ID");
+ 
+         # This can only happen if somebody hacked the enter_bug form.
+-        ThrowCodeError("inactive_group", { name => $group->name })
++        ThrowCodeError("inactive_group", { group_id => $id })
+             unless $group->is_active;
+ 
+         my $membercontrol = $controls->{$id}
+
+=== modified file 'template/en/default/global/code-error.html.tmpl'
+--- template/en/default/global/code-error.html.tmpl	2010-12-30 16:50:29 +0000
++++ template/en/default/global/code-error.html.tmpl	2011-08-01 21:29:11 +0000
+@@ -217,8 +217,8 @@
+     A legal [% field FILTER html %] was not set.
+ 
+   [% ELSIF error == "inactive_group" %]
+-    Attempted to add [% terms.bug %] to the '[% name FILTER html %]'
+-    group, which is not used for [% terms.bugs %].
++    Attempted to add [% terms.abug %] to group ID [% group_id FILTER html %],
++    which is not used for [% terms.bugs %].
+ 
+   [% ELSIF error == "invalid_attach_id_to_obsolete" %]
+      The attachment number of one of the attachments you wanted to obsolete,
+
diff --git a/bugzilla-3.2.10-CVE-2011-2381.patch b/bugzilla-3.2.10-CVE-2011-2381.patch
new file mode 100644
index 0000000..0d64a00
--- /dev/null
+++ b/bugzilla-3.2.10-CVE-2011-2381.patch
@@ -0,0 +1,27 @@
+=== modified file 'Bugzilla/Template.pm'
+--- Bugzilla/Template.pm	2011-02-14 21:56:52 +0000
++++ Bugzilla/Template.pm	2011-07-06 14:44:21 +0000
+@@ -549,6 +549,9 @@
+             # as prefix. In addition it replaces a ' ' by a '_'.
+             css_class_quote => \&Bugzilla::Util::css_class_quote ,
+ 
++            # Removes control characters and trims extra whitespace.
++            clean_text => \&Bugzilla::Util::clean_text ,
++
+             quoteUrls => [ sub {
+                                my ($context, $bug) = @_;
+                                return sub {
+
+=== modified file 'template/en/default/request/email.txt.tmpl'
+--- template/en/default/request/email.txt.tmpl	2009-09-03 19:05:33 +0000
++++ template/en/default/request/email.txt.tmpl	2011-07-06 14:43:11 +0000
+@@ -50,7 +50,7 @@
+ To: [% to %]
+ Subject: [% flag.type.name %] [%+ subject_status %]: [[% terms.Bug %] [%+ bug.bug_id %]] [% bug.short_desc %]
+ [%- IF attachment %] :
+-  [Attachment [% attachment.id %]] [% attachment.description %][% END %]
++  [Attachment [% attachment.id %]] [% attachment.description FILTER clean_text %][% END %]
+ X-Bugzilla-Type: request
+ [%+ threadingmarker %]
+ 
+
diff --git a/bugzilla-3.2.10-CVE-2011-2976.patch b/bugzilla-3.2.10-CVE-2011-2976.patch
new file mode 100644
index 0000000..c8d8e93
--- /dev/null
+++ b/bugzilla-3.2.10-CVE-2011-2976.patch
@@ -0,0 +1,96 @@
+=== modified file 'template/en/default/bug/navigate.html.tmpl'
+--- template/en/default/bug/navigate.html.tmpl	2008-01-28 01:21:11 +0000
++++ template/en/default/bug/navigate.html.tmpl	2011-05-26 19:06:35 +0000
+@@ -44,22 +44,24 @@
+   [% END %]
+ 
+ [% IF this_bug_idx != -1 %]
+-  <a href="show_bug.cgi?id=[% bug_list.first %]">First</a>
+-  <a href="show_bug.cgi?id=[% bug_list.last %]">Last</a>
++  <a href="show_bug.cgi?id=[% bug_list.first FILTER url_quote %]">First</a>
++  <a href="show_bug.cgi?id=[% bug_list.last FILTER url_quote %]">Last</a>
+ [% END %]
+ 
+   [% IF bug.bug_id %]
+     [% IF this_bug_idx != -1 %]
+       [% IF this_bug_idx > 0 %]
+         [% prev_bug = this_bug_idx - 1 %]
+-        <a href="show_bug.cgi?id=[% bug_list.$prev_bug %]">Prev</a>
++        <a href="show_bug.cgi?id=
++                 [%- bug_list.$prev_bug FILTER url_quote %]">Prev</a>
+       [% ELSE %]
+         <i><font color="#777777">Prev</font></i>
+       [% END %]
+ 
+       [% IF this_bug_idx + 1 < bug_list.size %]
+         [% next_bug = this_bug_idx + 1 %]
+-        <a href="show_bug.cgi?id=[% bug_list.$next_bug %]">Next</a>
++        <a href="show_bug.cgi?id=
++                 [%- bug_list.$next_bug FILTER url_quote %]">Next</a>
+       [% ELSE %]
+         <i><font color="#777777">Next</font></i>
+       [% END %]
+
+=== modified file 'template/en/default/filterexceptions.pl'
+--- template/en/default/filterexceptions.pl	2009-10-26 11:31:52 +0000
++++ template/en/default/filterexceptions.pl	2011-05-26 19:15:14 +0000
+@@ -250,10 +250,6 @@
+ ],
+ 
+ 'global/site-navigation.html.tmpl' => [
+-  'bug_list.first', 
+-  'bug_list.$prev_bug', 
+-  'bug_list.$next_bug', 
+-  'bug_list.last', 
+   'bug.bug_id', 
+   'bug.votes', 
+ ],
+@@ -300,13 +296,6 @@
+   '" spellcheck=\"$spellcheck\"" IF spellcheck',
+ ],
+ 
+-'bug/navigate.html.tmpl' => [
+-  'bug_list.first', 
+-  'bug_list.last', 
+-  'bug_list.$prev_bug', 
+-  'bug_list.$next_bug', 
+-],
+-
+ 'bug/show-multiple.html.tmpl' => [
+   'attachment.id', 
+   'flag.status',
+
+=== modified file 'template/en/default/global/site-navigation.html.tmpl'
+--- template/en/default/global/site-navigation.html.tmpl	2008-08-08 06:26:33 +0000
++++ template/en/default/global/site-navigation.html.tmpl	2011-05-26 19:16:12 +0000
+@@ -36,8 +36,10 @@
+   [% IF bug_list && bug_list.size > 0 %]
+     <link rel="Up" href="buglist.cgi?regetlastlist=1">
+ 
+-    <link rel="First" href="show_bug.cgi?id=[% bug_list.first %]">
+-    <link rel="Last" href="show_bug.cgi?id=[% bug_list.last %]">
++    <link rel="First" href="show_bug.cgi?id=
++                            [%- bug_list.first FILTER url_quote %]">
++    <link rel="Last" href="show_bug.cgi?id=
++                           [%- bug_list.last FILTER url_quote %]">
+ 
+     [% IF bug && bug.bug_id %]
+       [% current_bug_idx = lsearch(bug_list, bug.bug_id) %]
+@@ -45,12 +47,14 @@
+ 
+         [% IF current_bug_idx > 0 %]
+           [% prev_bug = current_bug_idx - 1 %]
+-          <link rel="Prev" href="show_bug.cgi?id=[% bug_list.$prev_bug %]">
++          <link rel="Prev" href="show_bug.cgi?id=
++                                 [%- bug_list.$prev_bug FILTER url_quote %]">
+         [% END %]
+ 
+         [% IF current_bug_idx + 1 < bug_list.size %]
+           [% next_bug = current_bug_idx + 1 %]
+-          <link rel="Next" href="show_bug.cgi?id=[% bug_list.$next_bug %]">
++          <link rel="Next" href="show_bug.cgi?id=
++                                 [%- bug_list.$next_bug FILTER url_quote %]">
+         [% END %]
+ 
+       [% END %]
+
diff --git a/bugzilla-3.2.10-CVE-2011-2978.patch b/bugzilla-3.2.10-CVE-2011-2978.patch
new file mode 100644
index 0000000..36508b9
--- /dev/null
+++ b/bugzilla-3.2.10-CVE-2011-2978.patch
@@ -0,0 +1,13 @@
+=== modified file 'userprefs.cgi'
+--- userprefs.cgi	2009-02-02 19:21:09 +0000
++++ userprefs.cgi	2011-07-22 08:00:33 +0000
+@@ -120,7 +120,7 @@
+         && Bugzilla->params->{"allowemailchange"}
+         && $cgi->param('new_login_name'))
+     {
+-        my $old_login_name = $cgi->param('Bugzilla_login');
++        my $old_login_name = $user->login;
+         my $new_login_name = trim($cgi->param('new_login_name'));
+ 
+         if($old_login_name ne $new_login_name) {
+
diff --git a/bugzilla.spec b/bugzilla.spec
index 3386c9c..55b9a23 100644
--- a/bugzilla.spec
+++ b/bugzilla.spec
@@ -6,13 +6,18 @@ URL: http://www.bugzilla.org/
 Name: bugzilla
 Version: 3.2.10
 Group: Applications/Publishing
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: MPLv1.1
 Source0: http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-%{version}.tar.gz
 Source1: bugzilla-httpd-conf
 Source2: README.fedora.bugzilla
 Patch0: bugzilla-rw-paths.patch
 Patch1: bugzilla-EL5-perl-versions.patch
+Patch2: bugzilla-3.2.10-CVE-2011-2379.patch
+Patch3: bugzilla-3.2.10-CVE-2011-2380.patch
+Patch4: bugzilla-3.2.10-CVE-2011-2381.patch
+Patch5: bugzilla-3.2.10-CVE-2011-2976.patch
+Patch6: bugzilla-3.2.10-CVE-2011-2978.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch: noarch
@@ -23,9 +28,9 @@ Requires: perl(File::Spec) >= 0.84
 Requires: perl(DBI) >= 1.41
 Requires: perl(Template) >= 2.15
 Requires: perl(Email::Send) >= 2.00
-Requires: perl(Email::MIME) >= 1.861
+Requires: perl(Email::MIME) >= 1.859
 Requires: perl(Email::MIME::Encodings) >= 1.313
-Requires: perl(Email::MIME::Modifier) >= 1.442
+Requires: perl(Email::MIME::Modifier) >= 1.441
 
 %package doc
 Summary: Bugzilla documentation
@@ -49,9 +54,15 @@ Documentation distributed with the Bugzilla bug tracking system
 Contributed scripts and functions for Bugzilla
 
 %prep
+set -x
 %setup -q -n %{name}-%{version}
 %patch0 -p1
 %patch1 -p2
+%patch2 -p0
+%patch3 -p0
+%patch4 -p0
+%patch5 -p0
+%patch6 -p0
 
 # Filter unwanted Requires found by /usr/lib/rpm/perldeps.pl:
 # create a wrapper script which runs the original perl_requires
@@ -88,6 +99,8 @@ for file in `find -type f -perm /664`; do
   fi
 done
 
+# Remove un-needed files
+find . -name *.orig -delete
 
 %install
 mkdir -p ${RPM_BUILD_ROOT}/%{bzinstallprefix}/bugzilla
@@ -151,6 +164,10 @@ popd > /dev/null)
 %{bzinstallprefix}/bugzilla/contrib
 
 %changelog
+* Thu Sep 15 2011 Xavier Bachelot <xavier at bachelot.org> - 3.2.10-2
+- Add patches for CVE-2011-2379, CVE-2011-2380, CVE-2011-2381, CVE-2011-2978
+  and CVE-2011-2976.
+
 * Tue May 03 2011 Xavier Bachelot <xavier at bachelot.org> - 3.2.10-1
 - Update to 3.2.10 for CVE-2010-4411, CVE-2010-4567, CVE-2010-4568,
   CVE-2010-4569, CVE-2010-4570, CVE-2010-4572, CVE-2011-0046, CVE-2011-0048)


More information about the scm-commits mailing list