Skip to content

Commit

Permalink
net: Create a wrapper for sock ioctl
Browse files Browse the repository at this point in the history
Creates a wrapper for ioctls, where it call sock->ioctls() and save the
result back to userspace.

For ipmr and ip6mr cases (RAW and RAW6 proto), they are special since
they read the input from userspace and return a structure, other than
int.  This function handles these exceptions, and for everything else,
calls the ioctl and copy the result back to the userspace memory.

Signed-off-by: Breno Leitao <leitao@debian.org>
  • Loading branch information
leitao committed Apr 18, 2023
1 parent 9b65b11 commit 511592e
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions net/core/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
#include <linux/memcontrol.h>
#include <linux/prefetch.h>
#include <linux/compat.h>
#include <linux/mroute.h>
#include <linux/mroute6.h>

#include <linux/uaccess.h>

Expand All @@ -135,6 +137,7 @@
#include <net/bpf_sk_storage.h>

#include <trace/events/sock.h>
#include <uapi/asm-generic/ioctls.h>

#include <net/tcp.h>
#include <net/busy_poll.h>
Expand Down Expand Up @@ -4111,3 +4114,33 @@ int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len)
return sk->sk_prot->bind_add(sk, addr, addr_len);
}
EXPORT_SYMBOL(sock_bind_add);

/* This function basically calls ioctl and populates userspace buffers */
int sock_skprot_ioctl(struct sock *sk, unsigned int cmd,
unsigned long arg)
{
int ret, karg;

/* Raw/Raw6 sockets use "arg" in different ways */
if (!strcmp(sk->sk_prot->name, "RAW")) {
if (cmd != SIOCOUTQ && cmd != SIOCINQ) {
#ifdef CONFIG_IP_MROUTE
return sock_skprot_ioctl_ipmr(sk, cmd, arg);
#endif
}
} else if (!strcmp(sk->sk_prot->name, "RAW6")) {
if (cmd != SIOCOUTQ && cmd != SIOCINQ) {
#ifdef CONFIG_IPV6_MROUTE
return sock_skprot_ioctl_ip6mr(sk, cmd, arg);
#endif
}
}

/* This is a regular ioctl, and the result an int that should be
* copied to userspace */
ret = sk->sk_prot->ioctl(sk, cmd, &karg);
if (ret)
return ret;

return put_user(karg, (int __user *)arg);
}

0 comments on commit 511592e

Please sign in to comment.