~ubuntu-branches/ubuntu/karmic/postfix/karmic-security

« back to all changes in this revision

Viewing changes to src/util/safe_open.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Berg
  • Date: 2008-09-07 14:02:15 UTC
  • mfrom: (29.1.21 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080907140215-d9zf8bj803ditke5
Tags: 2.5.5-1.1
* Non-maintainer upload.
* Add rsyslog.d config snipped to create a /dev/log syslog socket in the
  postfix chroot.  Also, add a note about other syslog daemons to
  README.Debian.  Closes: #311812

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
#include <msg.h>
84
84
#include <vstream.h>
85
85
#include <vstring.h>
 
86
#include <stringops.h>
86
87
#include <safe_open.h>
87
88
 
88
89
/* safe_open_exist - open existing file */
138
139
     * for symlinks owned by root. NEVER, NEVER, make exceptions for symlinks
139
140
     * owned by a non-root user. This would open a security hole when
140
141
     * delivering mail to a world-writable mailbox directory.
 
142
     * 
 
143
     * Sebastian Krahmer of SuSE brought to my attention that some systems have
 
144
     * changed their semantics of link(symlink, newpath), such that the
 
145
     * result is a hardlink to the symlink. For this reason, we now also
 
146
     * require that the symlink's parent directory is writable only by root.
141
147
     */
142
148
    else if (lstat(path, &lstat_st) < 0) {
143
149
        vstring_sprintf(why, "file status changed unexpectedly: %m");
144
150
        errno = EPERM;
145
151
    } else if (S_ISLNK(lstat_st.st_mode)) {
146
 
        if (lstat_st.st_uid == 0)
147
 
            return (fp);
 
152
        if (lstat_st.st_uid == 0) {
 
153
            VSTRING *parent_buf = vstring_alloc(100);
 
154
            const char *parent_path = sane_dirname(parent_buf, path);
 
155
            struct stat parent_st;
 
156
            int     parent_ok;
 
157
 
 
158
            parent_ok = (stat(parent_path, &parent_st) == 0     /* not lstat */
 
159
                         && parent_st.st_uid == 0
 
160
                         && (parent_st.st_mode & (S_IWGRP | S_IWOTH)) == 0);
 
161
            vstring_free(parent_buf);
 
162
            if (parent_ok)
 
163
                return (fp);
 
164
        }
148
165
        vstring_sprintf(why, "file is a symbolic link");
149
166
        errno = EPERM;
150
167
    } else if (fstat_st->st_dev != lstat_st.st_dev