Skip to content

Commit

Permalink
net: Make setsockopt() optlen be unsigned.
Browse files Browse the repository at this point in the history
This provides safety against negative optlen at the type
level instead of depending upon (sometimes non-trivial)
checks against this sprinkled all over the the place, in
each and every implementation.

Based upon work done by Arjan van de Ven and feedback
from Linus Torvalds.

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Sep 30, 2009
1 parent eb1cf0f commit b705884
Show file tree
Hide file tree
Showing 67 changed files with 149 additions and 153 deletions.
8 changes: 0 additions & 8 deletions drivers/atm/ambassador.c
Original file line number Diff line number Diff line change
Expand Up @@ -1306,14 +1306,6 @@ static void amb_close (struct atm_vcc * atm_vcc) {
return;
}

/********** Set socket options for a VC **********/

// int amb_getsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);

/********** Set socket options for a VC **********/

// int amb_setsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);

/********** Send **********/

static int amb_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/eni.c
Original file line number Diff line number Diff line change
Expand Up @@ -2031,7 +2031,7 @@ static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,


static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen)
void __user *optval,unsigned int optlen)
{
return -EINVAL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/firestream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,


static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen)
void __user *optval,unsigned int optlen)
{
func_enter ();
func_exit ();
Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/fore200e.c
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op


static int
fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
{
/* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */

Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/horizon.c
Original file line number Diff line number Diff line change
Expand Up @@ -2590,7 +2590,7 @@ static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
}

static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
void *optval, int optlen) {
void *optval, unsigned int optlen) {
hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
switch (level) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/iphase.c
Original file line number Diff line number Diff line change
Expand Up @@ -2862,7 +2862,7 @@ static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
}

static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
void __user *optval, int optlen)
void __user *optval, unsigned int optlen)
{
IF_EVENT(printk(">ia_setsockopt\n");)
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion drivers/atm/zatm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,7 +1517,7 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,


static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen)
void __user *optval,unsigned int optlen)
{
return -EINVAL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/isdn/mISDN/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}

static int data_sock_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int len)
char __user *optval, unsigned int len)
{
struct sock *sk = sock->sk;
int err = 0, opt = 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/pppol2tp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2179,7 +2179,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
* session or the special tunnel type.
*/
static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct pppol2tp_session *session = sk->sk_user_data;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/atmdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ struct atmdev_ops { /* only send is required */
int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen);
int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
void __user *optval,int optlen);
void __user *optval,unsigned int optlen);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
Expand Down
4 changes: 2 additions & 2 deletions include/linux/mroute.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,14 @@ static inline int ip_mroute_opt(int opt)
#endif

#ifdef CONFIG_IP_MROUTE
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int);
extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
extern int ip_mr_init(void);
#else
static inline
int ip_mroute_setsockopt(struct sock *sock,
int optname, char __user *optval, int optlen)
int optname, char __user *optval, unsigned int optlen)
{
return -ENOPROTOOPT;
}
Expand Down
4 changes: 2 additions & 2 deletions include/linux/mroute6.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static inline int ip6_mroute_opt(int opt)
struct sock;

#ifdef CONFIG_IPV6_MROUTE
extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int);
extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
extern int ip6_mr_input(struct sk_buff *skb);
extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
Expand All @@ -143,7 +143,7 @@ extern void ip6_mr_cleanup(void);
#else
static inline
int ip6_mroute_setsockopt(struct sock *sock,
int optname, char __user *optval, int optlen)
int optname, char __user *optval, unsigned int optlen)
{
return -ENOPROTOOPT;
}
Expand Down
8 changes: 4 additions & 4 deletions include/linux/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ struct proto_ops {
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int optlen);
int optname, char __user *optval, unsigned int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*compat_setsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int optlen);
int optname, char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
Expand Down Expand Up @@ -256,7 +256,7 @@ extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
extern int kernel_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen);
extern int kernel_setsockopt(struct socket *sock, int level, int optname,
char *optval, int optlen);
char *optval, unsigned int optlen);
extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags);
extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
Expand Down Expand Up @@ -313,7 +313,7 @@ SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
char __user *optval, int optlen), (sock, level, optname, optval, optlen)) \
char __user *optval, unsigned int optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \
char __user *optval, int __user *optlen), (sock, level, optname, optval, optlen)) \
SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len), \
Expand Down
4 changes: 2 additions & 2 deletions include/linux/netfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@ __ret;})

/* Call setsockopt() */
int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int len);
unsigned int len);
int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
int *len);

int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
char __user *opt, int len);
char __user *opt, unsigned int len);
int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
char __user *opt, int *len);

Expand Down
4 changes: 2 additions & 2 deletions include/net/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);

extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);

extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, int,
int (*)(struct sock *, int, int, char __user *, int));
extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, unsigned int,
int (*)(struct sock *, int, int, char __user *, unsigned int));
extern int compat_mc_getsockopt(struct sock *, int, int, char __user *,
int __user *, int (*)(struct sock *, int, int, char __user *,
int __user *));
Expand Down
6 changes: 3 additions & 3 deletions include/net/inet_connection_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ struct inet_connection_sock_af_ops {
u16 net_header_len;
u16 sockaddr_len;
int (*setsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(struct sock *sk,
int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
Expand Down Expand Up @@ -332,5 +332,5 @@ extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
#endif /* _INET_CONNECTION_SOCK_H */
4 changes: 2 additions & 2 deletions include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,10 @@ extern int ip_options_rcv_srr(struct sk_buff *skb);
extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
extern int ip_cmsg_send(struct net *net,
struct msghdr *msg, struct ipcm_cookie *ipc);
extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen);
extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen);
extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
extern int compat_ip_setsockopt(struct sock *sk, int level,
int optname, char __user *optval, int optlen);
int optname, char __user *optval, unsigned int optlen);
extern int compat_ip_getsockopt(struct sock *sk, int level,
int optname, char __user *optval, int __user *optlen);
extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
Expand Down
4 changes: 2 additions & 2 deletions include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
extern int ipv6_setsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
int optlen);
unsigned int optlen);
extern int ipv6_getsockopt(struct sock *sk, int level,
int optname,
char __user *optval,
Expand All @@ -559,7 +559,7 @@ extern int compat_ipv6_setsockopt(struct sock *sk,
int level,
int optname,
char __user *optval,
int optlen);
unsigned int optlen);
extern int compat_ipv6_getsockopt(struct sock *sk,
int level,
int optname,
Expand Down
4 changes: 2 additions & 2 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ struct sctp_af {
int level,
int optname,
char __user *optval,
int optlen);
unsigned int optlen);
int (*getsockopt) (struct sock *sk,
int level,
int optname,
Expand All @@ -554,7 +554,7 @@ struct sctp_af {
int level,
int optname,
char __user *optval,
int optlen);
unsigned int optlen);
int (*compat_getsockopt) (struct sock *sk,
int level,
int optname,
Expand Down
12 changes: 6 additions & 6 deletions include/net/sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,15 +624,15 @@ struct proto {
void (*shutdown)(struct sock *sk, int how);
int (*setsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
int optlen);
unsigned int optlen);
int (*getsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
int __user *option);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(struct sock *sk,
int level,
int optname, char __user *optval,
int optlen);
unsigned int optlen);
int (*compat_getsockopt)(struct sock *sk,
int level,
int optname, char __user *optval,
Expand Down Expand Up @@ -951,7 +951,7 @@ extern void sock_rfree(struct sk_buff *skb);

extern int sock_setsockopt(struct socket *sock, int level,
int op, char __user *optval,
int optlen);
unsigned int optlen);

extern int sock_getsockopt(struct socket *sock, int level,
int op, char __user *optval,
Expand Down Expand Up @@ -993,7 +993,7 @@ extern int sock_no_shutdown(struct socket *, int);
extern int sock_no_getsockopt(struct socket *, int , int,
char __user *, int __user *);
extern int sock_no_setsockopt(struct socket *, int, int,
char __user *, int);
char __user *, unsigned int);
extern int sock_no_sendmsg(struct kiocb *, struct socket *,
struct msghdr *, size_t);
extern int sock_no_recvmsg(struct kiocb *, struct socket *,
Expand All @@ -1015,11 +1015,11 @@ extern int sock_common_getsockopt(struct socket *sock, int level, int optname,
extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags);
extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
extern int compat_sock_common_getsockopt(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
extern int compat_sock_common_setsockopt(struct socket *sock, int level,
int optname, char __user *optval, int optlen);
int optname, char __user *optval, unsigned int optlen);

extern void sk_common_release(struct sock *sk);

Expand Down
4 changes: 2 additions & 2 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,13 +394,13 @@ extern int tcp_getsockopt(struct sock *sk, int level,
int __user *optlen);
extern int tcp_setsockopt(struct sock *sk, int level,
int optname, char __user *optval,
int optlen);
unsigned int optlen);
extern int compat_tcp_getsockopt(struct sock *sk,
int level, int optname,
char __user *optval, int __user *optlen);
extern int compat_tcp_setsockopt(struct sock *sk,
int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
extern void tcp_set_keepalive(struct sock *sk, int val);
extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg,
Expand Down
2 changes: 1 addition & 1 deletion include/net/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ extern unsigned int udp_poll(struct file *file, struct socket *sock,
extern int udp_lib_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
char __user *optval, int optlen,
char __user *optval, unsigned int optlen,
int (*push_pending_frames)(struct sock *));

extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
Expand Down
2 changes: 1 addition & 1 deletion net/atm/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos)
}

int vcc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
char __user *optval, unsigned int optlen)
{
struct atm_vcc *vcc;
unsigned long value;
Expand Down
2 changes: 1 addition & 1 deletion net/atm/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int vcc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen);
char __user *optval, unsigned int optlen);
int vcc_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen);

Expand Down
2 changes: 1 addition & 1 deletion net/atm/pvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
}

static int pvc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int error;
Expand Down
2 changes: 1 addition & 1 deletion net/atm/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)


static int svc_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct atm_vcc *vcc = ATM_SD(sock);
Expand Down
2 changes: 1 addition & 1 deletion net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void)
*/

static int ax25_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
char __user *optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
ax25_cb *ax25;
Expand Down
2 changes: 1 addition & 1 deletion net/bluetooth/hci_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto done;
}

static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len)
static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
{
struct hci_ufilter uf = { .opcode = 0 };
struct sock *sk = sock->sk;
Expand Down
Loading

0 comments on commit b705884

Please sign in to comment.