lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 3 Mar 2010 13:51:28 -0000
From:	"Mike McTernan" <mmcternan@...vana.com>
To:	"Daniel Baluta" <daniel.baluta@...il.com>
Cc:	<linux-kernel@...r.kernel.org>
Subject: RE: do_loop_readv_writev() not as described for drivers implementing only write()?

Hi,

> I would say that the libc enforces atomicity, but I have to dig deeper
for
> a real answer :).

If libc did do it, it would have to be fancy since readv() and writev()
are documented as being atomic between processes, as well as threads.

Still, all things being possible, I visually checked the glibc I'm
using. 

glibc-2.8/sysdeps/unix/sysv/linux/writev.c:

ssize_t
__libc_writev (fd, vector, count)
     int fd;
     const struct iovec *vector;
     int count;
{
  if (SINGLE_THREAD_P)
    return do_writev (fd, vector, count);

  int oldtype = LIBC_CANCEL_ASYNC ();

  ssize_t result = do_writev (fd, vector, count);

  LIBC_CANCEL_RESET (oldtype);

  return result;
}

So we end up in do_writev(), which is defined in the same file:

static ssize_t
do_writev (int fd, const struct iovec *vector, int count)
{
  ssize_t bytes_written;

  bytes_written = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector,
count), count);

  if (bytes_written >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
    return bytes_written;

  return __atomic_writev_replacement (fd, vector, count);
}

So assuming the syscall to writev() returns >= 0 (which is true for my
driver), I can't see locking being provided here unless
LIBC_CANCEL_ASYNC is doing something spectacular which I've overlooked.

The other observation from this is that the kernel could detect a case
where writev() is not supported by a driver (i.e. write() is implemented
but aio_write() is not) and return -ENOSYS instead of calling
do_loop_readv_writev().  This would allow the libc to use it's
replacement function - __atomic_writev_replacement() in this case.  

How writev() correctly works is still a mystery to me at this point.

Regards,

Mike
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