Re: freeze exception -- bugzilla3 3.6.3.0-1
On 12/26/2010 01:22 PM, Mehdi Dogguy wrote:
>
> I'll wait for your comments before uploading.
>
FTR, I've uploaded Bugzilla to testing-proposed-updates.
(debdiff is attached, fixed an issue found by Julien).
Regards,
--
Mehdi Dogguy مهدي الدڤي
http://dogguy.org/
diff -Nru bugzilla-3.6.2.0/debian/bugzilla3.config bugzilla-3.6.2.0/debian/bugzilla3.config
--- bugzilla-3.6.2.0/debian/bugzilla3.config 2010-08-27 09:51:13.000000000 +0200
+++ bugzilla-3.6.2.0/debian/bugzilla3.config 2010-12-25 21:25:38.000000000 +0100
@@ -138,6 +138,11 @@
ask_again "bugzilla3/bugzilla_admin_pwd" "bugzilla3/pwd_check"
fi
db_endblock
+
+ # Do not repeat if we are in non-interactive mode.
+ if [ "$DEBIAN_FRONTEND" = "noninteractive" ]; then
+ break
+ fi
done
# vim:ts=4 et sw=4
diff -Nru bugzilla-3.6.2.0/debian/bugzilla3.postinst bugzilla-3.6.2.0/debian/bugzilla3.postinst
--- bugzilla-3.6.2.0/debian/bugzilla3.postinst 2010-10-27 13:46:06.000000000 +0200
+++ bugzilla-3.6.2.0/debian/bugzilla3.postinst 2010-12-25 21:29:28.000000000 +0100
@@ -137,9 +137,9 @@
if [ "$mode" = "configure" ]; then
# Fix file/directory permissions.
- run_script $BUGZILLA_ETCDIR/post-checksetup.d/10setdefaultdpkgstatoverride 2>&1 >/dev/null \
+ run_script $BUGZILLA_ETCDIR/post-checksetup.d/10setdefaultdpkgstatoverride >/dev/null 2>&1 \
|| true
- run_script $BUGZILLA_ETCDIR/post-checksetup.d/15restoredpkgstatoverride 2>&1 >/dev/null \
+ run_script $BUGZILLA_ETCDIR/post-checksetup.d/15restoredpkgstatoverride >/dev/null 2>&1 \
|| true
# Setup a preleminary /etc/bugzilla3/params file.
diff -Nru bugzilla-3.6.2.0/debian/changelog bugzilla-3.6.2.0/debian/changelog
--- bugzilla-3.6.2.0/debian/changelog 2010-12-05 18:55:32.000000000 +0100
+++ bugzilla-3.6.2.0/debian/changelog 2010-12-26 01:06:06.000000000 +0100
@@ -1,3 +1,13 @@
+bugzilla (3.6.2.0-4.2) testing-proposed-updates; urgency=low
+
+ * Non-maintainer upload.
+ * Support for noninteractive mode in Debconf (Closes: #602738)
+ * Add security patches (Closes: #602420):
+ - 50_cve-2010-3172.sh fixes CVE-2010-3172
+ - 70_cve-2010-3764.sh fixes CVE-2010-3764 (and remove 50_graphdir.sh)
+
+ -- Mehdi Dogguy <mehdi@debian.org> Sat, 25 Dec 2010 22:25:55 +0100
+
bugzilla (3.6.2.0-4.1) testing-proposed-updates; urgency=low
* Non-maintainer upload.
diff -Nru bugzilla-3.6.2.0/debian/maintenance/50_graphdir.sh bugzilla-3.6.2.0/debian/maintenance/50_graphdir.sh
--- bugzilla-3.6.2.0/debian/maintenance/50_graphdir.sh 2010-08-08 18:49:32.000000000 +0200
+++ bugzilla-3.6.2.0/debian/maintenance/50_graphdir.sh 1970-01-01 01:00:00.000000000 +0100
@@ -1,69 +0,0 @@
-#!/bin/sh
-# https://bugs.launchpad.net/ubuntu/+source/bugzilla/+bug/419335
-set -e
-
-echo "> $0 $*"
-
-cd "$1" && patch -p1 < "$0"
-
-exit 0
-
-diff -Naur a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
---- a/Bugzilla/Install/Filesystem.pm 2010-07-14 01:09:27.000000000 +0200
-+++ b/Bugzilla/Install/Filesystem.pm 2010-08-08 18:13:35.534125065 +0200
-@@ -176,7 +176,7 @@
- dirs => $ws_dir_writeable },
- $webdotdir => { files => $ws_writeable,
- dirs => $ws_dir_writeable },
-- graphs => { files => $ws_writeable,
-+ "$datadir/graphs" => { files => $ws_writeable,
- dirs => $ws_dir_writeable },
-
- # Readable directories
-@@ -228,7 +228,7 @@
- "$datadir/extensions" => $ws_dir_readable,
- $attachdir => $ws_dir_writeable,
- $extensionsdir => $ws_dir_readable,
-- graphs => $ws_dir_writeable,
-+ "$datadir/graphs" => $ws_dir_writeable,
- $webdotdir => $ws_dir_writeable,
- "$skinsdir/custom" => $ws_dir_readable,
- "$skinsdir/contrib" => $ws_dir_readable,
-@@ -358,10 +358,10 @@
- my %files = %{$fs->{create_files}};
-
- my $datadir = bz_locations->{'datadir'};
-- # If the graphs/ directory doesn't exist, we're upgrading from
-+ # If the $datadir/graphs/ directory doesn't exist, we're upgrading from
- # a version old enough that we need to update the $datadir/mining
- # format.
-- if (-d "$datadir/mining" && !-d 'graphs') {
-+ if (-d "$datadir/mining" && !-d "$datadir/graphs") {
- _update_old_charts($datadir);
- }
-
-diff -Naur a/collectstats.pl b/collectstats.pl
---- a/collectstats.pl 2010-07-06 20:20:12.000000000 +0200
-+++ b/collectstats.pl 2010-08-08 18:17:23.746133772 +0200
-@@ -49,9 +49,11 @@
- # in the regenerate mode).
- $| = 1;
-
-+my $datadir = bz_locations()->{'datadir'};
-+
- # Tidy up after graphing module
- my $cwd = Cwd::getcwd();
--if (chdir("graphs")) {
-+if (chdir("$datadir/graphs")) {
- unlink <./*.gif>;
- unlink <./*.png>;
- # chdir("..") doesn't work if graphs is a symlink, see bug 429378
-@@ -68,8 +70,6 @@
- $regenerate = 1;
- }
-
--my $datadir = bz_locations()->{'datadir'};
--
- my @myproducts = map {$_->name} Bugzilla::Product->get_all;
- unshift(@myproducts, "-All-");
-
diff -Nru bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3172.sh bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3172.sh
--- bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3172.sh 1970-01-01 01:00:00.000000000 +0100
+++ bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3172.sh 2010-12-25 22:25:45.000000000 +0100
@@ -0,0 +1,23 @@
+#!/bin/sh
+# cve-2010-3172
+set -e
+
+echo "> $0 $*"
+
+cd "$1" && patch -p1 < "$0"
+
+exit 0
+
+diff -Naur a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
+--- a/Bugzilla/CGI.pm 2010-07-15 19:34:25.000000000 +0200
++++ b/Bugzilla/CGI.pm 2010-12-25 22:19:04.000000000 +0100
+@@ -223,7 +223,8 @@
+ }
+
+ # Set the MIME boundary and content-type
+- my $boundary = $param{'-boundary'} || '------- =_aaaaaaaaaa0';
++ my $boundary = $param{'-boundary'}
++ || '------- =_' . generate_random_password(16);
+ delete $param{'-boundary'};
+ $self->{'separator'} = "\r\n--$boundary\r\n";
+ $self->{'final_separator'} = "\r\n--$boundary--\r\n";
diff -Nru bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3764.sh bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3764.sh
--- bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3764.sh 1970-01-01 01:00:00.000000000 +0100
+++ bugzilla-3.6.2.0/debian/maintenance/70_cve-2010-3764.sh 2010-12-28 20:59:42.000000000 +0100
@@ -0,0 +1,326 @@
+#!/bin/sh
+# cve-2010-3764
+set -e
+
+echo "> $0 $*"
+
+cd "$1" && patch -p1 < "$0"
+
+exit 0
+
+diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
+index 2f6e72e..105954b 100644
+--- a/Bugzilla/Install/Filesystem.pm
++++ b/Bugzilla/Install/Filesystem.pm
+@@ -176,7 +176,7 @@ sub FILESYSTEM {
+ dirs => $ws_dir_writeable },
+ $webdotdir => { files => $ws_writeable,
+ dirs => $ws_dir_writeable },
+- graphs => { files => $ws_writeable,
++ "$datadir/graphs" => { files => $ws_writeable,
+ dirs => $ws_dir_writeable },
+
+ # Readable directories
+@@ -228,7 +228,7 @@ sub FILESYSTEM {
+ "$datadir/extensions" => $ws_dir_readable,
+ $attachdir => $ws_dir_writeable,
+ $extensionsdir => $ws_dir_readable,
+- graphs => $ws_dir_writeable,
++ "$datadir/graphs" => $ws_dir_writeable,
+ $webdotdir => $ws_dir_writeable,
+ "$skinsdir/custom" => $ws_dir_readable,
+ "$skinsdir/contrib" => $ws_dir_readable,
+@@ -329,11 +329,24 @@ EOT
+ "$datadir/.htaccess" => { perms => $ws_readable, contents => <<EOT
+ # Nothing in this directory is retrievable unless overridden by an .htaccess
+ # in a subdirectory.
+-deny from all
++Deny from all
+ EOT
+
+
+ },
++
++ "$datadir/graphs/.htaccess" => { perms => $ws_readable, contents => <<EOT
++# Allow access to .png and .gif files.
++<FilesMatch (\\.gif|\\.png)\$>
++ Allow from all
++</FilesMatch>
++
++# And no directory listings, either.
++Deny from all
++EOT
++
++ },
++
+ );
+
+ my %all_files = (%create_files, %htaccess, %index_html, %files);
+@@ -358,10 +371,10 @@ sub update_filesystem {
+ my %files = %{$fs->{create_files}};
+
+ my $datadir = bz_locations->{'datadir'};
+- # If the graphs/ directory doesn't exist, we're upgrading from
++ # If the $datadir/graphs/ directory doesn't exist, we're upgrading from
+ # a version old enough that we need to update the $datadir/mining
+ # format.
+- if (-d "$datadir/mining" && !-d 'graphs') {
++ if (-d "$datadir/mining" && !-d "$datadir/graphs") {
+ _update_old_charts($datadir);
+ }
+
+diff --git a/collectstats.pl b/collectstats.pl
+index 733a1e4..86ca07c 100755
+--- a/collectstats.pl
++++ b/collectstats.pl
+@@ -49,9 +49,11 @@ use Bugzilla::Field;
+ # in the regenerate mode).
+ $| = 1;
+
++my $datadir = bz_locations()->{'datadir'};
++
+ # Tidy up after graphing module
+ my $cwd = Cwd::getcwd();
+-if (chdir("graphs")) {
++if (chdir("$datadir/graphs")) {
+ unlink <./*.gif>;
+ unlink <./*.png>;
+ # chdir("..") doesn't work if graphs is a symlink, see bug 429378
+@@ -68,8 +70,6 @@ if ($#ARGV >= 0 && $ARGV[0] eq "--regenerate") {
+ $regenerate = 1;
+ }
+
+-my $datadir = bz_locations()->{'datadir'};
+-
+ my @myproducts = map {$_->name} Bugzilla::Product->get_all;
+ unshift(@myproducts, "-All-");
+
+diff --git a/reports.cgi b/reports.cgi
+index b53d952..d5e781f 100755
+--- a/reports.cgi
++++ b/reports.cgi
+@@ -45,9 +45,15 @@ use Bugzilla::Util;
+ use Bugzilla::Error;
+ use Bugzilla::Status;
+
++use File::Basename;
++use Digest::MD5 qw(md5_hex);
++
+ # If we're using bug groups for products, we should apply those restrictions
+ # to viewing reports, as well. Time to check the login in that case.
+ my $user = Bugzilla->login();
++my $cgi = Bugzilla->cgi;
++my $template = Bugzilla->template;
++my $vars = {};
+
+ if (!Bugzilla->feature('old_charts')) {
+ ThrowCodeError('feature_disabled', { feature => 'old_charts' });
+@@ -55,21 +61,12 @@ if (!Bugzilla->feature('old_charts')) {
+
+ my $dir = bz_locations()->{'datadir'} . "/mining";
+ my $graph_url = 'graphs';
+-my $graph_dir = bz_locations()->{'libpath'} . '/' .$graph_url;
++my $graph_dir = bz_locations()->{'datadir'} . "/" .$graph_url;
++my $product_name = $cgi->param('product') || '';
+
+ Bugzilla->switch_to_shadow_db();
+
+-my $cgi = Bugzilla->cgi;
+-my $template = Bugzilla->template;
+-my $vars = {};
+-
+-# We only want those products that the user has permissions for.
+-my @myproducts;
+-push( @myproducts, "-All-");
+-# Extract product names from objects and add them to the list.
+-push( @myproducts, map { $_->name } @{$user->get_selectable_products} );
+-
+-if (! defined $cgi->param('product')) {
++if (!$product_name) {
+ # Can we do bug charts?
+ (-d $dir && -d $graph_dir)
+ || ThrowCodeError('chart_dir_nonexistent',
+@@ -87,50 +84,62 @@ if (! defined $cgi->param('product')) {
+ push(@datasets, $datasets);
+ }
+
++ # We only want those products that the user has permissions for.
++ my @myproducts = ('-All-');
++ # Extract product names from objects and add them to the list.
++ push( @myproducts, map { $_->name } @{$user->get_selectable_products} );
++
+ $vars->{'datasets'} = \@datasets;
+ $vars->{'products'} = \@myproducts;
+
+ print $cgi->header();
+-
+- $template->process('reports/old-charts.html.tmpl', $vars)
+- || ThrowTemplateError($template->error());
+- exit(1);
+ }
+ else {
+- my $product = $cgi->param('product');
+-
+ # For security and correctness, validate the value of the "product" form variable.
+ # Valid values are those products for which the user has permissions which appear
+ # in the "product" drop-down menu on the report generation form.
+- grep($_ eq $product, @myproducts)
+- || ThrowUserError("invalid_product_name", {product => $product});
++ my ($product) = grep { $_->name eq $product_name } @{$user->get_selectable_products};
++ ($product || $product_name eq '-All-')
++ || ThrowUserError('invalid_product_name', {product => $product_name});
++
++ # Product names can change over time. Their ID cannot; so use the ID
++ # to generate the filename.
++ my $prod_id = $product ? $product->id : 0;
+
+- # We've checked that the product exists, and that the user can see it
+- # This means that is OK to detaint
+- trick_taint($product);
++ # Make sure there is something to plot.
++ my @datasets = $cgi->param('datasets');
++ scalar(@datasets) || ThrowUserError('missing_datasets');
+
+- defined($cgi->param('datasets')) || ThrowUserError('missing_datasets');
++ if (grep { $_ !~ /^[A-Za-z0-9:_-]+$/ } @datasets) {
++ ThrowUserError('invalid_datasets', {'datasets' => \@datasets});
++ }
+
+- my $datasets = join('', $cgi->param('datasets'));
++ # Filenames must not be guessable as they can point to products
++ # you are not allowed to see. Also, different projects can have
++ # the same product names.
++ my $key = Bugzilla->localconfig->{'site_wide_secret'};
++ my $project = bz_locations()->{'project'} || '';
++ my $image_file = join(':', ($key, $project, $prod_id, @datasets));
++ # Wide characters cause md5_hex() to die.
++ if (Bugzilla->params->{'utf8'}) {
++ utf8::encode($image_file) if utf8::is_utf8($image_file);
++ }
+
+ my $type = chart_image_type();
+- my $data_file = daily_stats_filename($product);
+- my $image_file = chart_image_name($data_file, $type, $datasets);
+- my $url_image = correct_urlbase() . "$graph_url/$image_file";
++ $image_file = md5_hex($image_file) . ".$type";
++ trick_taint($image_file);
+
+ if (! -e "$graph_dir/$image_file") {
+- generate_chart("$dir/$data_file", "$graph_dir/$image_file", $type,
+- $product, $datasets);
++ generate_chart($dir, "$graph_dir/$image_file", $type, $product, \@datasets);
+ }
+
+- $vars->{'url_image'} = $url_image;
++ $vars->{'url_image'} = "$graph_url/$image_file";
+
+ print $cgi->header(-Content_Disposition=>'inline; filename=bugzilla_report.html');
+-
+- $template->process('reports/old-charts.html.tmpl', $vars)
+- || ThrowTemplateError($template->error());
+- exit(1);
+ }
++$template->process('reports/old-charts.html.tmpl', $vars)
++ || ThrowTemplateError($template->error());
++exit(1);
+
+ #####################
+ # Subroutines #
+@@ -140,9 +149,8 @@ sub get_data {
+ my $dir = shift;
+
+ my @datasets;
+- my $datafile = daily_stats_filename('-All-');
+- open(DATA, '<', "$dir/$datafile")
+- || ThrowCodeError('chart_file_open_fail', {filename => "$dir/$datafile"});
++ open(DATA, '<', "$dir/-All-")
++ || ThrowCodeError('chart_file_open_fail', {filename => "$dir/-All-"});
+
+ while (<DATA>) {
+ if (/^# fields?: (.+)\s*$/) {
+@@ -154,12 +162,6 @@ sub get_data {
+ return @datasets;
+ }
+
+-sub daily_stats_filename {
+- my ($prodname) = @_;
+- $prodname =~ s/\//-/gs;
+- return $prodname;
+-}
+-
+ sub chart_image_type {
+ # what chart type should we be generating?
+ my $testimg = Chart::Lines->new(2,2);
+@@ -169,32 +171,12 @@ sub chart_image_type {
+ return $type;
+ }
+
+-sub chart_image_name {
+- my ($data_file, $type, $datasets) = @_;
+-
+- # This routine generates a filename from the requested fields. The problem
+- # is that we have to check the safety of doing this. We can't just require
+- # that the fields exist, because what stats were collected could change
+- # over time (eg by changing the resolutions available)
+- # Instead, just require that each field name consists only of letters,
+- # numbers, underscores and hyphens.
+-
+- if ($datasets !~ m/^[A-Za-z0-9:_-]+$/) {
+- ThrowUserError('invalid_datasets', {'datasets' => $datasets});
+- }
+-
+- # Since we pass the tests, consider it OK
+- trick_taint($datasets);
+-
+- # Cache charts by generating a unique filename based on what they
+- # show. Charts should be deleted by collectstats.pl nightly.
+- my $id = join ("_", split (":", $datasets));
+-
+- return "${data_file}_${id}.$type";
+-}
+-
+ sub generate_chart {
+- my ($data_file, $image_file, $type, $product, $datasets) = @_;
++ my ($dir, $image_file, $type, $product, $datasets) = @_;
++ $product = $product ? $product->name : '-All-';
++ my $data_file = $product;
++ $data_file =~ s/\//-/gs;
++ $data_file = $dir . '/' . $data_file;
+
+ if (! open FILE, $data_file) {
+ if ($product eq '-All-') {
+@@ -205,7 +187,7 @@ sub generate_chart {
+
+ my @fields;
+ my @labels = qw(DATE);
+- my %datasets = map { $_ => 1 } split /:/, $datasets;
++ my %datasets = map { $_ => 1 } @$datasets;
+
+ my %data = ();
+ while (<FILE>) {
+diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl
+index e59b6c5..1bfc0af 100644
+--- a/template/en/default/global/user-error.html.tmpl
++++ b/template/en/default/global/user-error.html.tmpl
+@@ -911,7 +911,7 @@
+
+ [% ELSIF error == "invalid_datasets" %]
+ [% title = "Invalid Datasets" %]
+- Invalid datasets <em>[% datasets FILTER html %]</em>. Only digits,
++ Invalid datasets <em>[% datasets.join(":") FILTER html %]</em>. Only digits,
+ letters and colons are allowed.
+
+ [% ELSIF error == "invalid_format" %]
+diff --git a/template/en/default/reports/old-charts.html.tmpl b/template/en/default/reports/old-charts.html.tmpl
+index ca3ba6c..4bdc0cf 100644
+--- a/template/en/default/reports/old-charts.html.tmpl
++++ b/template/en/default/reports/old-charts.html.tmpl
+@@ -51,7 +51,7 @@
+ [%# We cannot use translated statuses and resolutions from field-descs.none.html
+ # because old charts do not distinguish statuses from resolutions. %]
+ [% FOREACH dataset = datasets %]
+- <option value="[% dataset.value FILTER html %]:"
++ <option value="[% dataset.value FILTER html %]"
+ [% " selected=\"selected\"" IF dataset.selected %]>
+ [% dataset.value FILTER html %]</option>
+ [% END %]
Reply to: