aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Reisner <philipp.reisner@linbit.com>2011-04-27 05:27:47 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-11-08 10:49:08 -0500
commit0fd0ea064c30022577f62d9060889d964123be6f (patch)
tree937fb63d9a6072b51594d933814aab769d814f3b
parentd9cc6e231897a9ab1a94e6cfe12d71bfec0b7a81 (diff)
drbd: Consider all crypto options in connect and in net-options
So for this was simply not considered after the options have been re-arranged. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r--drivers/block/drbd/drbd_nl.c230
1 files changed, 121 insertions, 109 deletions
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index a16089ce0a56..f85cef448387 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -1727,6 +1727,88 @@ check_net_options(struct drbd_tconn *tconn, struct net_conf *new_conf)
1727 return rv; 1727 return rv;
1728} 1728}
1729 1729
1730struct crypto {
1731 struct crypto_hash *verify_tfm;
1732 struct crypto_hash *csums_tfm;
1733 struct crypto_hash *cram_hmac_tfm;
1734 struct crypto_hash *integrity_w_tfm;
1735 struct crypto_hash *integrity_r_tfm;
1736 void *int_dig_in;
1737 void *int_dig_vv;
1738};
1739
1740static int
1741alloc_tfm(struct crypto_hash **tfm, char *tfm_name, int err_alg, int err_nd)
1742{
1743 if (!tfm_name[0])
1744 return NO_ERROR;
1745
1746 *tfm = crypto_alloc_hash(tfm_name, 0, CRYPTO_ALG_ASYNC);
1747 if (IS_ERR(*tfm)) {
1748 *tfm = NULL;
1749 return err_alg;
1750 }
1751
1752 if (!drbd_crypto_is_hash(crypto_hash_tfm(*tfm)))
1753 return err_nd;
1754
1755 return NO_ERROR;
1756}
1757
1758static enum drbd_ret_code
1759alloc_crypto(struct crypto *crypto, struct net_conf *new_conf)
1760{
1761 char hmac_name[CRYPTO_MAX_ALG_NAME];
1762 enum drbd_ret_code rv;
1763 int hash_size;
1764
1765 rv = alloc_tfm(&crypto->csums_tfm, new_conf->csums_alg,
1766 ERR_CSUMS_ALG, ERR_CSUMS_ALG_ND);
1767 if (rv != NO_ERROR)
1768 return rv;
1769 rv = alloc_tfm(&crypto->verify_tfm, new_conf->verify_alg,
1770 ERR_VERIFY_ALG, ERR_VERIFY_ALG_ND);
1771 if (rv != NO_ERROR)
1772 return rv;
1773 rv = alloc_tfm(&crypto->integrity_w_tfm, new_conf->integrity_alg,
1774 ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
1775 if (rv != NO_ERROR)
1776 return rv;
1777 rv = alloc_tfm(&crypto->integrity_r_tfm, new_conf->integrity_alg,
1778 ERR_INTEGRITY_ALG, ERR_INTEGRITY_ALG_ND);
1779 if (rv != NO_ERROR)
1780 return rv;
1781 if (new_conf->cram_hmac_alg[0] != 0) {
1782 snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
1783 new_conf->cram_hmac_alg);
1784
1785 rv = alloc_tfm(&crypto->cram_hmac_tfm, hmac_name,
1786 ERR_AUTH_ALG, ERR_AUTH_ALG_ND);
1787 }
1788 if (crypto->integrity_w_tfm) {
1789 hash_size = crypto_hash_digestsize(crypto->integrity_w_tfm);
1790 crypto->int_dig_in = kmalloc(hash_size, GFP_KERNEL);
1791 if (!crypto->int_dig_in)
1792 return ERR_NOMEM;
1793 crypto->int_dig_vv = kmalloc(hash_size, GFP_KERNEL);
1794 if (!crypto->int_dig_vv)
1795 return ERR_NOMEM;
1796 }
1797
1798 return rv;
1799}
1800
1801static void free_crypto(struct crypto *crypto)
1802{
1803 kfree(crypto->int_dig_in);
1804 kfree(crypto->int_dig_vv);
1805 crypto_free_hash(crypto->cram_hmac_tfm);
1806 crypto_free_hash(crypto->integrity_w_tfm);
1807 crypto_free_hash(crypto->integrity_r_tfm);
1808 crypto_free_hash(crypto->csums_tfm);
1809 crypto_free_hash(crypto->verify_tfm);
1810}
1811
1730int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) 1812int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
1731{ 1813{
1732 enum drbd_ret_code retcode; 1814 enum drbd_ret_code retcode;
@@ -1735,9 +1817,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
1735 int err; 1817 int err;
1736 int ovr; /* online verify running */ 1818 int ovr; /* online verify running */
1737 int rsr; /* re-sync running */ 1819 int rsr; /* re-sync running */
1738 struct crypto_hash *verify_tfm = NULL; 1820 struct crypto crypto = { };
1739 struct crypto_hash *csums_tfm = NULL;
1740
1741 1821
1742 retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONN); 1822 retcode = drbd_adm_prepare(skb, info, DRBD_ADM_NEED_CONN);
1743 if (!adm_ctx.reply_skb) 1823 if (!adm_ctx.reply_skb)
@@ -1779,61 +1859,49 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
1779 1859
1780 /* re-sync running */ 1860 /* re-sync running */
1781 rsr = conn_resync_running(tconn); 1861 rsr = conn_resync_running(tconn);
1782 if (rsr && old_conf && strcmp(new_conf->csums_alg, old_conf->csums_alg)) { 1862 if (rsr && strcmp(new_conf->csums_alg, old_conf->csums_alg)) {
1783 retcode = ERR_CSUMS_RESYNC_RUNNING; 1863 retcode = ERR_CSUMS_RESYNC_RUNNING;
1784 goto fail; 1864 goto fail;
1785 } 1865 }
1786 1866
1787 if (!rsr && new_conf->csums_alg[0]) {
1788 csums_tfm = crypto_alloc_hash(new_conf->csums_alg, 0, CRYPTO_ALG_ASYNC);
1789 if (IS_ERR(csums_tfm)) {
1790 csums_tfm = NULL;
1791 retcode = ERR_CSUMS_ALG;
1792 goto fail;
1793 }
1794
1795 if (!drbd_crypto_is_hash(crypto_hash_tfm(csums_tfm))) {
1796 retcode = ERR_CSUMS_ALG_ND;
1797 goto fail;
1798 }
1799 }
1800
1801 /* online verify running */ 1867 /* online verify running */
1802 ovr = conn_ov_running(tconn); 1868 ovr = conn_ov_running(tconn);
1803 if (ovr) { 1869 if (ovr && strcmp(new_conf->verify_alg, old_conf->verify_alg)) {
1804 if (strcmp(new_conf->verify_alg, old_conf->verify_alg)) { 1870 retcode = ERR_VERIFY_RUNNING;
1805 retcode = ERR_VERIFY_RUNNING; 1871 goto fail;
1806 goto fail;
1807 }
1808 } 1872 }
1809 1873
1810 if (!ovr && new_conf->verify_alg[0]) { 1874 retcode = alloc_crypto(&crypto, new_conf);
1811 verify_tfm = crypto_alloc_hash(new_conf->verify_alg, 0, CRYPTO_ALG_ASYNC); 1875 if (retcode != NO_ERROR)
1812 if (IS_ERR(verify_tfm)) { 1876 goto fail;
1813 verify_tfm = NULL;
1814 retcode = ERR_VERIFY_ALG;
1815 goto fail;
1816 }
1817
1818 if (!drbd_crypto_is_hash(crypto_hash_tfm(verify_tfm))) {
1819 retcode = ERR_VERIFY_ALG_ND;
1820 goto fail;
1821 }
1822 }
1823 1877
1824 rcu_assign_pointer(tconn->net_conf, new_conf); 1878 rcu_assign_pointer(tconn->net_conf, new_conf);
1825 1879
1826 if (!rsr) { 1880 if (!rsr) {
1827 crypto_free_hash(tconn->csums_tfm); 1881 crypto_free_hash(tconn->csums_tfm);
1828 tconn->csums_tfm = csums_tfm; 1882 tconn->csums_tfm = crypto.csums_tfm;
1829 csums_tfm = NULL; 1883 crypto.csums_tfm = NULL;
1830 } 1884 }
1831 if (!ovr) { 1885 if (!ovr) {
1832 crypto_free_hash(tconn->verify_tfm); 1886 crypto_free_hash(tconn->verify_tfm);
1833 tconn->verify_tfm = verify_tfm; 1887 tconn->verify_tfm = crypto.verify_tfm;
1834 verify_tfm = NULL; 1888 crypto.verify_tfm = NULL;
1835 } 1889 }
1836 1890
1891 /* FIXME can not assign these so bluntly while we have ongoing IO */
1892 kfree(tconn->int_dig_in);
1893 tconn->int_dig_in = crypto.int_dig_in;
1894 kfree(tconn->int_dig_vv);
1895 tconn->int_dig_vv = crypto.int_dig_vv;
1896 crypto_free_hash(tconn->integrity_w_tfm);
1897 tconn->integrity_w_tfm = crypto.integrity_w_tfm;
1898 crypto_free_hash(tconn->integrity_r_tfm);
1899 tconn->integrity_r_tfm = crypto.integrity_r_tfm;
1900
1901 /* FIXME Changing cram_hmac while the connection is established is useless */
1902 crypto_free_hash(tconn->cram_hmac_tfm);
1903 tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
1904
1837 mutex_unlock(&tconn->net_conf_update); 1905 mutex_unlock(&tconn->net_conf_update);
1838 synchronize_rcu(); 1906 synchronize_rcu();
1839 kfree(old_conf); 1907 kfree(old_conf);
@@ -1845,8 +1913,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
1845 1913
1846 fail: 1914 fail:
1847 mutex_unlock(&tconn->net_conf_update); 1915 mutex_unlock(&tconn->net_conf_update);
1848 crypto_free_hash(csums_tfm); 1916 free_crypto(&crypto);
1849 crypto_free_hash(verify_tfm);
1850 kfree(new_conf); 1917 kfree(new_conf);
1851 done: 1918 done:
1852 conn_reconfig_done(tconn); 1919 conn_reconfig_done(tconn);
@@ -1857,14 +1924,9 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info)
1857 1924
1858int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) 1925int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
1859{ 1926{
1860 char hmac_name[CRYPTO_MAX_ALG_NAME];
1861 struct drbd_conf *mdev; 1927 struct drbd_conf *mdev;
1862 struct net_conf *old_conf, *new_conf = NULL; 1928 struct net_conf *old_conf, *new_conf = NULL;
1863 struct crypto_hash *tfm = NULL; 1929 struct crypto crypto = { };
1864 struct crypto_hash *integrity_w_tfm = NULL;
1865 struct crypto_hash *integrity_r_tfm = NULL;
1866 void *int_dig_in = NULL;
1867 void *int_dig_vv = NULL;
1868 struct drbd_tconn *oconn; 1930 struct drbd_tconn *oconn;
1869 struct drbd_tconn *tconn; 1931 struct drbd_tconn *tconn;
1870 struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr; 1932 struct sockaddr *new_my_addr, *new_peer_addr, *taken_addr;
@@ -1969,60 +2031,12 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
1969 goto fail; 2031 goto fail;
1970 } 2032 }
1971 2033
1972 if (new_conf->cram_hmac_alg[0] != 0) { 2034 retcode = alloc_crypto(&crypto, new_conf);
1973 snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", 2035 if (retcode != NO_ERROR)
1974 new_conf->cram_hmac_alg); 2036 goto fail;
1975 tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC);
1976 if (IS_ERR(tfm)) {
1977 tfm = NULL;
1978 retcode = ERR_AUTH_ALG;
1979 goto fail;
1980 }
1981
1982 if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
1983 retcode = ERR_AUTH_ALG_ND;
1984 goto fail;
1985 }
1986 }
1987
1988 if (new_conf->integrity_alg[0]) {
1989 integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
1990 if (IS_ERR(integrity_w_tfm)) {
1991 integrity_w_tfm = NULL;
1992 retcode=ERR_INTEGRITY_ALG;
1993 goto fail;
1994 }
1995
1996 if (!drbd_crypto_is_hash(crypto_hash_tfm(integrity_w_tfm))) {
1997 retcode=ERR_INTEGRITY_ALG_ND;
1998 goto fail;
1999 }
2000
2001 integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC);
2002 if (IS_ERR(integrity_r_tfm)) {
2003 integrity_r_tfm = NULL;
2004 retcode=ERR_INTEGRITY_ALG;
2005 goto fail;
2006 }
2007 }
2008 2037
2009 ((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; 2038 ((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0;
2010 2039
2011 /* allocation not in the IO path, cqueue thread context */
2012 if (integrity_w_tfm) {
2013 i = crypto_hash_digestsize(integrity_w_tfm);
2014 int_dig_in = kmalloc(i, GFP_KERNEL);
2015 if (!int_dig_in) {
2016 retcode = ERR_NOMEM;
2017 goto fail;
2018 }
2019 int_dig_vv = kmalloc(i, GFP_KERNEL);
2020 if (!int_dig_vv) {
2021 retcode = ERR_NOMEM;
2022 goto fail;
2023 }
2024 }
2025
2026 conn_flush_workqueue(tconn); 2040 conn_flush_workqueue(tconn);
2027 2041
2028 mutex_lock(&tconn->net_conf_update); 2042 mutex_lock(&tconn->net_conf_update);
@@ -2035,11 +2049,13 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
2035 rcu_assign_pointer(tconn->net_conf, new_conf); 2049 rcu_assign_pointer(tconn->net_conf, new_conf);
2036 2050
2037 conn_free_crypto(tconn); 2051 conn_free_crypto(tconn);
2038 tconn->cram_hmac_tfm = tfm; 2052 tconn->int_dig_in = crypto.int_dig_in;
2039 tconn->integrity_w_tfm = integrity_w_tfm; 2053 tconn->int_dig_vv = crypto.int_dig_vv;
2040 tconn->integrity_r_tfm = integrity_r_tfm; 2054 tconn->cram_hmac_tfm = crypto.cram_hmac_tfm;
2041 tconn->int_dig_in = int_dig_in; 2055 tconn->integrity_w_tfm = crypto.integrity_w_tfm;
2042 tconn->int_dig_vv = int_dig_vv; 2056 tconn->integrity_r_tfm = crypto.integrity_r_tfm;
2057 tconn->csums_tfm = crypto.csums_tfm;
2058 tconn->verify_tfm = crypto.verify_tfm;
2043 2059
2044 mutex_unlock(&tconn->net_conf_update); 2060 mutex_unlock(&tconn->net_conf_update);
2045 2061
@@ -2057,11 +2073,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info)
2057 return 0; 2073 return 0;
2058 2074
2059fail: 2075fail:
2060 kfree(int_dig_in); 2076 free_crypto(&crypto);
2061 kfree(int_dig_vv);
2062 crypto_free_hash(tfm);
2063 crypto_free_hash(integrity_w_tfm);
2064 crypto_free_hash(integrity_r_tfm);
2065 kfree(new_conf); 2077 kfree(new_conf);
2066 2078
2067 conn_reconfig_done(tconn); 2079 conn_reconfig_done(tconn);