|
| 1 | +/* |
| 2 | + * fix-CVE-2024-4317.sql |
| 3 | + * |
| 4 | + * Copyright (c) 2024, PostgreSQL Global Development Group |
| 5 | + * |
| 6 | + * src/backend/catalog/fix-CVE-2024-4317.sql |
| 7 | + * |
| 8 | + * This file should be run in every database in the cluster to address |
| 9 | + * CVE-2024-4317. |
| 10 | + */ |
| 11 | + |
| 12 | +SET search_path = pg_catalog; |
| 13 | + |
| 14 | +CREATE OR REPLACE VIEW pg_stats_ext WITH (security_barrier) AS |
| 15 | + SELECT cn.nspname AS schemaname, |
| 16 | + c.relname AS tablename, |
| 17 | + sn.nspname AS statistics_schemaname, |
| 18 | + s.stxname AS statistics_name, |
| 19 | + pg_get_userbyid(s.stxowner) AS statistics_owner, |
| 20 | + ( SELECT array_agg(a.attname ORDER BY a.attnum) |
| 21 | + FROM unnest(s.stxkeys) k |
| 22 | + JOIN pg_attribute a |
| 23 | + ON (a.attrelid = s.stxrelid AND a.attnum = k) |
| 24 | + ) AS attnames, |
| 25 | + pg_get_statisticsobjdef_expressions(s.oid) as exprs, |
| 26 | + s.stxkind AS kinds, |
| 27 | + sd.stxdndistinct AS n_distinct, |
| 28 | + sd.stxddependencies AS dependencies, |
| 29 | + m.most_common_vals, |
| 30 | + m.most_common_val_nulls, |
| 31 | + m.most_common_freqs, |
| 32 | + m.most_common_base_freqs |
| 33 | + FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid) |
| 34 | + JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid) |
| 35 | + LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace) |
| 36 | + LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace) |
| 37 | + LEFT JOIN LATERAL |
| 38 | + ( SELECT array_agg(values) AS most_common_vals, |
| 39 | + array_agg(nulls) AS most_common_val_nulls, |
| 40 | + array_agg(frequency) AS most_common_freqs, |
| 41 | + array_agg(base_frequency) AS most_common_base_freqs |
| 42 | + FROM pg_mcv_list_items(sd.stxdmcv) |
| 43 | + ) m ON sd.stxdmcv IS NOT NULL |
| 44 | + WHERE pg_has_role(c.relowner, 'USAGE') |
| 45 | + AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); |
| 46 | + |
| 47 | +CREATE OR REPLACE VIEW pg_stats_ext_exprs WITH (security_barrier) AS |
| 48 | + SELECT cn.nspname AS schemaname, |
| 49 | + c.relname AS tablename, |
| 50 | + sn.nspname AS statistics_schemaname, |
| 51 | + s.stxname AS statistics_name, |
| 52 | + pg_get_userbyid(s.stxowner) AS statistics_owner, |
| 53 | + stat.expr, |
| 54 | + (stat.a).stanullfrac AS null_frac, |
| 55 | + (stat.a).stawidth AS avg_width, |
| 56 | + (stat.a).stadistinct AS n_distinct, |
| 57 | + (CASE |
| 58 | + WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1 |
| 59 | + WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2 |
| 60 | + WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3 |
| 61 | + WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4 |
| 62 | + WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5 |
| 63 | + END) AS most_common_vals, |
| 64 | + (CASE |
| 65 | + WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1 |
| 66 | + WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2 |
| 67 | + WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3 |
| 68 | + WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4 |
| 69 | + WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5 |
| 70 | + END) AS most_common_freqs, |
| 71 | + (CASE |
| 72 | + WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1 |
| 73 | + WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2 |
| 74 | + WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3 |
| 75 | + WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4 |
| 76 | + WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5 |
| 77 | + END) AS histogram_bounds, |
| 78 | + (CASE |
| 79 | + WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1] |
| 80 | + WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1] |
| 81 | + WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1] |
| 82 | + WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1] |
| 83 | + WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1] |
| 84 | + END) correlation, |
| 85 | + (CASE |
| 86 | + WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1 |
| 87 | + WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2 |
| 88 | + WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3 |
| 89 | + WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4 |
| 90 | + WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5 |
| 91 | + END) AS most_common_elems, |
| 92 | + (CASE |
| 93 | + WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1 |
| 94 | + WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2 |
| 95 | + WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3 |
| 96 | + WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4 |
| 97 | + WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5 |
| 98 | + END) AS most_common_elem_freqs, |
| 99 | + (CASE |
| 100 | + WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1 |
| 101 | + WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2 |
| 102 | + WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3 |
| 103 | + WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4 |
| 104 | + WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5 |
| 105 | + END) AS elem_count_histogram |
| 106 | + FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid) |
| 107 | + LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid) |
| 108 | + LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace) |
| 109 | + LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace) |
| 110 | + JOIN LATERAL ( |
| 111 | + SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr, |
| 112 | + unnest(sd.stxdexpr)::pg_statistic AS a |
| 113 | + ) stat ON (stat.expr IS NOT NULL) |
| 114 | + WHERE pg_has_role(c.relowner, 'USAGE') |
| 115 | + AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); |
0 commit comments