#include <linux/audit.h>
#include <linux/slab.h>
#include <linux/refcount.h>
+#include <linux/sockptr.h>
#include <net/sock.h>
#include <net/dst.h>
void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu);
int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
-int xfrm_user_policy(struct sock *sk, int optname,
- u8 __user *optval, int optlen);
+int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval,
+ int optlen);
#else
-static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
+static inline int xfrm_user_policy(struct sock *sk, int optname,
+ sockptr_t optval, int optlen)
{
return -ENOPROTOOPT;
}
err = -EPERM;
if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
break;
- err = xfrm_user_policy(sk, optname, optval, optlen);
+ err = xfrm_user_policy(sk, optname, USER_SOCKPTR(optval),
+ optlen);
break;
case IP_TRANSPARENT:
retv = -EPERM;
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
break;
- retv = xfrm_user_policy(sk, optname, optval, optlen);
+ retv = xfrm_user_policy(sk, optname, USER_SOCKPTR(optval),
+ optlen);
break;
case IPV6_ADDR_PREFERENCES:
return is_alive;
}
-int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
+int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
{
int err;
u8 *data;
if (in_compat_syscall())
return -EOPNOTSUPP;
- if (!optval && !optlen) {
+ if (sockptr_is_null(optval) && !optlen) {
xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
__sk_dst_reset(sk);
if (optlen <= 0 || optlen > PAGE_SIZE)
return -EMSGSIZE;
- data = memdup_user(optval, optlen);
+ data = memdup_sockptr(optval, optlen);
if (IS_ERR(data))
return PTR_ERR(data);