aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c40
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
1855static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 1855static 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
1917err_einval: 1907 return link->doit(skb, nlh, xfrma);
1918 *errp = -EINVAL;
1919 return -1;
1920} 1908}
1921 1909
1922static void xfrm_netlink_rcv(struct sock *sk, int len) 1910static void xfrm_netlink_rcv(struct sock *sk, int len)