diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-03-20 16:36:13 +0100 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-11 16:28:57 +0200 |
commit | 00e856db49bbaf0ec315bf81a3c4fc02e4d0beea (patch) | |
tree | 85ae9930d70bb465429b36225c3df5e64117fc66 /net/nfc | |
parent | 5eef6669759f8e291ab0347894876b532c242324 (diff) |
NFC: llcp: Fall back to local values when getting socket options
If a socket option has not been set by the user, fall back to the LLCP
local ones.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp/sock.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 873c837e5c97..f3027c21c442 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -299,9 +299,12 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { + struct nfc_llcp_local *local; struct sock *sk = sock->sk; struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); int len, err = 0; + u16 miux; + u8 rw; pr_debug("%p optname %d\n", sk, optname); @@ -311,20 +314,27 @@ static int nfc_llcp_getsockopt(struct socket *sock, int level, int optname, if (get_user(len, optlen)) return -EFAULT; + local = llcp_sock->local; + if (!local) + return -ENODEV; + len = min_t(u32, len, sizeof(u32)); lock_sock(sk); switch (optname) { case NFC_LLCP_RW: - if (put_user(llcp_sock->rw, (u32 __user *) optval)) + rw = llcp_sock->rw > LLCP_MAX_RW ? local->rw : llcp_sock->rw; + if (put_user(rw, (u32 __user *) optval)) err = -EFAULT; break; case NFC_LLCP_MIUX: - if (put_user(be16_to_cpu(llcp_sock->miux), - (u32 __user *) optval)) + miux = be16_to_cpu(llcp_sock->miux) > LLCP_MAX_MIUX ? + be16_to_cpu(local->miux) : be16_to_cpu(llcp_sock->miux); + + if (put_user(miux, (u32 __user *) optval)) err = -EFAULT; break; |