@@ -97,7 +97,7 @@ static bool contain_mutable_functions_walker(Node *node, void *context);
97
97
static bool contain_volatile_functions_walker (Node * node , void * context );
98
98
static bool contain_volatile_functions_not_nextval_walker (Node * node , void * context );
99
99
static bool contain_nonstrict_functions_walker (Node * node , void * context );
100
- static bool contain_leaky_functions_walker (Node * node , void * context );
100
+ static bool contain_leaked_vars_walker (Node * node , void * context );
101
101
static Relids find_nonnullable_rels_walker (Node * node , bool top_level );
102
102
static List * find_nonnullable_vars_walker (Node * node , bool top_level );
103
103
static bool is_strict_saop (ScalarArrayOpExpr * expr , bool falseOK );
@@ -1318,26 +1318,30 @@ contain_nonstrict_functions_walker(Node *node, void *context)
1318
1318
}
1319
1319
1320
1320
/*****************************************************************************
1321
- * Check clauses for non-leakproof functions
1321
+ * Check clauses for Vars passed to non-leakproof functions
1322
1322
*****************************************************************************/
1323
1323
1324
1324
/*
1325
- * contain_leaky_functions
1326
- * Recursively search for leaky functions within a clause.
1325
+ * contain_leaked_vars
1326
+ * Recursively scan a clause to discover whether it contains any Var
1327
+ * nodes (of the current query level) that are passed as arguments to
1328
+ * leaky functions.
1327
1329
*
1328
- * Returns true if any function call with side-effect may be present in the
1329
- * clause. Qualifiers from outside the a security_barrier view should not
1330
- * be pushed down into the view, lest the contents of tuples intended to be
1331
- * filtered out be revealed via side effects.
1330
+ * Returns true if the clause contains any non-leakproof functions that are
1331
+ * passed Var nodes of the current query level, and which might therefore leak
1332
+ * data. Qualifiers from outside a security_barrier view that might leak data
1333
+ * in this way should not be pushed down into the view in case the contents of
1334
+ * tuples intended to be filtered out by the view are revealed by the leaky
1335
+ * functions.
1332
1336
*/
1333
1337
bool
1334
- contain_leaky_functions (Node * clause )
1338
+ contain_leaked_vars (Node * clause )
1335
1339
{
1336
- return contain_leaky_functions_walker (clause , NULL );
1340
+ return contain_leaked_vars_walker (clause , NULL );
1337
1341
}
1338
1342
1339
1343
static bool
1340
- contain_leaky_functions_walker (Node * node , void * context )
1344
+ contain_leaked_vars_walker (Node * node , void * context )
1341
1345
{
1342
1346
if (node == NULL )
1343
1347
return false;
@@ -1369,7 +1373,8 @@ contain_leaky_functions_walker(Node *node, void *context)
1369
1373
{
1370
1374
FuncExpr * expr = (FuncExpr * ) node ;
1371
1375
1372
- if (!get_func_leakproof (expr -> funcid ))
1376
+ if (!get_func_leakproof (expr -> funcid ) &&
1377
+ contain_var_clause ((Node * ) expr -> args ))
1373
1378
return true;
1374
1379
}
1375
1380
break ;
@@ -1381,7 +1386,8 @@ contain_leaky_functions_walker(Node *node, void *context)
1381
1386
OpExpr * expr = (OpExpr * ) node ;
1382
1387
1383
1388
set_opfuncid (expr );
1384
- if (!get_func_leakproof (expr -> opfuncid ))
1389
+ if (!get_func_leakproof (expr -> opfuncid ) &&
1390
+ contain_var_clause ((Node * ) expr -> args ))
1385
1391
return true;
1386
1392
}
1387
1393
break ;
@@ -1391,7 +1397,8 @@ contain_leaky_functions_walker(Node *node, void *context)
1391
1397
ScalarArrayOpExpr * expr = (ScalarArrayOpExpr * ) node ;
1392
1398
1393
1399
set_sa_opfuncid (expr );
1394
- if (!get_func_leakproof (expr -> opfuncid ))
1400
+ if (!get_func_leakproof (expr -> opfuncid ) &&
1401
+ contain_var_clause ((Node * ) expr -> args ))
1395
1402
return true;
1396
1403
}
1397
1404
break ;
@@ -1401,15 +1408,29 @@ contain_leaky_functions_walker(Node *node, void *context)
1401
1408
CoerceViaIO * expr = (CoerceViaIO * ) node ;
1402
1409
Oid funcid ;
1403
1410
Oid ioparam ;
1411
+ bool leakproof ;
1404
1412
bool varlena ;
1405
1413
1414
+ /*
1415
+ * Data may be leaked if either the input or the output
1416
+ * function is leaky.
1417
+ */
1406
1418
getTypeInputInfo (exprType ((Node * ) expr -> arg ),
1407
1419
& funcid , & ioparam );
1408
- if (!get_func_leakproof (funcid ))
1409
- return true;
1420
+ leakproof = get_func_leakproof (funcid );
1421
+
1422
+ /*
1423
+ * If the input function is leakproof, then check the output
1424
+ * function.
1425
+ */
1426
+ if (leakproof )
1427
+ {
1428
+ getTypeOutputInfo (expr -> resulttype , & funcid , & varlena );
1429
+ leakproof = get_func_leakproof (funcid );
1430
+ }
1410
1431
1411
- getTypeOutputInfo ( expr -> resulttype , & funcid , & varlena );
1412
- if (! get_func_leakproof ( funcid ))
1432
+ if (! leakproof &&
1433
+ contain_var_clause (( Node * ) expr -> arg ))
1413
1434
return true;
1414
1435
}
1415
1436
break ;
@@ -1419,14 +1440,29 @@ contain_leaky_functions_walker(Node *node, void *context)
1419
1440
ArrayCoerceExpr * expr = (ArrayCoerceExpr * ) node ;
1420
1441
Oid funcid ;
1421
1442
Oid ioparam ;
1443
+ bool leakproof ;
1422
1444
bool varlena ;
1423
1445
1446
+ /*
1447
+ * Data may be leaked if either the input or the output
1448
+ * function is leaky.
1449
+ */
1424
1450
getTypeInputInfo (exprType ((Node * ) expr -> arg ),
1425
1451
& funcid , & ioparam );
1426
- if (!get_func_leakproof (funcid ))
1427
- return true;
1428
- getTypeOutputInfo (expr -> resulttype , & funcid , & varlena );
1429
- if (!get_func_leakproof (funcid ))
1452
+ leakproof = get_func_leakproof (funcid );
1453
+
1454
+ /*
1455
+ * If the input function is leakproof, then check the output
1456
+ * function.
1457
+ */
1458
+ if (leakproof )
1459
+ {
1460
+ getTypeOutputInfo (expr -> resulttype , & funcid , & varlena );
1461
+ leakproof = get_func_leakproof (funcid );
1462
+ }
1463
+
1464
+ if (!leakproof &&
1465
+ contain_var_clause ((Node * ) expr -> arg ))
1430
1466
return true;
1431
1467
}
1432
1468
break ;
@@ -1435,12 +1471,22 @@ contain_leaky_functions_walker(Node *node, void *context)
1435
1471
{
1436
1472
RowCompareExpr * rcexpr = (RowCompareExpr * ) node ;
1437
1473
ListCell * opid ;
1474
+ ListCell * larg ;
1475
+ ListCell * rarg ;
1438
1476
1439
- foreach (opid , rcexpr -> opnos )
1477
+ /*
1478
+ * Check the comparison function and arguments passed to it for
1479
+ * each pair of row elements.
1480
+ */
1481
+ forthree (opid , rcexpr -> opnos ,
1482
+ larg , rcexpr -> largs ,
1483
+ rarg , rcexpr -> rargs )
1440
1484
{
1441
1485
Oid funcid = get_opcode (lfirst_oid (opid ));
1442
1486
1443
- if (!get_func_leakproof (funcid ))
1487
+ if (!get_func_leakproof (funcid ) &&
1488
+ (contain_var_clause ((Node * ) lfirst (larg )) ||
1489
+ contain_var_clause ((Node * ) lfirst (rarg ))))
1444
1490
return true;
1445
1491
}
1446
1492
}
@@ -1455,7 +1501,7 @@ contain_leaky_functions_walker(Node *node, void *context)
1455
1501
*/
1456
1502
return true;
1457
1503
}
1458
- return expression_tree_walker (node , contain_leaky_functions_walker ,
1504
+ return expression_tree_walker (node , contain_leaked_vars_walker ,
1459
1505
context );
1460
1506
}
1461
1507
0 commit comments