aboutsummaryrefslogtreecommitdiff
path: root/net/nfc
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-03-20 16:36:13 +0100
committerSamuel Ortiz <sameo@linux.intel.com>2013-04-11 16:28:57 +0200
commit00e856db49bbaf0ec315bf81a3c4fc02e4d0beea (patch)
tree85ae9930d70bb465429b36225c3df5e64117fc66 /net/nfc
parent5eef6669759f8e291ab0347894876b532c242324 (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.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 873c837e5c9..f3027c21c44 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;