]> granicus.if.org Git - sudo/commitdiff
Use pread(2) and pwrite(2) where possible.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 7 Sep 2015 12:06:08 +0000 (06:06 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 7 Sep 2015 12:06:08 +0000 (06:06 -0600)
config.h.in
configure
configure.ac
plugins/sudoers/iolog.c
plugins/sudoers/timestamp.c

index 85ecf5db75b11db82b00537f0baa6a2949233745..2635a0ffcf2cb48d1c57a706050da7792bfdb458 100644 (file)
 /* Define to 1 if you have the `posix_spawnp' function. */
 #undef HAVE_POSIX_SPAWNP
 
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
 /* Define to 1 if you have the `priv_set' function. */
 #undef HAVE_PRIV_SET
 
 /* Define to 1 if you have the <pty.h> header file. */
 #undef HAVE_PTY_H
 
+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
 /* Define to 1 if you have the `pw_dup' function. */
 #undef HAVE_PW_DUP
 
index a600d7c1aa4a54ae5db0126d4694739fab2d7b82..147df43173317598b7f72f32875dfd1bd86fadc4 100755 (executable)
--- a/configure
+++ b/configure
@@ -2653,6 +2653,8 @@ as_fn_append ac_header_list " sys/sysmacros.h"
 as_fn_append ac_func_list " killpg"
 as_fn_append ac_func_list " nl_langinfo"
 as_fn_append ac_func_list " strftime"
+as_fn_append ac_func_list " pread"
+as_fn_append ac_func_list " pwrite"
 as_fn_append ac_func_list " seteuid"
 # Check that the precious variables saved in the cache have kept the same
 # value.
@@ -18084,6 +18086,10 @@ done
 
 
 
+
+
+
+
 for ac_func in getgrouplist
 do :
   ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist"
index a997e91306975ac8ec1016ce195ddbf02d260bfb..a287d948ab764492b77c75bb5eadc00e7f597813 100644 (file)
@@ -2389,7 +2389,7 @@ dnl
 dnl Function checks
 dnl
 AC_FUNC_GETGROUPS
-AC_CHECK_FUNCS_ONCE([killpg nl_langinfo strftime])
+AC_CHECK_FUNCS_ONCE([killpg nl_langinfo strftime pread pwrite])
 AC_CHECK_FUNCS([getgrouplist], [], [
     case "$host_os" in
     aix*)
index 9a4f97c786af25f033c64490a6ee3df232f36df2..c7b4584cda4c3a6a47ed01f47ec497a34eeee22a 100644 (file)
@@ -269,7 +269,11 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
     sessid[6] = '\0';
 
     /* Rewind and overwrite old seq file, including the NUL byte. */
-    if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7) {
+#ifdef HAVE_PWRITE
+    if (pwrite(fd, buf, 7, 0) != 7) {
+#else
+    if (lseek(fd, 0, SEEK_SET) == -1 || write(fd, buf, 7) != 7) {
+#endif
        log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf);
        debug_return_bool(false);
     }
index 307f0332129458d31cc6bc02046318cd508f003f..5f838cab041bfac9af986c00fa75669aeea68f16 100644 (file)
@@ -61,8 +61,6 @@
  * The TS_LOCKEXCL entry must be unlocked before locking the actual record.
  */
 
-/* TODO: use pread/pwrite when possible */
-
 struct ts_cookie {
     char *fname;
     int fd;
@@ -274,14 +272,29 @@ ts_open(const char *path, int flags)
 }
 
 static ssize_t
-ts_write(int fd, const char *fname, struct timestamp_entry *entry)
+ts_write(int fd, const char *fname, struct timestamp_entry *entry, off_t offset)
 {
     ssize_t nwritten;
     off_t old_eof;
     debug_decl(ts_write, SUDOERS_DEBUG_AUTH)
 
-    old_eof = lseek(fd, (off_t)0, SEEK_CUR);
-    nwritten = write(fd, entry, entry->size);
+    if (offset == -1) {
+       old_eof = lseek(fd, 0, SEEK_CUR);
+       nwritten = write(fd, entry, entry->size);
+    } else {
+       old_eof = offset;
+#ifdef HAVE_PWRITE
+       nwritten = pwrite(fd, entry, entry->size, offset);
+#else
+       if (lseek(fd, offset, SEEK_SET) == -1) {
+           sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+               "unable to seek to %lld", offset);
+           nwritten = -1;
+       } else {
+           nwritten = write(fd, entry, entry->size);
+       }
+#endif
+    }
     if ((size_t)nwritten != entry->size) {
        if (nwritten == -1) {
            log_warning(SLOG_SEND_MAIL,
@@ -500,12 +513,16 @@ ts_read(struct ts_cookie *cookie, struct timestamp_entry *entry)
     }
 
     /* Seek to the record position and read it.  */
+#ifdef HAVE_PREAD
+    nread = pread(cookie->fd, entry, sizeof(*entry), cookie->pos);
+#else
     if (lseek(cookie->fd, cookie->pos, SEEK_SET) == -1) {
        sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
            "unable to seek to %lld", (long long)cookie->pos);
        goto done;
     }
     nread = read(cookie->fd, entry, sizeof(*entry));
+#endif
     if (nread != sizeof(*entry)) {
        /* short read, should not happen */
        sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
@@ -559,14 +576,14 @@ timestamp_lock(void *vcookie, struct passwd *pw)
        entry.version = TS_VERSION;
        entry.size = sizeof(entry);
        entry.type = TS_LOCKEXCL;
-       if (ts_write(cookie->fd, cookie->fname, &entry) == -1)
+       if (ts_write(cookie->fd, cookie->fname, &entry, -1) == -1)
            debug_return_bool(false);
     } else if (entry.type != TS_LOCKEXCL) {
        /* Old sudo record, convert it to TS_LOCKEXCL. */
        entry.type = TS_LOCKEXCL;
        memset((char *)&entry + offsetof(struct timestamp_entry, type), 0,
            nread - offsetof(struct timestamp_entry, type));
-       if (ts_write(cookie->fd, cookie->fname, &entry) == -1)
+       if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1)
            debug_return_bool(false);
     }
 
@@ -582,7 +599,7 @@ timestamp_lock(void *vcookie, struct passwd *pw)
        sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
            "appending new tty time stamp record");
        lock_pos = lseek(cookie->fd, 0, SEEK_CUR);
-       if (ts_write(cookie->fd, cookie->fname, &cookie->key) == -1)
+       if (ts_write(cookie->fd, cookie->fname, &cookie->key, -1) == -1)
            debug_return_bool(false);
     }
     sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
