[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Nbd] nbd-client: bug in passing flags?



nbd-server passes flags in 2 octets.

               smallflags = (uint16_t)(flags & ~((uint16_t)0));
               smallflags = htons(smallflags);
if (write(client->net, &smallflags, sizeof(smallflags)) < 0) {
                       err("Negotiation failed: %m");

That takes the least significant two bytes of flags, converts to
network order, and writes to the net.

nbd-client reads these in negotiate() as follows:
void negotiate(int sock, u64 *rsize64, u32 *flags, char* name) {
...
       if(name) {
...
               *flags = ((u32)ntohs(tmp)) << 16;
...
	}
...
       if(!name) {
               if (read(sock, flags, sizeof(*flags)) < 0)
                       err("Failed/4: %m\n");
               *flags = ntohl(*flags);
       } ...

The first assignment (line 153) converts back to host order and
puts the flags in the top 2 bytes (host order) of flags (<<16).

However, line 215 does
 int read_only = (flags & NBD_FLAG_READ_ONLY) ? 1 : 0;

NBD_FLAG_READ_ONLY is 1<<0, which means this can never be set
if the first evaluation (line 215) is done.

I think the "<< 16" on line 215 is superfluous. The flags should
simply be converted to host order, and assigned to "flags", so
they will live in least significant two bytes (where they came
from).

--
Alex Bligh



Reply to: