lkml.org 
[lkml]   [1998]   [Mar]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subjectpatch 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;
    \
     
     \ /
      Last update: 2005-03-22 13:41    [W:0.023 / U:90.292 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site