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 <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
9501bd1241
commit
0c729c2291
@@ -1,6 +1,6 @@
|
|||||||
SubDir HAIKU_TOP src add-ons kernel file_systems nfs ;
|
SubDir HAIKU_TOP src add-ons kernel file_systems nfs ;
|
||||||
|
|
||||||
UsePrivateHeaders kernel ;
|
UsePrivateKernelHeaders ;
|
||||||
|
|
||||||
#SubDirCcFlags -DTRACK_FILENAME ;
|
#SubDirCcFlags -DTRACK_FILENAME ;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#include "XDRInPacket.h"
|
#include "XDRInPacket.h"
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
#include "nfs.h"
|
#include "nfs.h"
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
@@ -29,26 +33,28 @@ XDRInPacketGetInt32(struct XDRInPacket *packet)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int32
|
|
||||||
|
status_t
|
||||||
XDRInPacketGetFixed(struct XDRInPacket *packet, void *buffer, size_t len)
|
XDRInPacketGetFixed(struct XDRInPacket *packet, void *buffer, size_t len)
|
||||||
{
|
{
|
||||||
if (user_memcpy(buffer, &packet->fBuffer[packet->fOffset], len)
|
if (!IS_USER_ADDRESS(buffer))
|
||||||
!= B_OK) {
|
memcpy(buffer, &packet->fBuffer[packet->fOffset], len);
|
||||||
return NFSERR_IO;
|
else if (user_memcpy(buffer, &packet->fBuffer[packet->fOffset], len) != B_OK)
|
||||||
}
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
packet->fOffset += (len + 3) & ~3;
|
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);
|
*len = XDRInPacketGetInt32(packet);
|
||||||
XDRInPacketGetFixed(packet,buffer,size);
|
return XDRInPacketGetFixed(packet, buffer, *len);
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern char *
|
extern char *
|
||||||
XDRInPacketGetString(struct XDRInPacket *packet)
|
XDRInPacketGetString(struct XDRInPacket *packet)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ struct XDRInPacket
|
|||||||
void XDRInPacketInit (struct XDRInPacket *packet);
|
void XDRInPacketInit (struct XDRInPacket *packet);
|
||||||
void XDRInPacketDestroy (struct XDRInPacket *packet);
|
void XDRInPacketDestroy (struct XDRInPacket *packet);
|
||||||
int32 XDRInPacketGetInt32 (struct XDRInPacket *packet);
|
int32 XDRInPacketGetInt32 (struct XDRInPacket *packet);
|
||||||
int32 XDRInPacketGetFixed (struct XDRInPacket *packet, void *buffer,
|
status_t XDRInPacketGetFixed (struct XDRInPacket *packet, void *buffer, size_t len);
|
||||||
size_t len);
|
status_t XDRInPacketGetDynamic (struct XDRInPacket *packet, void *buffer, size_t *_len);
|
||||||
size_t XDRInPacketGetDynamic (struct XDRInPacket *packet, void *buffer);
|
|
||||||
char *XDRInPacketGetString (struct XDRInPacket *packet);
|
char *XDRInPacketGetString (struct XDRInPacket *packet);
|
||||||
void XDRInPacketSetTo (struct XDRInPacket *packet, uint8 *buffer, size_t offset);
|
void XDRInPacketSetTo (struct XDRInPacket *packet, uint8 *buffer, size_t offset);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
|
||||||
extern const uint8 *
|
extern const uint8 *
|
||||||
XDROutPacketBuffer(struct XDROutPacket *packet)
|
XDROutPacketBuffer(struct XDROutPacket *packet)
|
||||||
@@ -49,29 +54,37 @@ XDROutPacketAddInt32(struct XDROutPacket *packet, int32 val)
|
|||||||
packet->fLength+=4;
|
packet->fLength+=4;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void
|
|
||||||
|
status_t
|
||||||
XDROutPacketAddDynamic(struct XDROutPacket *packet, const void *data, size_t size)
|
XDROutPacketAddDynamic(struct XDROutPacket *packet, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
XDROutPacketAddInt32 (packet,size);
|
XDROutPacketAddInt32(packet, size);
|
||||||
XDROutPacketAddFixed (packet,data,size);
|
return XDROutPacketAddFixed(packet, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void
|
|
||||||
|
status_t
|
||||||
XDROutPacketAddFixed(struct XDROutPacket *packet, const void *data, size_t size)
|
XDROutPacketAddFixed(struct XDROutPacket *packet, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
size_t roundedSize=(size+3)&~3;
|
size_t roundedSize = (size + 3) & ~3;
|
||||||
XDROutPacketGrow (packet,roundedSize);
|
XDROutPacketGrow(packet, roundedSize);
|
||||||
memcpy (&packet->fBuffer[packet->fLength],data,size);
|
if (!IS_USER_ADDRESS(data))
|
||||||
memset (&packet->fBuffer[packet->fLength+size],0,roundedSize-size);
|
memcpy(&packet->fBuffer[packet->fLength], data, size);
|
||||||
packet->fLength+=roundedSize;
|
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)
|
XDROutPacketAddString(struct XDROutPacket *packet, const char *string)
|
||||||
{
|
{
|
||||||
XDROutPacketAddDynamic(packet,string,strlen(string));
|
return XDROutPacketAddDynamic(packet, string, strlen(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
XDROutPacketAppend(struct XDROutPacket *me, const struct XDROutPacket *packet)
|
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 XDROutPacketGrow (struct XDROutPacket *packet, size_t size);
|
||||||
void XDROutPacketAddInt32 (struct XDROutPacket *packet, int32 val);
|
void XDROutPacketAddInt32 (struct XDROutPacket *packet, int32 val);
|
||||||
void XDROutPacketAddDynamic (struct XDROutPacket *packet, const void *data, size_t size);
|
status_t XDROutPacketAddDynamic (struct XDROutPacket *packet, const void *data, size_t size);
|
||||||
void XDROutPacketAddFixed (struct XDROutPacket *packet, const void *data, size_t size);
|
status_t XDROutPacketAddFixed (struct XDROutPacket *packet, const void *data, size_t size);
|
||||||
void XDROutPacketAddString (struct XDROutPacket *packet, const char *string);
|
status_t XDROutPacketAddString (struct XDROutPacket *packet, const char *string);
|
||||||
void XDROutPacketAppend (struct XDROutPacket *me, const struct XDROutPacket *packet);
|
void XDROutPacketAppend (struct XDROutPacket *me, const struct XDROutPacket *packet);
|
||||||
|
|
||||||
const uint8 *XDROutPacketBuffer (struct XDROutPacket *packet);
|
const uint8 *XDROutPacketBuffer (struct XDROutPacket *packet);
|
||||||
|
|||||||
@@ -389,7 +389,8 @@ is_successful_reply(struct XDRInPacket *reply)
|
|||||||
} else {
|
} else {
|
||||||
rpc_auth_flavor flavor = (rpc_auth_flavor)XDRInPacketGetInt32(reply);
|
rpc_auth_flavor flavor = (rpc_auth_flavor)XDRInPacketGetInt32(reply);
|
||||||
char body[400];
|
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);
|
rpc_accept_stat acceptStat = (rpc_accept_stat)XDRInPacketGetInt32(reply);
|
||||||
(void)flavor;
|
(void)flavor;
|
||||||
@@ -1554,7 +1555,9 @@ fs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
|
|||||||
get_nfs_attr(&reply, &st);
|
get_nfs_attr(&reply, &st);
|
||||||
cookie->st = 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;
|
buf = (char *)buf + readbytes;
|
||||||
(*len) += 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, 0);
|
||||||
XDROutPacketAddInt32(&call, pos + bytesWritten);
|
XDROutPacketAddInt32(&call, pos + bytesWritten);
|
||||||
XDROutPacketAddInt32(&call, 0);
|
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,
|
replyBuf = send_rpc_call(ns, &ns->nfsAddr, NFS_PROGRAM, NFS_VERSION,
|
||||||
NFSPROC_WRITE, &call);
|
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);
|
return map_nfs_to_system_error(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
length = XDRInPacketGetDynamic(&reply, data);
|
XDRInPacketGetDynamic(&reply, data, &length);
|
||||||
|
|
||||||
memcpy(buf, data, min_c(length, *bufsize));
|
memcpy(buf, data, min_c(length, *bufsize));
|
||||||
*bufsize = length;
|
*bufsize = length;
|
||||||
|
|||||||
Reference in New Issue
Block a user