diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 40 |
1 files changed, 14 insertions, 26 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 4d2f2094e6df..5e52d6275bad 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1852,46 +1852,39 @@ static struct xfrm_link { | |||
1852 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, | 1852 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, |
1853 | }; | 1853 | }; |
1854 | 1854 | ||
1855 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) | 1855 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
1856 | { | 1856 | { |
1857 | struct rtattr *xfrma[XFRMA_MAX]; | 1857 | struct rtattr *xfrma[XFRMA_MAX]; |
1858 | struct xfrm_link *link; | 1858 | struct xfrm_link *link; |
1859 | int type, min_len; | 1859 | int type, min_len, err; |
1860 | 1860 | ||
1861 | type = nlh->nlmsg_type; | 1861 | type = nlh->nlmsg_type; |
1862 | |||
1863 | /* Unknown message: reply with EINVAL */ | ||
1864 | if (type > XFRM_MSG_MAX) | 1862 | if (type > XFRM_MSG_MAX) |
1865 | goto err_einval; | 1863 | return -EINVAL; |
1866 | 1864 | ||
1867 | type -= XFRM_MSG_BASE; | 1865 | type -= XFRM_MSG_BASE; |
1868 | link = &xfrm_dispatch[type]; | 1866 | link = &xfrm_dispatch[type]; |
1869 | 1867 | ||
1870 | /* All operations require privileges, even GET */ | 1868 | /* All operations require privileges, even GET */ |
1871 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) { | 1869 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) |
1872 | *errp = -EPERM; | 1870 | return -EPERM; |
1873 | return -1; | ||
1874 | } | ||
1875 | 1871 | ||
1876 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 1872 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
1877 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | 1873 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && |
1878 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | 1874 | (nlh->nlmsg_flags & NLM_F_DUMP)) { |
1879 | if (link->dump == NULL) | 1875 | if (link->dump == NULL) |
1880 | goto err_einval; | 1876 | return -EINVAL; |
1881 | |||
1882 | if ((*errp = netlink_dump_start(xfrm_nl, skb, nlh, | ||
1883 | link->dump, NULL)) != 0) { | ||
1884 | return -1; | ||
1885 | } | ||
1886 | 1877 | ||
1887 | netlink_queue_skip(nlh, skb); | 1878 | err = netlink_dump_start(xfrm_nl, skb, nlh, link->dump, NULL); |
1888 | return -1; | 1879 | if (err == 0) |
1880 | err = -EINTR; | ||
1881 | return err; | ||
1889 | } | 1882 | } |
1890 | 1883 | ||
1891 | memset(xfrma, 0, sizeof(xfrma)); | 1884 | memset(xfrma, 0, sizeof(xfrma)); |
1892 | 1885 | ||
1893 | if (nlh->nlmsg_len < (min_len = xfrm_msg_min[type])) | 1886 | if (nlh->nlmsg_len < (min_len = xfrm_msg_min[type])) |
1894 | goto err_einval; | 1887 | return -EINVAL; |
1895 | 1888 | ||
1896 | if (nlh->nlmsg_len > min_len) { | 1889 | if (nlh->nlmsg_len > min_len) { |
1897 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); | 1890 | int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); |
@@ -1901,7 +1894,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
1901 | unsigned short flavor = attr->rta_type; | 1894 | unsigned short flavor = attr->rta_type; |
1902 | if (flavor) { | 1895 | if (flavor) { |
1903 | if (flavor > XFRMA_MAX) | 1896 | if (flavor > XFRMA_MAX) |
1904 | goto err_einval; | 1897 | return -EINVAL; |
1905 | xfrma[flavor - 1] = attr; | 1898 | xfrma[flavor - 1] = attr; |
1906 | } | 1899 | } |
1907 | attr = RTA_NEXT(attr, attrlen); | 1900 | attr = RTA_NEXT(attr, attrlen); |
@@ -1909,14 +1902,9 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err | |||
1909 | } | 1902 | } |
1910 | 1903 | ||
1911 | if (link->doit == NULL) | 1904 | if (link->doit == NULL) |
1912 | goto err_einval; | 1905 | return -EINVAL; |
1913 | *errp = link->doit(skb, nlh, xfrma); | ||
1914 | |||
1915 | return *errp; | ||
1916 | 1906 | ||
1917 | err_einval: | 1907 | return link->doit(skb, nlh, xfrma); |
1918 | *errp = -EINVAL; | ||
1919 | return -1; | ||
1920 | } | 1908 | } |
1921 | 1909 | ||
1922 | static void xfrm_netlink_rcv(struct sock *sk, int len) | 1910 | static void xfrm_netlink_rcv(struct sock *sk, int len) |