net/scm: cleanup scm_detach_fds
Factor out two helpes to keep the code tidy. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									0462b6bdb6
								
							
						
					
					
						commit
						2618d530dd
					
				| @ -277,78 +277,86 @@ void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_inter | ||||
| } | ||||
| EXPORT_SYMBOL(put_cmsg_scm_timestamping); | ||||
| 
 | ||||
| static int __scm_install_fd(struct file *file, int __user *ufd, int o_flags) | ||||
| { | ||||
| 	struct socket *sock; | ||||
| 	int new_fd; | ||||
| 	int error; | ||||
| 
 | ||||
| 	error = security_file_receive(file); | ||||
| 	if (error) | ||||
| 		return error; | ||||
| 
 | ||||
| 	new_fd = get_unused_fd_flags(o_flags); | ||||
| 	if (new_fd < 0) | ||||
| 		return new_fd; | ||||
| 
 | ||||
| 	error = put_user(new_fd, ufd); | ||||
| 	if (error) { | ||||
| 		put_unused_fd(new_fd); | ||||
| 		return error; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Bump the usage count and install the file. */ | ||||
| 	sock = sock_from_file(file, &error); | ||||
| 	if (sock) { | ||||
| 		sock_update_netprioidx(&sock->sk->sk_cgrp_data); | ||||
| 		sock_update_classid(&sock->sk->sk_cgrp_data); | ||||
| 	} | ||||
| 	fd_install(new_fd, get_file(file)); | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| static int scm_max_fds(struct msghdr *msg) | ||||
| { | ||||
| 	if (msg->msg_controllen <= sizeof(struct cmsghdr)) | ||||
| 		return 0; | ||||
| 	return (msg->msg_controllen - sizeof(struct cmsghdr)) / sizeof(int); | ||||
| } | ||||
| 
 | ||||
| void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | ||||
| { | ||||
| 	struct cmsghdr __user *cm | ||||
| 		= (__force struct cmsghdr __user*)msg->msg_control; | ||||
| 
 | ||||
| 	int fdmax = 0; | ||||
| 	int fdnum = scm->fp->count; | ||||
| 	struct file **fp = scm->fp->fp; | ||||
| 	int __user *cmfptr; | ||||
| 	int o_flags = (msg->msg_flags & MSG_CMSG_CLOEXEC) ? O_CLOEXEC : 0; | ||||
| 	int fdmax = min_t(int, scm_max_fds(msg), scm->fp->count); | ||||
| 	int __user *cmsg_data = CMSG_USER_DATA(cm); | ||||
| 	int err = 0, i; | ||||
| 
 | ||||
| 	if (MSG_CMSG_COMPAT & msg->msg_flags) { | ||||
| 	if (msg->msg_flags & MSG_CMSG_COMPAT) { | ||||
| 		scm_detach_fds_compat(msg, scm); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (msg->msg_controllen > sizeof(struct cmsghdr)) | ||||
| 		fdmax = ((msg->msg_controllen - sizeof(struct cmsghdr)) | ||||
| 			 / sizeof(int)); | ||||
| 
 | ||||
| 	if (fdnum < fdmax) | ||||
| 		fdmax = fdnum; | ||||
| 
 | ||||
| 	for (i=0, cmfptr =(int __user *)CMSG_USER_DATA(cm); i<fdmax; | ||||
| 	     i++, cmfptr++) | ||||
| 	{ | ||||
| 		struct socket *sock; | ||||
| 		int new_fd; | ||||
| 		err = security_file_receive(fp[i]); | ||||
| 	for (i = 0; i < fdmax; i++) { | ||||
| 		err = __scm_install_fd(scm->fp->fp[i], cmsg_data + i, o_flags); | ||||
| 		if (err) | ||||
| 			break; | ||||
| 		err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & msg->msg_flags | ||||
| 					  ? O_CLOEXEC : 0); | ||||
| 		if (err < 0) | ||||
| 			break; | ||||
| 		new_fd = err; | ||||
| 		err = put_user(new_fd, cmfptr); | ||||
| 		if (err) { | ||||
| 			put_unused_fd(new_fd); | ||||
| 			break; | ||||
| 		} | ||||
| 		/* Bump the usage count and install the file. */ | ||||
| 		sock = sock_from_file(fp[i], &err); | ||||
| 		if (sock) { | ||||
| 			sock_update_netprioidx(&sock->sk->sk_cgrp_data); | ||||
| 			sock_update_classid(&sock->sk->sk_cgrp_data); | ||||
| 		} | ||||
| 		fd_install(new_fd, get_file(fp[i])); | ||||
| 	} | ||||
| 
 | ||||
| 	if (i > 0) | ||||
| 	{ | ||||
| 		int cmlen = CMSG_LEN(i*sizeof(int)); | ||||
| 	if (i > 0)  { | ||||
| 		int cmlen = CMSG_LEN(i * sizeof(int)); | ||||
| 
 | ||||
| 		err = put_user(SOL_SOCKET, &cm->cmsg_level); | ||||
| 		if (!err) | ||||
| 			err = put_user(SCM_RIGHTS, &cm->cmsg_type); | ||||
| 		if (!err) | ||||
| 			err = put_user(cmlen, &cm->cmsg_len); | ||||
| 		if (!err) { | ||||
| 			cmlen = CMSG_SPACE(i*sizeof(int)); | ||||
| 			cmlen = CMSG_SPACE(i * sizeof(int)); | ||||
| 			if (msg->msg_controllen < cmlen) | ||||
| 				cmlen = msg->msg_controllen; | ||||
| 			msg->msg_control += cmlen; | ||||
| 			msg->msg_controllen -= cmlen; | ||||
| 		} | ||||
| 	} | ||||
| 	if (i < fdnum || (fdnum && fdmax <= 0)) | ||||
| 
 | ||||
| 	if (i < scm->fp->count || (scm->fp->count && fdmax <= 0)) | ||||
| 		msg->msg_flags |= MSG_CTRUNC; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * All of the files that fit in the message have had their | ||||
| 	 * usage counts incremented, so we just free the list. | ||||
| 	 * All of the files that fit in the message have had their usage counts | ||||
| 	 * incremented, so we just free the list. | ||||
| 	 */ | ||||
| 	__scm_destroy(scm); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user