@@ -607,9 +624,9 @@ timestamp_lock(void *vcookie, struct passwd *pw)
            cookie->pos = lseek(cookie->fd, 0, SEEK_CUR) - (off_t)entry.size;
        } else {
            sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
-               "appending new globbal record");
+               "appending new global record");
            cookie->pos = lseek(cookie->fd, 0, SEEK_CUR);
-           if (ts_write(cookie->fd, cookie->fname, &cookie->key) == -1)
+           if (ts_write(cookie->fd, cookie->fname, &cookie->key, -1) == -1)
                debug_return_bool(false);
        }
     }
@@ -724,7 +741,7 @@ timestamp_status(void *vcookie, struct passwd *pw)
                N_("ignoring time stamp from the future"));
            status = TS_OLD;
            SET(entry.flags, TS_DISABLED);
-           ts_write(cookie->fd, cookie->fname, &entry);
+           ts_write(cookie->fd, cookie->fname, &entry, cookie->pos);
        }
 #else
        /* Check for bogus (future) time in the stampfile. */
@@ -737,7 +754,7 @@ timestamp_status(void *vcookie, struct passwd *pw)
                4 + ctime(&tv_sec));
            status = TS_OLD;
            SET(entry.flags, TS_DISABLED);
-           ts_write(cookie->fd, cookie->fname, &entry);
+           ts_write(cookie->fd, cookie->fname, &entry, cookie->pos);
        }
 #endif /* CLOCK_MONOTONIC */
     } else {
@@ -779,15 +796,10 @@ timestamp_update(void *vcookie, struct passwd *pw)
     }
 
     /* Write out the locked record. */
-    if (lseek(cookie->fd, cookie->pos, SEEK_SET) == -1) {
-       sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
-           "unable to seek to %lld", (long long)cookie->pos);
-       goto done;
-    }
     sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
        "writing %zu byte record at %lld", sizeof(cookie->key),
        (long long)cookie->pos);
-    if (ts_write(cookie->fd, cookie->fname, &cookie->key) != -1)
+    if (ts_write(cookie->fd, cookie->fname, &cookie->key, cookie->pos) != -1)
        rval = true;
 
 done:
@@ -845,9 +857,9 @@ timestamp_remove(bool unlink_it)
     while (ts_find_record(fd, &key, &entry)) {
        /* Back up and disable the entry. */
        if (!ISSET(entry.flags, TS_DISABLED)) {
-           lseek(fd, (off_t)0 - sizeof(entry), SEEK_CUR);
            SET(entry.flags, TS_DISABLED);
-           if (ts_write(fd, fname, &entry) == -1)
+           lseek(fd, 0 - sizeof(entry), SEEK_CUR);
+           if (ts_write(fd, fname, &entry, -1) == -1)
                rval = false;
        }
     }