nfs: fix SMAP violation on write

also rewrite the fix on read for consistency.
should fix #17708

Change-Id: Ia75ed90ba427db7a7d96aff3457fbce61e857533
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5211
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Jérôme Duval 2022-04-18 11:25:49 +02:00 committed by waddlesplash
parent 9501bd1241
commit 0c729c2291
6 changed files with 56 additions and 33 deletions

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src add-ons kernel file_systems nfs ;
UsePrivateHeaders kernel ;
UsePrivateKernelHeaders ;
#SubDirCcFlags -DTRACK_FILENAME ;

View File

@ -1,9 +1,13 @@
#include "XDRInPacket.h"
#include <malloc.h>
#include <string.h>
#include <ByteOrder.h>
#include <KernelExport.h>
#include <kernel.h>
#include "nfs.h"
extern void
@ -29,26 +33,28 @@ XDRInPacketGetInt32(struct XDRInPacket *packet)
return val;
}
extern int32
status_t
XDRInPacketGetFixed(struct XDRInPacket *packet, void *buffer, size_t len)
{
if (user_memcpy(buffer, &packet->fBuffer[packet->fOffset], len)
!= B_OK) {
return NFSERR_IO;
}
if (!IS_USER_ADDRESS(buffer))
memcpy(buffer, &packet->fBuffer[packet->fOffset], len);
else if (user_memcpy(buffer, &packet->fBuffer[packet->fOffset], len) != B_OK)
return B_BAD_ADDRESS;
packet->fOffset += (len + 3) & ~3;
return NFS_OK;
return B_OK;
}
extern size_t
XDRInPacketGetDynamic(struct XDRInPacket *packet, void *buffer)
status_t
XDRInPacketGetDynamic(struct XDRInPacket *packet, void *buffer, size_t *len)
{
size_t size=XDRInPacketGetInt32(packet);
XDRInPacketGetFixed(packet,buffer,size);
return size;
*len = XDRInPacketGetInt32(packet);
return XDRInPacketGetFixed(packet, buffer, *len);
}
extern char *
XDRInPacketGetString(struct XDRInPacket *packet)
{

View File

@ -13,9 +13,8 @@ struct XDRInPacket
void XDRInPacketInit (struct XDRInPacket *packet);
void XDRInPacketDestroy (struct XDRInPacket *packet);
int32 XDRInPacketGetInt32 (struct XDRInPacket *packet);
int32 XDRInPacketGetFixed (struct XDRInPacket *packet, void *buffer,
size_t len);
size_t XDRInPacketGetDynamic (struct XDRInPacket *packet, void *buffer);
status_t XDRInPacketGetFixed (struct XDRInPacket *packet, void *buffer, size_t len);
status_t XDRInPacketGetDynamic (struct XDRInPacket *packet, void *buffer, size_t *_len);
char *XDRInPacketGetString (struct XDRInPacket *packet);
void XDRInPacketSetTo (struct XDRInPacket *packet, uint8 *buffer, size_t offset);

View File

@ -2,7 +2,12 @@
#include <malloc.h>
#include <string.h>
#include <ByteOrder.h>
#include <KernelExport.h>
#include <kernel.h>
extern const uint8 *
XDROutPacketBuffer(struct XDROutPacket *packet)
@ -49,29 +54,37 @@ XDROutPacketAddInt32(struct XDROutPacket *packet, int32 val)
packet->fLength+=4;
}
extern void
status_t
XDROutPacketAddDynamic(struct XDROutPacket *packet, const void *data, size_t size)
{
XDROutPacketAddInt32 (packet,size);
XDROutPacketAddFixed (packet,data,size);
XDROutPacketAddInt32(packet, size);
return XDROutPacketAddFixed(packet, data, size);
}
extern void
status_t
XDROutPacketAddFixed(struct XDROutPacket *packet, const void *data, size_t size)
{
size_t roundedSize=(size+3)&~3;
XDROutPacketGrow (packet,roundedSize);
memcpy (&packet->fBuffer[packet->fLength],data,size);
memset (&packet->fBuffer[packet->fLength+size],0,roundedSize-size);
packet->fLength+=roundedSize;
size_t roundedSize = (size + 3) & ~3;
XDROutPacketGrow(packet, roundedSize);
if (!IS_USER_ADDRESS(data))
memcpy(&packet->fBuffer[packet->fLength], data, size);
else if (user_memcpy(&packet->fBuffer[packet->fLength], data, size) != B_OK)
return B_BAD_ADDRESS;
memset(&packet->fBuffer[packet->fLength + size], 0, roundedSize - size);
packet->fLength += roundedSize;
return B_OK;
}
extern void
status_t
XDROutPacketAddString(struct XDROutPacket *packet, const char *string)
{
XDROutPacketAddDynamic(packet,string,strlen(string));
return XDROutPacketAddDynamic(packet, string, strlen(string));
}
extern void
XDROutPacketAppend(struct XDROutPacket *me, const struct XDROutPacket *packet)
{

View File

@ -18,9 +18,9 @@ void XDROutPacketDestroy (struct XDROutPacket *packet);
void XDROutPacketGrow (struct XDROutPacket *packet, size_t size);
void XDROutPacketAddInt32 (struct XDROutPacket *packet, int32 val);
void XDROutPacketAddDynamic (struct XDROutPacket *packet, const void *data, size_t size);
void XDROutPacketAddFixed (struct XDROutPacket *packet, const void *data, size_t size);
void XDROutPacketAddString (struct XDROutPacket *packet, const char *string);
status_t XDROutPacketAddDynamic (struct XDROutPacket *packet, const void *data, size_t size);
status_t XDROutPacketAddFixed (struct XDROutPacket *packet, const void *data, size_t size);
status_t XDROutPacketAddString (struct XDROutPacket *packet, const char *string);
void XDROutPacketAppend (struct XDROutPacket *me, const struct XDROutPacket *packet);
const uint8 *XDROutPacketBuffer (struct XDROutPacket *packet);

View File

@ -389,7 +389,8 @@ is_successful_reply(struct XDRInPacket *reply)
} else {
rpc_auth_flavor flavor = (rpc_auth_flavor)XDRInPacketGetInt32(reply);
char body[400];
size_t bodyLength = XDRInPacketGetDynamic(reply, body);
size_t bodyLength;
XDRInPacketGetDynamic(reply, body, &bodyLength);
rpc_accept_stat acceptStat = (rpc_accept_stat)XDRInPacketGetInt32(reply);
(void)flavor;
@ -1554,7 +1555,9 @@ fs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
get_nfs_attr(&reply, &st);
cookie->st = st;
readbytes = XDRInPacketGetDynamic(&reply, buf);
status_t err = XDRInPacketGetDynamic(&reply, buf, &readbytes);
if (err != B_OK)
return err;
buf = (char *)buf + readbytes;
(*len) += readbytes;
@ -1605,7 +1608,9 @@ fs_write(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
XDROutPacketAddInt32(&call, 0);
XDROutPacketAddInt32(&call, pos + bytesWritten);
XDROutPacketAddInt32(&call, 0);
XDROutPacketAddDynamic(&call, (const char *)buf + bytesWritten, count);
status_t err = XDROutPacketAddDynamic(&call, (const char *)buf + bytesWritten, count);
if (err != B_OK)
return err;
replyBuf = send_rpc_call(ns, &ns->nfsAddr, NFS_PROGRAM, NFS_VERSION,
NFSPROC_WRITE, &call);
@ -2309,7 +2314,7 @@ fs_readlink(fs_volume *_volume, fs_vnode *_node, char *buf, size_t *bufsize)
return map_nfs_to_system_error(status);
}
length = XDRInPacketGetDynamic(&reply, data);
XDRInPacketGetDynamic(&reply, data, &length);
memcpy(buf, data, min_c(length, *bufsize));
*bufsize = length;