Messages in this thread Patch in this message | | | Date | Mon, 02 Mar 1998 09:23:10 -0500 | From | Bill Hawes <> | Subject | patch for 2.1.89-5 net/core/scm.c |
| |
The attached patch against pre-2.1.89-5 for net/core/scm.c uses fget() to protect an access to the fd array, and fixes some error exits to avoid possible resource leaks.
The access to a socket file using the passed fd previously just returned a reference to the socket. Since the fd could be closed at any time and cause the sock pointer to become stale, I've used an fget() to hold a count on the file structure, and added the file pointer in the scm cookie structure to be freed after the last use.
The patch also changes the error exits for the CONNECT message to go through the cleanup error exit used by other failures. This will ensure that the resources (memory and file counts) get freed if a prior SCM_RIGHTS message has been processed and a later CONNECT message fails.
Regards, Bill--- include/net/scm.h Sun Jan 19 08:47:27 1997 +++ include/net/scm.h Sun Mar 1 11:56:37 1998 @@ -17,6 +17,7 @@ struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ unsigned long seq; /* Connection seqno */ + struct file *file; /* file for socket */ struct socket *sock; /* Passed socket */ }; --- net/core/scm.c Sun Mar 1 12:20:18 1998 +++ net/core/scm.c Sun Mar 1 11:53:11 1998 @@ -106,6 +106,7 @@ void __scm_destroy(struct scm_cookie *scm) { struct scm_fp_list *fpl = scm->fp; + struct file *file; int i; if (fpl) { @@ -114,6 +115,13 @@ fput(fpl->fp[i]); kfree(fpl); } + + file = scm->file; + if (file) { + scm->sock = NULL; + scm->file = NULL; + fput(file); + } } @@ -126,11 +134,10 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) { - int err; struct cmsghdr *cmsg; struct file *file; - int acc_fd; - unsigned scm_flags=0; + int acc_fd, err; + unsigned int scm_flags=0; for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { @@ -162,14 +169,19 @@ memcpy(&acc_fd, CMSG_DATA(cmsg), sizeof(int)); p->sock = NULL; if (acc_fd != -1) { - if (acc_fd < 0 || acc_fd >= NR_OPEN || - (file=current->files->fd[acc_fd])==NULL) - return -EBADF; - if (!file->f_dentry->d_inode || !file->f_dentry->d_inode->i_sock) - return -ENOTSOCK; + err = -EBADF; + file = fget(acc_fd); + if (!file) + goto error; + p->file = file; + err = -ENOTSOCK; + if (!file->f_dentry->d_inode || + !file->f_dentry->d_inode->i_sock) + goto error; p->sock = &file->f_dentry->d_inode->u.socket_i; + err = -EINVAL; if (p->sock->state != SS_UNCONNECTED) - return -EINVAL; + goto error; } scm_flags |= MSG_SYN; break; | |