comparison src/iflow.sml @ 1220:526575a9537a

Insert policies
author Adam Chlipala <adamc@hcoop.net>
date Sun, 11 Apr 2010 10:57:52 -0400
parents 3224faec752d
children 00e628854005
comparison
equal deleted inserted replaced
1219:3224faec752d 1220:526575a9537a
882 [("a", p_atom a), 882 [("a", p_atom a),
883 ("hyps", Print.p_list p_atom hyps), 883 ("hyps", Print.p_list p_atom hyps),
884 ("db", Cc.p_database cc)];*) 884 ("db", Cc.p_database cc)];*)
885 false)) acc 885 false)) acc
886 (*andalso (Print.preface ("Finding", Cc.p_database cc); true)*) 886 (*andalso (Print.preface ("Finding", Cc.p_database cc); true)*)
887 andalso Cc.builtFrom (cc, {Derived = Var 0, 887 andalso (case outs of
888 Base = outs})) 888 NONE => true
889 | SOME outs => Cc.builtFrom (cc, {Derived = Var 0,
890 Base = outs})))
889 handle Cc.Contradiction => false 891 handle Cc.Contradiction => false
890 end handle Cc.Undetermined => false) 892 end handle Cc.Undetermined => false)
891 orelse onFail () 893 orelse onFail ()
892 | (g as AReln (Sql gf, [ge])) :: goals => 894 | (g as AReln (Sql gf, [ge])) :: goals =>
893 let 895 let
1216 1218
1217 val query = log "query" 1219 val query = log "query"
1218 (wrap (follow (follow select from) (opt wher)) 1220 (wrap (follow (follow select from) (opt wher))
1219 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher})) 1221 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher}))
1220 1222
1223 datatype dml =
1224 Insert of string * (string * sqexp) list
1225
1226 val insert = log "insert"
1227 (wrapP (follow (const "INSERT INTO ")
1228 (follow uw_ident
1229 (follow (const " (")
1230 (follow (list uw_ident)
1231 (follow (const ") VALUES (")
1232 (follow (list sqexp)
1233 (const ")")))))))
1234 (fn ((), (tab, ((), (fs, ((), (es, ())))))) =>
1235 (SOME (Insert (tab, ListPair.zipEq (fs, es))))
1236 handle ListPair.UnequalLengths => NONE))
1237
1238 val dml = log "dml"
1239 insert
1240
1221 fun removeDups (ls : (string * string) list) = 1241 fun removeDups (ls : (string * string) list) =
1222 case ls of 1242 case ls of
1223 [] => [] 1243 [] => []
1224 | x :: ls => 1244 | x :: ls =>
1225 let 1245 let
1233 1253
1234 datatype queryMode = 1254 datatype queryMode =
1235 SomeCol 1255 SomeCol
1236 | AllCols of exp 1256 | AllCols of exp
1237 1257
1238 exception Default 1258 fun expIn rv env rvOf =
1259 let
1260 fun expIn (e, rvN) =
1261 let
1262 fun default () =
1263 let
1264 val (rvN, e) = rv rvN
1265 in
1266 (inl e, rvN)
1267 end
1268 in
1269 case e of
1270 SqConst p => (inl (Const p), rvN)
1271 | Field (v, f) => (inl (Proj (rvOf v, f)), rvN)
1272 | Binop (bo, e1, e2) =>
1273 let
1274 val (e1, rvN) = expIn (e1, rvN)
1275 val (e2, rvN) = expIn (e2, rvN)
1276 in
1277 (inr (case (bo, e1, e2) of
1278 (Exps f, inl e1, inl e2) => f (e1, e2)
1279 | (Props f, inr p1, inr p2) => f (p1, p2)
1280 | _ => Unknown), rvN)
1281 end
1282 | SqKnown e =>
1283 (case expIn (e, rvN) of
1284 (inl e, rvN) => (inr (Reln (Known, [e])), rvN)
1285 | _ => (inr Unknown, rvN))
1286 | Inj e =>
1287 let
1288 fun deinj e =
1289 case #1 e of
1290 ERel n => (List.nth (env, n), rvN)
1291 | EField (e, f) =>
1292 let
1293 val (e, rvN) = deinj e
1294 in
1295 (Proj (e, f), rvN)
1296 end
1297 | _ =>
1298 let
1299 val (rvN, e) = rv rvN
1300 in
1301 (e, rvN)
1302 end
1303
1304 val (e, rvN) = deinj e
1305 in
1306 (inl e, rvN)
1307 end
1308 | SqFunc (f, e) =>
1309 (case expIn (e, rvN) of
1310 (inl e, rvN) => (inl (Func (Other f, [e])), rvN)
1311 | _ => default ())
1312
1313 | Count => default ()
1314 end
1315 in
1316 expIn
1317 end
1239 1318
1240 fun queryProp env rvN rv oe e = 1319 fun queryProp env rvN rv oe e =
1241 let 1320 let
1242 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " 1321 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1243 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1322 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1270 | Count => [] 1349 | Count => []
1271 1350
1272 val p = 1351 val p =
1273 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r) 1352 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r)
1274 1353
1275 fun expIn e = 1354 val expIn = expIn rv env rvOf
1276 case e of 1355
1277 SqConst p => inl (Const p) 1356 val (p, rvN) = case #Where r of
1278 | Field (v, f) => inl (Proj (rvOf v, f)) 1357 NONE => (p, rvN)
1279 | Binop (bo, e1, e2) => 1358 | SOME e =>
1280 inr (case (bo, expIn e1, expIn e2) of 1359 case expIn (e, rvN) of
1281 (Exps f, inl e1, inl e2) => f (e1, e2) 1360 (inr p', rvN) => (And (p, p'), rvN)
1282 | (Props f, inr p1, inr p2) => f (p1, p2) 1361 | _ => (p, rvN)
1283 | _ => Unknown)
1284 | SqKnown e =>
1285 inr (case expIn e of
1286 inl e => Reln (Known, [e])
1287 | _ => Unknown)
1288 | Inj e =>
1289 let
1290 fun deinj (e, _) =
1291 case e of
1292 ERel n => List.nth (env, n)
1293 | EField (e, f) => Proj (deinj e, f)
1294 | _ => raise Fail "Iflow: non-variable injected into query"
1295 in
1296 inl (deinj e)
1297 end
1298 | SqFunc (f, e) =>
1299 inl (case expIn e of
1300 inl e => Func (Other f, [e])
1301 | _ => raise Fail ("Iflow: non-expresion passed to function " ^ f))
1302 | Count => raise Default
1303
1304 val p = case #Where r of
1305 NONE => p
1306 | SOME e =>
1307 case expIn e of
1308 inr p' => And (p, p')
1309 | _ => p
1310 1362
1311 fun normal () = 1363 fun normal () =
1312 case oe of 1364 case oe of
1313 SomeCol => 1365 SomeCol =>
1314 (rvN, p, True, 1366 let
1315 List.mapPartial (fn si => 1367 val (sis, rvN) =
1316 case si of 1368 ListUtil.foldlMap
1317 SqField (v, f) => SOME (Proj (rvOf v, f)) 1369 (fn (si, rvN) =>
1318 | SqExp (e, f) => 1370 case si of
1319 case expIn e of 1371 SqField (v, f) => (Proj (rvOf v, f), rvN)
1320 inr _ => NONE 1372 | SqExp (e, f) =>
1321 | inl e => SOME e) (#Select r)) 1373 case expIn (e, rvN) of
1374 (inr _, _) =>
1375 let
1376 val (rvN, e) = rv rvN
1377 in
1378 (e, rvN)
1379 end
1380 | (inl e, rvN) => (e, rvN)) rvN (#Select r)
1381 in
1382 (rvN, p, True, sis)
1383 end
1322 | AllCols oe => 1384 | AllCols oe =>
1323 (rvN, And (p, foldl (fn (si, p) => 1385 let
1324 let 1386 val (p', rvN) =
1325 val p' = case si of 1387 foldl (fn (si, (p, rvN)) =>
1326 SqField (v, f) => Reln (Eq, [Proj (Proj (oe, v), f), 1388 let
1327 Proj (rvOf v, f)]) 1389 val (p', rvN) =
1328 | SqExp (e, f) => 1390 case si of
1329 case expIn e of 1391 SqField (v, f) => (Reln (Eq, [Proj (Proj (oe, v), f),
1330 inr p => Cond (Proj (oe, f), p) 1392 Proj (rvOf v, f)]), rvN)
1331 | inl e => Reln (Eq, [Proj (oe, f), e]) 1393 | SqExp (e, f) =>
1332 in 1394 case expIn (e, rvN) of
1333 And (p, p') 1395 (inr p, rvN) => (Cond (Proj (oe, f), p), rvN)
1334 end) 1396 | (inl e, rvN) => (Reln (Eq, [Proj (oe, f), e]), rvN)
1335 True (#Select r)), 1397 in
1336 True, []) 1398 (And (p, p'), rvN)
1399 end)
1400 (True, rvN) (#Select r)
1401 in
1402 (rvN, And (p, p'), True, [])
1403 end
1337 1404
1338 val (rvN, p, wp, outs) = 1405 val (rvN, p, wp, outs) =
1339 case #Select r of 1406 case #Select r of
1340 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] => 1407 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] =>
1341 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of 1408 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of
1368 in 1435 in
1369 (rvN, p, wp, case #Where r of 1436 (rvN, p, wp, case #Where r of
1370 NONE => [] 1437 NONE => []
1371 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e), outs) 1438 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e), outs)
1372 end 1439 end
1373 handle Default => default () 1440 end
1441
1442 fun insertProp rvN rv e =
1443 let
1444 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1445 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1446 Unknown)
1447 in
1448 case parse query e of
1449 NONE => default ()
1450 | SOME r =>
1451 let
1452 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1453 let
1454 val (rvN, e) = rv rvN
1455 in
1456 ((v, e), rvN)
1457 end) rvN (#From r)
1458
1459 fun rvOf v =
1460 case List.find (fn (v', _) => v' = v) rvs of
1461 NONE => raise Fail "Iflow.insertProp: Bad table variable"
1462 | SOME (_, e) => e
1463
1464 val p =
1465 foldl (fn ((t, v), p) =>
1466 let
1467 val t =
1468 case v of
1469 "New" => "$New"
1470 | _ => t
1471 in
1472 And (p, Reln (Sql t, [rvOf v]))
1473 end) True (#From r)
1474
1475 val expIn = expIn rv [] rvOf
1476 in
1477 case #Where r of
1478 NONE => p
1479 | SOME e =>
1480 case expIn (e, rvN) of
1481 (inr p', _) => And (p, p')
1482 | _ => p
1483 end
1374 end 1484 end
1375 1485
1376 fun evalPat env e (pt, _) = 1486 fun evalPat env e (pt, _) =
1377 case pt of 1487 case pt of
1378 PWild => (env, True) 1488 PWild => (env, True)
1426 end 1536 end
1427 1537
1428 datatype cflow = Case | Where 1538 datatype cflow = Case | Where
1429 datatype flow = Data | Control of cflow 1539 datatype flow = Data | Control of cflow
1430 type check = ErrorMsg.span * exp * prop 1540 type check = ErrorMsg.span * exp * prop
1541 type insert = ErrorMsg.span * prop
1431 1542
1432 structure St :> sig 1543 structure St :> sig
1433 type t 1544 type t
1434 val create : {Var : int, 1545 val create : {Var : int,
1435 Ambient : prop} -> t 1546 Ambient : prop} -> t
1447 val setPaths : t * (check * cflow) list -> t 1558 val setPaths : t * (check * cflow) list -> t
1448 1559
1449 val sent : t -> (check * flow) list 1560 val sent : t -> (check * flow) list
1450 val addSent : t * (check * flow) -> t 1561 val addSent : t * (check * flow) -> t
1451 val setSent : t * (check * flow) list -> t 1562 val setSent : t * (check * flow) list -> t
1563
1564 val inserted : t -> insert list
1565 val addInsert : t * insert -> t
1452 end = struct 1566 end = struct
1453 1567
1454 type t = {Var : int, 1568 type t = {Var : int,
1455 Ambient : prop, 1569 Ambient : prop,
1456 Path : (check * cflow) list, 1570 Path : (check * cflow) list,
1457 Sent : (check * flow) list} 1571 Sent : (check * flow) list,
1572 Insert : insert list}
1458 1573
1459 fun create {Var = v, Ambient = p} = {Var = v, 1574 fun create {Var = v, Ambient = p} = {Var = v,
1460 Ambient = p, 1575 Ambient = p,
1461 Path = [], 1576 Path = [],
1462 Sent = []} 1577 Sent = [],
1578 Insert = []}
1463 1579
1464 fun curVar (t : t) = #Var t 1580 fun curVar (t : t) = #Var t
1465 fun nextVar (t : t) = ({Var = #Var t + 1, 1581 fun nextVar (t : t) = ({Var = #Var t + 1,
1466 Ambient = #Ambient t, 1582 Ambient = #Ambient t,
1467 Path = #Path t, 1583 Path = #Path t,
1468 Sent = #Sent t}, #Var t) 1584 Sent = #Sent t,
1585 Insert = #Insert t}, #Var t)
1469 1586
1470 fun ambient (t : t) = #Ambient t 1587 fun ambient (t : t) = #Ambient t
1471 fun setAmbient (t : t, p) = {Var = #Var t, 1588 fun setAmbient (t : t, p) = {Var = #Var t,
1472 Ambient = p, 1589 Ambient = p,
1473 Path = #Path t, 1590 Path = #Path t,
1474 Sent = #Sent t} 1591 Sent = #Sent t,
1592 Insert = #Insert t}
1475 1593
1476 fun paths (t : t) = #Path t 1594 fun paths (t : t) = #Path t
1477 fun addPath (t : t, c) = {Var = #Var t, 1595 fun addPath (t : t, c) = {Var = #Var t,
1478 Ambient = #Ambient t, 1596 Ambient = #Ambient t,
1479 Path = c :: #Path t, 1597 Path = c :: #Path t,
1480 Sent = #Sent t} 1598 Sent = #Sent t,
1599 Insert = #Insert t}
1481 fun addPaths (t : t, cs) = {Var = #Var t, 1600 fun addPaths (t : t, cs) = {Var = #Var t,
1482 Ambient = #Ambient t, 1601 Ambient = #Ambient t,
1483 Path = cs @ #Path t, 1602 Path = cs @ #Path t,
1484 Sent = #Sent t} 1603 Sent = #Sent t,
1604 Insert = #Insert t}
1485 fun clearPaths (t : t) = {Var = #Var t, 1605 fun clearPaths (t : t) = {Var = #Var t,
1486 Ambient = #Ambient t, 1606 Ambient = #Ambient t,
1487 Path = [], 1607 Path = [],
1488 Sent = #Sent t} 1608 Sent = #Sent t,
1609 Insert = #Insert t}
1489 fun setPaths (t : t, cs) = {Var = #Var t, 1610 fun setPaths (t : t, cs) = {Var = #Var t,
1490 Ambient = #Ambient t, 1611 Ambient = #Ambient t,
1491 Path = cs, 1612 Path = cs,
1492 Sent = #Sent t} 1613 Sent = #Sent t,
1614 Insert = #Insert t}
1493 1615
1494 fun sent (t : t) = #Sent t 1616 fun sent (t : t) = #Sent t
1495 fun addSent (t : t, c) = {Var = #Var t, 1617 fun addSent (t : t, c) = {Var = #Var t,
1496 Ambient = #Ambient t, 1618 Ambient = #Ambient t,
1497 Path = #Path t, 1619 Path = #Path t,
1498 Sent = c :: #Sent t} 1620 Sent = c :: #Sent t,
1621 Insert = #Insert t}
1499 fun setSent (t : t, cs) = {Var = #Var t, 1622 fun setSent (t : t, cs) = {Var = #Var t,
1500 Ambient = #Ambient t, 1623 Ambient = #Ambient t,
1501 Path = #Path t, 1624 Path = #Path t,
1502 Sent = cs} 1625 Sent = cs,
1626 Insert = #Insert t}
1627
1628 fun inserted (t : t) = #Insert t
1629 fun addInsert (t : t, c) = {Var = #Var t,
1630 Ambient = #Ambient t,
1631 Path = #Path t,
1632 Sent = #Sent t,
1633 Insert = c :: #Insert t}
1503 1634
1504 end 1635 end
1505 1636
1506 fun evalExp env (e as (_, loc), st) = 1637 fun evalExp env (e as (_, loc), st) =
1507 let 1638 let
1718 val p' = And (p', qwp) 1849 val p' = And (p', qwp)
1719 val paths = map (fn e => ((loc, e, p'), Where)) used 1850 val paths = map (fn e => ((loc, e, p'), Where)) used
1720 in 1851 in
1721 (res, St.addPaths (St.setSent (st, sent), paths)) 1852 (res, St.addPaths (St.setSent (st, sent), paths))
1722 end 1853 end
1723 | EDml _ => default () 1854 | EDml e =>
1855 (case parse dml e of
1856 NONE => (print ("Warning: Information flow checker can't parse DML command at "
1857 ^ ErrorMsg.spanToString loc ^ "\n");
1858 default ())
1859 | SOME d =>
1860 case d of
1861 Insert (tab, es) =>
1862 let
1863 val (st, new) = St.nextVar st
1864
1865 fun rv st =
1866 let
1867 val (st, n) = St.nextVar st
1868 in
1869 (st, Var n)
1870 end
1871
1872 val expIn = expIn rv env (fn "New" => Var new
1873 | _ => raise Fail "Iflow.evalExp: Bad field expression in EDml")
1874
1875 val (es, st) = ListUtil.foldlMap
1876 (fn ((x, e), st) =>
1877 let
1878 val (e, st) = case expIn (e, st) of
1879 (inl e, st) => (e, st)
1880 | (inr _, _) => raise Fail
1881 ("Iflow.evalExp: Selecting "
1882 ^ "boolean expression")
1883 in
1884 ((x, e), st)
1885 end)
1886 st es
1887 in
1888 (Recd [], St.addInsert (st, (loc, And (St.ambient st,
1889 Reln (Sql "$New", [Recd es])))))
1890 end)
1891
1724 | ENextval _ => default () 1892 | ENextval _ => default ()
1725 | ESetval _ => default () 1893 | ESetval _ => default ()
1726 1894
1727 | EUnurlify ((EFfiApp ("Basis", "get_cookie", _), _), _, _) => 1895 | EUnurlify ((EFfiApp ("Basis", "get_cookie", _), _), _, _) =>
1728 let 1896 let
1754 val exptd = foldl (fn ((d, _), exptd) => 1922 val exptd = foldl (fn ((d, _), exptd) =>
1755 case d of 1923 case d of
1756 DExport (_, _, n, _, _, _) => IS.add (exptd, n) 1924 DExport (_, _, n, _, _, _) => IS.add (exptd, n)
1757 | _ => exptd) IS.empty file 1925 | _ => exptd) IS.empty file
1758 1926
1759 fun decl ((d, _), (vals, pols)) = 1927 fun decl ((d, _), (vals, inserts, client, insert)) =
1760 case d of 1928 case d of
1761 DVal (_, n, _, e, _) => 1929 DVal (_, n, _, e, _) =>
1762 let 1930 let
1763 val isExptd = IS.member (exptd, n) 1931 val isExptd = IS.member (exptd, n)
1764 1932
1774 val (e, env, nv, p) = deAbs (e, [], 1, True) 1942 val (e, env, nv, p) = deAbs (e, [], 1, True)
1775 1943
1776 val (_, st) = evalExp env (e, St.create {Var = nv, 1944 val (_, st) = evalExp env (e, St.create {Var = nv,
1777 Ambient = p}) 1945 Ambient = p})
1778 in 1946 in
1779 (St.sent st @ vals, pols) 1947 (St.sent st @ vals, St.inserted st @ inserts, client, insert)
1780 end 1948 end
1781 1949
1782 | DPolicy (PolClient e) => 1950 | DPolicy pol =>
1783 let 1951 let
1784 val (_, p, _, _, outs) = queryProp [] 0 (fn rvN => (rvN + 1, Lvar rvN)) SomeCol e 1952 fun rv rvN = (rvN + 1, Lvar rvN)
1785 in 1953 in
1786 (vals, (p, outs) :: pols) 1954 case pol of
1955 PolClient e =>
1956 let
1957 val (_, p, _, _, outs) = queryProp [] 0 rv SomeCol e
1958 in
1959 (vals, inserts, (p, outs) :: client, insert)
1960 end
1961 | PolInsert e =>
1962 let
1963 val p = insertProp 0 rv e
1964 in
1965 (vals, inserts,client, p :: insert)
1966 end
1787 end 1967 end
1788 1968
1789 | _ => (vals, pols) 1969 | _ => (vals, inserts, client, insert)
1790 1970
1791 val () = reset () 1971 val () = reset ()
1792 1972
1793 val (vals, pols) = foldl decl ([], []) file 1973 val (vals, inserts, client, insert) = foldl decl ([], [], [], []) file
1974
1975 val decompH = decomp true (fn (e1, e2) => e1 andalso e2 ())
1976 val decompG = decomp false (fn (e1, e2) => e1 orelse e2 ())
1794 in 1977 in
1795 app (fn ((loc, e, p), fl) => 1978 app (fn ((loc, e, p), fl) =>
1796 let 1979 let
1797 fun doOne e = 1980 fun doOne e =
1798 let 1981 let
1799 val p = And (p, Reln (Eq, [Var 0, e])) 1982 val p = And (p, Reln (Eq, [Var 0, e]))
1800 in 1983 in
1801 if decomp true (fn (e1, e2) => e1 andalso e2 ()) p 1984 if decompH p
1802 (fn hyps => 1985 (fn hyps =>
1803 (fl <> Control Where 1986 (fl <> Control Where
1804 andalso imply (hyps, [AReln (Known, [Var 0])], [Var 0])) 1987 andalso imply (hyps, [AReln (Known, [Var 0])], SOME [Var 0]))
1805 orelse List.exists (fn (p', outs) => 1988 orelse List.exists (fn (p', outs) =>
1806 decomp false (fn (e1, e2) => e1 orelse e2 ()) p' 1989 decompG p'
1807 (fn goals => imply (hyps, goals, outs))) 1990 (fn goals => imply (hyps, goals, SOME outs)))
1808 pols) then 1991 client) then
1809 () 1992 ()
1810 else 1993 else
1811 (ErrorMsg.errorAt loc "The information flow policy may be violated here."; 1994 (ErrorMsg.errorAt loc "The information flow policy may be violated here.";
1812 Print.preface ("The state satisifies this predicate:", p_prop p)) 1995 Print.preface ("The state satisifies this predicate:", p_prop p))
1813 end 1996 end
1822 | Recd xes => app (doAll o #2) xes 2005 | Recd xes => app (doAll o #2) xes
1823 | Proj _ => doOne e 2006 | Proj _ => doOne e
1824 | Finish => () 2007 | Finish => ()
1825 in 2008 in
1826 doAll e 2009 doAll e
1827 end) vals 2010 end) vals;
2011
2012 app (fn (loc, p) =>
2013 if decompH p
2014 (fn hyps =>
2015 List.exists (fn p' =>
2016 decompG p'
2017 (fn goals => imply (hyps, goals, NONE)))
2018 insert) then
2019 ()
2020 else
2021 (ErrorMsg.errorAt loc "The information flow policy may be violated here.";
2022 Print.preface ("The state satisifies this predicate:", p_prop p))) inserts
1828 end 2023 end
1829 2024
1830 val check = fn file => 2025 val check = fn file =>
1831 let 2026 let
1832 val oldInline = Settings.getMonoInline () 2027 val oldInline = Settings.getMonoInline ()