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:
parent
9501bd1241
commit
0c729c2291
@ -1,6 +1,6 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel file_systems nfs ;
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
UsePrivateKernelHeaders ;
|
||||
|
||||
#SubDirCcFlags -DTRACK_FILENAME ;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user