mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	[NET]: Fix function put_cmsg() which may cause usr application memory overflow
When used function put_cmsg() to copy kernel information to user 
application memory, if the memory length given by user application is 
not enough, by the bad length calculate of msg.msg_controllen, 
put_cmsg() function may cause the msg.msg_controllen to be a large 
value, such as 0xFFFFFFF0, so the following put_cmsg() can also write 
data to usr application memory even usr has no valid memory to store 
this. This may cause usr application memory overflow.
int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
{
    struct cmsghdr __user *cm
        = (__force struct cmsghdr __user *)msg->msg_control;
    struct cmsghdr cmhdr;
    int cmlen = CMSG_LEN(len);
    ~~~~~~~~~~~~~~~~~~~~~
    int err;
    if (MSG_CMSG_COMPAT & msg->msg_flags)
        return put_cmsg_compat(msg, level, type, len, data);
    if (cm==NULL || msg->msg_controllen < sizeof(*cm)) {
        msg->msg_flags |= MSG_CTRUNC;
        return 0; /* XXX: return error? check spec. */
    }
    if (msg->msg_controllen < cmlen) {
    ~~~~~~~~~~~~~~~~~~~~~~~~
        msg->msg_flags |= MSG_CTRUNC;
        cmlen = msg->msg_controllen;
    }
    cmhdr.cmsg_level = level;
    cmhdr.cmsg_type = type;
    cmhdr.cmsg_len = cmlen;
    err = -EFAULT;
    if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
        goto out;
    if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
        goto out;
    cmlen = CMSG_SPACE(len);
~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If MSG_CTRUNC flags is set, msg->msg_controllen is less than 
CMSG_SPACE(len), "msg->msg_controllen -= cmlen" will cause unsinged int 
type msg->msg_controllen to be a large value.
~~~~~~~~~~~~~~~~~~~~~~~~~~~
    msg->msg_control += cmlen;
    msg->msg_controllen -= cmlen;
    ~~~~~~~~~~~~~~~~~~~~~
    err = 0;
out:
    return err;
}
The same promble exists in put_cmsg_compat(). This patch can fix this 
problem.
Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									c5c0f33d8e
								
							
						
					
					
						commit
						1ac70e7ad2
					
				
					 2 changed files with 4 additions and 0 deletions
				
			
		| 
						 | 
					@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *dat
 | 
				
			||||||
	if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
 | 
						if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
 | 
				
			||||||
		return -EFAULT;
 | 
							return -EFAULT;
 | 
				
			||||||
	cmlen = CMSG_COMPAT_SPACE(len);
 | 
						cmlen = CMSG_COMPAT_SPACE(len);
 | 
				
			||||||
 | 
						if (kmsg->msg_controllen < cmlen)
 | 
				
			||||||
 | 
							cmlen = kmsg->msg_controllen;
 | 
				
			||||||
	kmsg->msg_control += cmlen;
 | 
						kmsg->msg_control += cmlen;
 | 
				
			||||||
	kmsg->msg_controllen -= cmlen;
 | 
						kmsg->msg_controllen -= cmlen;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
 | 
				
			||||||
	if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
 | 
						if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	cmlen = CMSG_SPACE(len);
 | 
						cmlen = CMSG_SPACE(len);
 | 
				
			||||||
 | 
						if (msg->msg_controllen < cmlen)
 | 
				
			||||||
 | 
							cmlen = msg->msg_controllen;
 | 
				
			||||||
	msg->msg_control += cmlen;
 | 
						msg->msg_control += cmlen;
 | 
				
			||||||
	msg->msg_controllen -= cmlen;
 | 
						msg->msg_controllen -= cmlen;
 | 
				
			||||||
	err = 0;
 | 
						err = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue