diff options
| -rw-r--r-- | net/ipv4/cipso_ipv4.c | 115 |
1 files changed, 42 insertions, 73 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index ab56a052ce31..805a78e6ed55 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -1831,68 +1831,75 @@ socket_setattr_failure: | |||
| 1831 | } | 1831 | } |
| 1832 | 1832 | ||
| 1833 | /** | 1833 | /** |
| 1834 | * cipso_v4_sock_getattr - Get the security attributes from a sock | 1834 | * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions |
| 1835 | * @sk: the sock | 1835 | * @cipso: the CIPSO v4 option |
| 1836 | * @secattr: the security attributes | 1836 | * @secattr: the security attributes |
| 1837 | * | 1837 | * |
| 1838 | * Description: | 1838 | * Description: |
| 1839 | * Query @sk to see if there is a CIPSO option attached to the sock and if | 1839 | * Inspect @cipso and return the security attributes in @secattr. Returns zero |
| 1840 | * there is return the CIPSO security attributes in @secattr. This function | 1840 | * on success and negative values on failure. |
| 1841 | * requires that @sk be locked, or privately held, but it does not do any | ||
| 1842 | * locking itself. Returns zero on success and negative values on failure. | ||
| 1843 | * | 1841 | * |
| 1844 | */ | 1842 | */ |
| 1845 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | 1843 | static int cipso_v4_getattr(const unsigned char *cipso, |
| 1844 | struct netlbl_lsm_secattr *secattr) | ||
| 1846 | { | 1845 | { |
| 1847 | int ret_val = -ENOMSG; | 1846 | int ret_val = -ENOMSG; |
| 1848 | struct inet_sock *sk_inet; | ||
| 1849 | unsigned char *cipso_ptr; | ||
| 1850 | u32 doi; | 1847 | u32 doi; |
| 1851 | struct cipso_v4_doi *doi_def; | 1848 | struct cipso_v4_doi *doi_def; |
| 1852 | 1849 | ||
| 1853 | sk_inet = inet_sk(sk); | 1850 | if (cipso_v4_cache_check(cipso, cipso[1], secattr) == 0) |
| 1854 | if (sk_inet->opt == NULL || sk_inet->opt->cipso == 0) | 1851 | return 0; |
| 1855 | return -ENOMSG; | ||
| 1856 | cipso_ptr = sk_inet->opt->__data + sk_inet->opt->cipso - | ||
| 1857 | sizeof(struct iphdr); | ||
| 1858 | ret_val = cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr); | ||
| 1859 | if (ret_val == 0) | ||
| 1860 | return ret_val; | ||
| 1861 | 1852 | ||
| 1862 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); | 1853 | doi = ntohl(get_unaligned((__be32 *)&cipso[2])); |
| 1863 | rcu_read_lock(); | 1854 | rcu_read_lock(); |
| 1864 | doi_def = cipso_v4_doi_search(doi); | 1855 | doi_def = cipso_v4_doi_search(doi); |
| 1865 | if (doi_def == NULL) { | 1856 | if (doi_def == NULL) |
| 1866 | rcu_read_unlock(); | 1857 | goto getattr_return; |
| 1867 | return -ENOMSG; | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | /* XXX - This code assumes only one tag per CIPSO option which isn't | 1858 | /* XXX - This code assumes only one tag per CIPSO option which isn't |
| 1871 | * really a good assumption to make but since we only support the MAC | 1859 | * really a good assumption to make but since we only support the MAC |
| 1872 | * tags right now it is a safe assumption. */ | 1860 | * tags right now it is a safe assumption. */ |
| 1873 | switch (cipso_ptr[6]) { | 1861 | switch (cipso[6]) { |
| 1874 | case CIPSO_V4_TAG_RBITMAP: | 1862 | case CIPSO_V4_TAG_RBITMAP: |
| 1875 | ret_val = cipso_v4_parsetag_rbm(doi_def, | 1863 | ret_val = cipso_v4_parsetag_rbm(doi_def, &cipso[6], secattr); |
| 1876 | &cipso_ptr[6], | ||
| 1877 | secattr); | ||
| 1878 | break; | 1864 | break; |
| 1879 | case CIPSO_V4_TAG_ENUM: | 1865 | case CIPSO_V4_TAG_ENUM: |
| 1880 | ret_val = cipso_v4_parsetag_enum(doi_def, | 1866 | ret_val = cipso_v4_parsetag_enum(doi_def, &cipso[6], secattr); |
| 1881 | &cipso_ptr[6], | ||
| 1882 | secattr); | ||
| 1883 | break; | 1867 | break; |
| 1884 | case CIPSO_V4_TAG_RANGE: | 1868 | case CIPSO_V4_TAG_RANGE: |
| 1885 | ret_val = cipso_v4_parsetag_rng(doi_def, | 1869 | ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr); |
| 1886 | &cipso_ptr[6], | ||
| 1887 | secattr); | ||
| 1888 | break; | 1870 | break; |
| 1889 | } | 1871 | } |
| 1890 | rcu_read_unlock(); | ||
| 1891 | 1872 | ||
| 1873 | getattr_return: | ||
| 1874 | rcu_read_unlock(); | ||
| 1892 | return ret_val; | 1875 | return ret_val; |
| 1893 | } | 1876 | } |
| 1894 | 1877 | ||
| 1895 | /** | 1878 | /** |
| 1879 | * cipso_v4_sock_getattr - Get the security attributes from a sock | ||
| 1880 | * @sk: the sock | ||
| 1881 | * @secattr: the security attributes | ||
| 1882 | * | ||
| 1883 | * Description: | ||
| 1884 | * Query @sk to see if there is a CIPSO option attached to the sock and if | ||
| 1885 | * there is return the CIPSO security attributes in @secattr. This function | ||
| 1886 | * requires that @sk be locked, or privately held, but it does not do any | ||
| 1887 | * locking itself. Returns zero on success and negative values on failure. | ||
| 1888 | * | ||
| 1889 | */ | ||
| 1890 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | ||
| 1891 | { | ||
| 1892 | struct ip_options *opt; | ||
| 1893 | |||
| 1894 | opt = inet_sk(sk)->opt; | ||
| 1895 | if (opt == NULL || opt->cipso == 0) | ||
| 1896 | return -ENOMSG; | ||
| 1897 | |||
| 1898 | return cipso_v4_getattr(opt->__data + opt->cipso - sizeof(struct iphdr), | ||
| 1899 | secattr); | ||
| 1900 | } | ||
| 1901 | |||
| 1902 | /** | ||
| 1896 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option | 1903 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option |
| 1897 | * @skb: the packet | 1904 | * @skb: the packet |
| 1898 | * @secattr: the security attributes | 1905 | * @secattr: the security attributes |
| @@ -1905,45 +1912,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
| 1905 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | 1912 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, |
| 1906 | struct netlbl_lsm_secattr *secattr) | 1913 | struct netlbl_lsm_secattr *secattr) |
| 1907 | { | 1914 | { |
| 1908 | int ret_val = -ENOMSG; | 1915 | return cipso_v4_getattr(CIPSO_V4_OPTPTR(skb), secattr); |
| 1909 | unsigned char *cipso_ptr; | ||
| 1910 | u32 doi; | ||
| 1911 | struct cipso_v4_doi *doi_def; | ||
| 1912 | |||
| 1913 | cipso_ptr = CIPSO_V4_OPTPTR(skb); | ||
| 1914 | if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) | ||
| 1915 | return 0; | ||
| 1916 | |||
| 1917 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); | ||
| 1918 | rcu_read_lock(); | ||
| 1919 | doi_def = cipso_v4_doi_search(doi); | ||
| 1920 | if (doi_def == NULL) | ||
| 1921 | goto skbuff_getattr_return; | ||
| 1922 | |||
| 1923 | /* XXX - This code assumes only one tag per CIPSO option which isn't | ||
| 1924 | * really a good assumption to make but since we only support the MAC | ||
| 1925 | * tags right now it is a safe assumption. */ | ||
| 1926 | switch (cipso_ptr[6]) { | ||
| 1927 | case CIPSO_V4_TAG_RBITMAP: | ||
| 1928 | ret_val = cipso_v4_parsetag_rbm(doi_def, | ||
| 1929 | &cipso_ptr[6], | ||
| 1930 | secattr); | ||
| 1931 | break; | ||
| 1932 | case CIPSO_V4_TAG_ENUM: | ||
| 1933 | ret_val = cipso_v4_parsetag_enum(doi_def, | ||
| 1934 | &cipso_ptr[6], | ||
| 1935 | secattr); | ||
| 1936 | break; | ||
| 1937 | case CIPSO_V4_TAG_RANGE: | ||
| 1938 | ret_val = cipso_v4_parsetag_rng(doi_def, | ||
| 1939 | &cipso_ptr[6], | ||
| 1940 | secattr); | ||
| 1941 | break; | ||
| 1942 | } | ||
| 1943 | |||
| 1944 | skbuff_getattr_return: | ||
| 1945 | rcu_read_unlock(); | ||
| 1946 | return ret_val; | ||
| 1947 | } | 1916 | } |
| 1948 | 1917 | ||
| 1949 | /* | 1918 | /* |
