comparison src/iflow.sml @ 1223:62af4cacd191

Update policies
author Adam Chlipala <adamc@hcoop.net>
date Sun, 11 Apr 2010 13:11:25 -0400
parents 117f13bdc1fd
children 3950cf1f5736
comparison
equal deleted inserted replaced
1222:117f13bdc1fd 1223:62af4cacd191
956 end 956 end
957 | g :: goals => gls goals onFail (g :: acc) 957 | g :: goals => gls goals onFail (g :: acc)
958 in 958 in
959 reset (); 959 reset ();
960 (*Print.prefaces "Big go" [("hyps", Print.p_list p_atom hyps), 960 (*Print.prefaces "Big go" [("hyps", Print.p_list p_atom hyps),
961 ("goals", Print.p_list p_atom goals)];*) 961 ("goals", Print.p_list p_atom goals)];*)
962 gls goals (fn () => false) [] 962 gls goals (fn () => false) []
963 end handle Cc.Contradiction => true 963 end handle Cc.Contradiction => true
964 964
965 fun patCon pc = 965 fun patCon pc =
966 case pc of 966 case pc of
1255 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher})) 1255 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher}))
1256 1256
1257 datatype dml = 1257 datatype dml =
1258 Insert of string * (string * sqexp) list 1258 Insert of string * (string * sqexp) list
1259 | Delete of string * sqexp 1259 | Delete of string * sqexp
1260 | Update of string * (string * sqexp) list * sqexp
1260 1261
1261 val insert = log "insert" 1262 val insert = log "insert"
1262 (wrapP (follow (const "INSERT INTO ") 1263 (wrapP (follow (const "INSERT INTO ")
1263 (follow uw_ident 1264 (follow uw_ident
1264 (follow (const " (") 1265 (follow (const " (")
1275 (follow uw_ident 1276 (follow uw_ident
1276 (follow (const " AS T_T WHERE ") 1277 (follow (const " AS T_T WHERE ")
1277 sqexp))) 1278 sqexp)))
1278 (fn ((), (tab, ((), es))) => (tab, es))) 1279 (fn ((), (tab, ((), es))) => (tab, es)))
1279 1280
1281 val setting = log "setting"
1282 (wrap (follow uw_ident (follow (const " = ") sqexp))
1283 (fn (f, ((), e)) => (f, e)))
1284
1285 val update = log "update"
1286 (wrap (follow (const "UPDATE ")
1287 (follow uw_ident
1288 (follow (const " AS T_T SET ")
1289 (follow (list setting)
1290 (follow (ws (const "WHERE "))
1291 sqexp)))))
1292 (fn ((), (tab, ((), (fs, ((), e))))) =>
1293 (tab, fs, e)))
1294
1280 val dml = log "dml" 1295 val dml = log "dml"
1281 (altL [wrap insert Insert, 1296 (altL [wrap insert Insert,
1282 wrap delete Delete]) 1297 wrap delete Delete,
1298 wrap update Update])
1283 1299
1284 fun removeDups (ls : (string * string) list) = 1300 fun removeDups (ls : (string * string) list) =
1285 case ls of 1301 case ls of
1286 [] => [] 1302 [] => []
1287 | x :: ls => 1303 | x :: ls =>
1574 (inr p', _) => And (p, p') 1590 (inr p', _) => And (p, p')
1575 | _ => p) 1591 | _ => p)
1576 end 1592 end
1577 end 1593 end
1578 1594
1595 fun updateProp rvN rv e =
1596 let
1597 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1598 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1599 Unknown)
1600 in
1601 case parse query e of
1602 NONE => default ()
1603 | SOME r =>
1604 let
1605 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1606 let
1607 val (rvN, e) = rv rvN
1608 in
1609 ((v, e), rvN)
1610 end) rvN (#From r)
1611
1612 fun rvOf v =
1613 case List.find (fn (v', _) => v' = v) rvs of
1614 NONE => raise Fail "Iflow.insertProp: Bad table variable"
1615 | SOME (_, e) => e
1616
1617 val p =
1618 foldl (fn ((t, v), p) =>
1619 let
1620 val t =
1621 case v of
1622 "New" => "$New"
1623 | _ => t
1624 in
1625 And (p, Reln (Sql t, [rvOf v]))
1626 end) True (#From r)
1627
1628 val expIn = expIn rv [] rvOf
1629 in
1630 And (Reln (Sql "$Old", [rvOf "Old"]),
1631 case #Where r of
1632 NONE => p
1633 | SOME e =>
1634 case expIn (e, rvN) of
1635 (inr p', _) => And (p, p')
1636 | _ => p)
1637 end
1638 end
1639
1579 fun evalPat env e (pt, _) = 1640 fun evalPat env e (pt, _) =
1580 case pt of 1641 case pt of
1581 PWild => (env, True) 1642 PWild => (env, True)
1582 | PVar _ => (e :: env, True) 1643 | PVar _ => (e :: env, True)
1583 | PPrim _ => (env, True) 1644 | PPrim _ => (env, True)
1657 val inserted : t -> dml list 1718 val inserted : t -> dml list
1658 val addInsert : t * dml -> t 1719 val addInsert : t * dml -> t
1659 1720
1660 val deleted : t -> dml list 1721 val deleted : t -> dml list
1661 val addDelete : t * dml -> t 1722 val addDelete : t * dml -> t
1723
1724 val updated : t -> dml list
1725 val addUpdate : t * dml -> t
1662 end = struct 1726 end = struct
1663 1727
1664 type t = {Var : int, 1728 type t = {Var : int,
1665 Ambient : prop, 1729 Ambient : prop,
1666 Path : (check * cflow) list, 1730 Path : (check * cflow) list,
1667 Sent : (check * flow) list, 1731 Sent : (check * flow) list,
1668 Insert : dml list, 1732 Insert : dml list,
1669 Delete : dml list} 1733 Delete : dml list,
1734 Update : dml list}
1670 1735
1671 fun create {Var = v, Ambient = p} = {Var = v, 1736 fun create {Var = v, Ambient = p} = {Var = v,
1672 Ambient = p, 1737 Ambient = p,
1673 Path = [], 1738 Path = [],
1674 Sent = [], 1739 Sent = [],
1675 Insert = [], 1740 Insert = [],
1676 Delete = []} 1741 Delete = [],
1742 Update = []}
1677 1743
1678 fun curVar (t : t) = #Var t 1744 fun curVar (t : t) = #Var t
1679 fun nextVar (t : t) = ({Var = #Var t + 1, 1745 fun nextVar (t : t) = ({Var = #Var t + 1,
1680 Ambient = #Ambient t, 1746 Ambient = #Ambient t,
1681 Path = #Path t, 1747 Path = #Path t,
1682 Sent = #Sent t, 1748 Sent = #Sent t,
1683 Insert = #Insert t, 1749 Insert = #Insert t,
1684 Delete = #Delete t}, #Var t) 1750 Delete = #Delete t,
1751 Update = #Update t}, #Var t)
1685 1752
1686 fun ambient (t : t) = #Ambient t 1753 fun ambient (t : t) = #Ambient t
1687 fun setAmbient (t : t, p) = {Var = #Var t, 1754 fun setAmbient (t : t, p) = {Var = #Var t,
1688 Ambient = p, 1755 Ambient = p,
1689 Path = #Path t, 1756 Path = #Path t,
1690 Sent = #Sent t, 1757 Sent = #Sent t,
1691 Insert = #Insert t, 1758 Insert = #Insert t,
1692 Delete = #Delete t} 1759 Delete = #Delete t,
1760 Update = #Update t}
1693 1761
1694 fun paths (t : t) = #Path t 1762 fun paths (t : t) = #Path t
1695 fun addPath (t : t, c) = {Var = #Var t, 1763 fun addPath (t : t, c) = {Var = #Var t,
1696 Ambient = #Ambient t, 1764 Ambient = #Ambient t,
1697 Path = c :: #Path t, 1765 Path = c :: #Path t,
1698 Sent = #Sent t, 1766 Sent = #Sent t,
1699 Insert = #Insert t, 1767 Insert = #Insert t,
1700 Delete = #Delete t} 1768 Delete = #Delete t,
1769 Update = #Update t}
1701 fun addPaths (t : t, cs) = {Var = #Var t, 1770 fun addPaths (t : t, cs) = {Var = #Var t,
1702 Ambient = #Ambient t, 1771 Ambient = #Ambient t,
1703 Path = cs @ #Path t, 1772 Path = cs @ #Path t,
1704 Sent = #Sent t, 1773 Sent = #Sent t,
1705 Insert = #Insert t, 1774 Insert = #Insert t,
1706 Delete = #Delete t} 1775 Delete = #Delete t,
1776 Update = #Update t}
1707 fun clearPaths (t : t) = {Var = #Var t, 1777 fun clearPaths (t : t) = {Var = #Var t,
1708 Ambient = #Ambient t, 1778 Ambient = #Ambient t,
1709 Path = [], 1779 Path = [],
1710 Sent = #Sent t, 1780 Sent = #Sent t,
1711 Insert = #Insert t, 1781 Insert = #Insert t,
1712 Delete = #Delete t} 1782 Delete = #Delete t,
1783 Update = #Update t}
1713 fun setPaths (t : t, cs) = {Var = #Var t, 1784 fun setPaths (t : t, cs) = {Var = #Var t,
1714 Ambient = #Ambient t, 1785 Ambient = #Ambient t,
1715 Path = cs, 1786 Path = cs,
1716 Sent = #Sent t, 1787 Sent = #Sent t,
1717 Insert = #Insert t, 1788 Insert = #Insert t,
1718 Delete = #Delete t} 1789 Delete = #Delete t,
1790 Update = #Update t}
1719 1791
1720 fun sent (t : t) = #Sent t 1792 fun sent (t : t) = #Sent t
1721 fun addSent (t : t, c) = {Var = #Var t, 1793 fun addSent (t : t, c) = {Var = #Var t,
1722 Ambient = #Ambient t, 1794 Ambient = #Ambient t,
1723 Path = #Path t, 1795 Path = #Path t,
1724 Sent = c :: #Sent t, 1796 Sent = c :: #Sent t,
1725 Insert = #Insert t, 1797 Insert = #Insert t,
1726 Delete = #Delete t} 1798 Delete = #Delete t,
1799 Update = #Update t}
1727 fun setSent (t : t, cs) = {Var = #Var t, 1800 fun setSent (t : t, cs) = {Var = #Var t,
1728 Ambient = #Ambient t, 1801 Ambient = #Ambient t,
1729 Path = #Path t, 1802 Path = #Path t,
1730 Sent = cs, 1803 Sent = cs,
1731 Insert = #Insert t, 1804 Insert = #Insert t,
1732 Delete = #Delete t} 1805 Delete = #Delete t,
1806 Update = #Update t}
1733 1807
1734 fun inserted (t : t) = #Insert t 1808 fun inserted (t : t) = #Insert t
1735 fun addInsert (t : t, c) = {Var = #Var t, 1809 fun addInsert (t : t, c) = {Var = #Var t,
1736 Ambient = #Ambient t, 1810 Ambient = #Ambient t,
1737 Path = #Path t, 1811 Path = #Path t,
1738 Sent = #Sent t, 1812 Sent = #Sent t,
1739 Insert = c :: #Insert t, 1813 Insert = c :: #Insert t,
1740 Delete = #Delete t} 1814 Delete = #Delete t,
1815 Update = #Update t}
1741 1816
1742 fun deleted (t : t) = #Delete t 1817 fun deleted (t : t) = #Delete t
1743 fun addDelete (t : t, c) = {Var = #Var t, 1818 fun addDelete (t : t, c) = {Var = #Var t,
1744 Ambient = #Ambient t, 1819 Ambient = #Ambient t,
1745 Path = #Path t, 1820 Path = #Path t,
1746 Sent = #Sent t, 1821 Sent = #Sent t,
1747 Insert = #Insert t, 1822 Insert = #Insert t,
1748 Delete = c :: #Delete t} 1823 Delete = c :: #Delete t,
1824 Update = #Update t}
1825
1826 fun updated (t : t) = #Update t
1827 fun addUpdate (t : t, c) = {Var = #Var t,
1828 Ambient = #Ambient t,
1829 Path = #Path t,
1830 Sent = #Sent t,
1831 Insert = #Insert t,
1832 Delete = #Delete t,
1833 Update = c :: #Update t}
1749 1834
1750 end 1835 end
1751 1836
1752 fun evalExp env (e as (_, loc), st) = 1837 fun evalExp env (e as (_, loc), st) =
1753 let 1838 let
1982 val (st, n) = St.nextVar st 2067 val (st, n) = St.nextVar st
1983 in 2068 in
1984 (st, Var n) 2069 (st, Var n)
1985 end 2070 end
1986 2071
1987 val expIn = expIn rv env (fn "New" => Var new 2072 val expIn = expIn rv env (fn _ => raise Fail "Iflow.evalExp: Bad field expression in INSERT")
1988 | _ => raise Fail "Iflow.evalExp: Bad field expression in UPDATE")
1989 2073
1990 val (es, st) = ListUtil.foldlMap 2074 val (es, st) = ListUtil.foldlMap
1991 (fn ((x, e), st) => 2075 (fn ((x, e), st) =>
1992 let 2076 let
1993 val (e, st) = case expIn (e, st) of 2077 val (e, st) = case expIn (e, st) of
2024 val p = And (p, 2108 val p = And (p,
2025 And (Reln (Sql "$Old", [Var old]), 2109 And (Reln (Sql "$Old", [Var old]),
2026 Reln (Sql tab, [Var old]))) 2110 Reln (Sql tab, [Var old])))
2027 in 2111 in
2028 (Recd [], St.addDelete (st, (loc, And (St.ambient st, p)))) 2112 (Recd [], St.addDelete (st, (loc, And (St.ambient st, p))))
2113 end
2114 | Update (tab, fs, e) =>
2115 let
2116 val (st, new) = St.nextVar st
2117 val (st, old) = St.nextVar st
2118
2119 fun rv st =
2120 let
2121 val (st, n) = St.nextVar st
2122 in
2123 (st, Var n)
2124 end
2125
2126 val expIn = expIn rv env (fn "T" => Var old
2127 | _ => raise Fail "Iflow.evalExp: Bad field expression in UPDATE")
2128
2129 val (fs, st) = ListUtil.foldlMap
2130 (fn ((x, e), st) =>
2131 let
2132 val (e, st) = case expIn (e, st) of
2133 (inl e, st) => (e, st)
2134 | (inr _, _) => raise Fail
2135 ("Iflow.evalExp: Selecting "
2136 ^ "boolean expression")
2137 in
2138 ((x, e), st)
2139 end)
2140 st fs
2141
2142 val (p, st) = case expIn (e, st) of
2143 (inl e, _) => raise Fail "Iflow.evalExp: UPDATE with non-boolean"
2144 | (inr p, st) => (p, st)
2145
2146 val p = And (p,
2147 And (Reln (Sql "$New", [Recd fs]),
2148 And (Reln (Sql "$Old", [Var old]),
2149 Reln (Sql tab, [Var old]))))
2150 in
2151 (Recd [], St.addUpdate (st, (loc, And (St.ambient st, p))))
2029 end) 2152 end)
2030 2153
2031 | ENextval _ => default () 2154 | ENextval _ => default ()
2032 | ESetval _ => default () 2155 | ESetval _ => default ()
2033 2156
2061 val exptd = foldl (fn ((d, _), exptd) => 2184 val exptd = foldl (fn ((d, _), exptd) =>
2062 case d of 2185 case d of
2063 DExport (_, _, n, _, _, _) => IS.add (exptd, n) 2186 DExport (_, _, n, _, _, _) => IS.add (exptd, n)
2064 | _ => exptd) IS.empty file 2187 | _ => exptd) IS.empty file
2065 2188
2066 fun decl ((d, _), (vals, inserts, deletes, client, insert, delete)) = 2189 fun decl ((d, _), (vals, inserts, deletes, updates, client, insert, delete, update)) =
2067 case d of 2190 case d of
2068 DVal (_, n, _, e, _) => 2191 DVal (_, n, _, e, _) =>
2069 let 2192 let
2070 val isExptd = IS.member (exptd, n) 2193 val isExptd = IS.member (exptd, n)
2071 2194
2081 val (e, env, nv, p) = deAbs (e, [], 1, True) 2204 val (e, env, nv, p) = deAbs (e, [], 1, True)
2082 2205
2083 val (_, st) = evalExp env (e, St.create {Var = nv, 2206 val (_, st) = evalExp env (e, St.create {Var = nv,
2084 Ambient = p}) 2207 Ambient = p})
2085 in 2208 in
2086 (St.sent st @ vals, St.inserted st @ inserts, St.deleted st @ deletes, client, insert, delete) 2209 (St.sent st @ vals, St.inserted st @ inserts, St.deleted st @ deletes, St.updated st @ updates,
2210 client, insert, delete, update)
2087 end 2211 end
2088 2212
2089 | DPolicy pol => 2213 | DPolicy pol =>
2090 let 2214 let
2091 fun rv rvN = (rvN + 1, Lvar rvN) 2215 fun rv rvN = (rvN + 1, Lvar rvN)
2093 case pol of 2217 case pol of
2094 PolClient e => 2218 PolClient e =>
2095 let 2219 let
2096 val (_, p, _, _, outs) = queryProp [] 0 rv SomeCol e 2220 val (_, p, _, _, outs) = queryProp [] 0 rv SomeCol e
2097 in 2221 in
2098 (vals, inserts, deletes, (p, outs) :: client, insert, delete) 2222 (vals, inserts, deletes, updates, (p, outs) :: client, insert, delete, update)
2099 end 2223 end
2100 | PolInsert e => 2224 | PolInsert e =>
2101 let 2225 let
2102 val p = insertProp 0 rv e 2226 val p = insertProp 0 rv e
2103 in 2227 in
2104 (vals, inserts, deletes, client, p :: insert, delete) 2228 (vals, inserts, deletes, updates, client, p :: insert, delete, update)
2105 end 2229 end
2106 | PolDelete e => 2230 | PolDelete e =>
2107 let 2231 let
2108 val p = deleteProp 0 rv e 2232 val p = deleteProp 0 rv e
2109 in 2233 in
2110 (vals, inserts, deletes, client, insert, p :: delete) 2234 (vals, inserts, deletes, updates, client, insert, p :: delete, update)
2235 end
2236 | PolUpdate e =>
2237 let
2238 val p = updateProp 0 rv e
2239 in
2240 (vals, inserts, deletes, updates, client, insert, delete, p :: update)
2111 end 2241 end
2112 end 2242 end
2113 2243
2114 | _ => (vals, inserts, deletes, client, insert, delete) 2244 | _ => (vals, inserts, deletes, updates, client, insert, delete, update)
2115 2245
2116 val () = reset () 2246 val () = reset ()
2117 2247
2118 val (vals, inserts, deletes, client, insert, delete) = foldl decl ([], [], [], [], [], []) file 2248 val (vals, inserts, deletes, updates, client, insert, delete, update) =
2249 foldl decl ([], [], [], [], [], [], [], []) file
2119 2250
2120 val decompH = decomp true (fn (e1, e2) => e1 andalso e2 ()) 2251 val decompH = decomp true (fn (e1, e2) => e1 andalso e2 ())
2121 val decompG = decomp false (fn (e1, e2) => e1 orelse e2 ()) 2252 val decompG = decomp false (fn (e1, e2) => e1 orelse e2 ())
2122 2253
2123 fun doDml (cmds, pols) = 2254 fun doDml (cmds, pols) =
2166 in 2297 in
2167 doAll e 2298 doAll e
2168 end) vals; 2299 end) vals;
2169 2300
2170 doDml (inserts, insert); 2301 doDml (inserts, insert);
2171 doDml (deletes, delete) 2302 doDml (deletes, delete);
2303 doDml (updates, update)
2172 end 2304 end
2173 2305
2174 val check = fn file => 2306 val check = fn file =>
2175 let 2307 let
2176 val oldInline = Settings.getMonoInline () 2308 val oldInline = Settings.getMonoInline ()