mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
Fixed nasty bug where file writes with start offsets in the range
0x80000000 -> 0xFFFFFFFF would fail as they were being cast from IVAL (uint32) to SMB_OFF_T (off_t or off64_t, both *signed* types). The sign extension would cause the offset to be treated as negative. Thanks to Herb for helping me track this one down (IRIX is good for large file tests :-). Jeremy. PS. That horrid EXEXIST thing has broken configure.....
This commit is contained in:
parent
8c306804c6
commit
fc7d3faed7
@ -589,9 +589,11 @@ typedef int socklen_t;
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
#define SOFF_T(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
|
||||
#define SOFF_T_R(p, ofs, v) (SIVAL(p,(ofs)+4,(v)&0xFFFFFFFF), SIVAL(p,ofs,(v)>>32))
|
||||
#define IVAL_TO_SMB_OFF_T(buf,off) ((SMB_OFF_T)(( ((SMB_BIG_UINT)(IVAL((buf),(off)))) & ((SMB_BIG_UINT)0xFFFFFFFF) )))
|
||||
#else
|
||||
#define SOFF_T(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
|
||||
#define SOFF_T_R(p, ofs, v) (SIVAL(p,(ofs)+4,v),SIVAL(p,ofs,0))
|
||||
#define IVAL_TO_SMB_OFF_T(buf,off) ((SMB_OFF_T)(( ((uint32)(IVAL((buf),(off)))) & 0xFFFFFFFF )))
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -267,20 +267,20 @@ static BOOL process_lockread(blocking_lock_record *blr)
|
||||
ssize_t nread = -1;
|
||||
char *data, *p;
|
||||
int outsize = 0;
|
||||
SMB_OFF_T startpos;
|
||||
SMB_BIG_UINT startpos;
|
||||
size_t numtoread;
|
||||
NTSTATUS status;
|
||||
connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
|
||||
files_struct *fsp = blr->fsp;
|
||||
|
||||
numtoread = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2);
|
||||
|
||||
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
|
||||
data = smb_buf(outbuf) + 3;
|
||||
|
||||
status = do_lock_spin( fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)numtoread,
|
||||
(SMB_BIG_UINT)startpos, READ_LOCK);
|
||||
startpos, READ_LOCK);
|
||||
if (NT_STATUS_V(status)) {
|
||||
if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
|
||||
!NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
|
||||
@ -337,17 +337,17 @@ static BOOL process_lock(blocking_lock_record *blr)
|
||||
char *outbuf = OutBuffer;
|
||||
char *inbuf = blr->inbuf;
|
||||
int outsize;
|
||||
SMB_OFF_T count = 0, offset = 0;
|
||||
SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0;
|
||||
NTSTATUS status;
|
||||
connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
|
||||
files_struct *fsp = blr->fsp;
|
||||
|
||||
count = IVAL(inbuf,smb_vwv1);
|
||||
offset = IVAL(inbuf,smb_vwv3);
|
||||
count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
|
||||
offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
|
||||
errno = 0;
|
||||
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), (SMB_BIG_UINT)count,
|
||||
(SMB_BIG_UINT)offset, WRITE_LOCK);
|
||||
status = do_lock_spin(fsp, conn, SVAL(inbuf,smb_pid), count,
|
||||
offset, WRITE_LOCK);
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
|
||||
!NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
|
||||
|
@ -1304,9 +1304,9 @@ static int call_nt_transact_create(connection_struct *conn,
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
/* Save the requested allocation size. */
|
||||
allocation_size = IVAL(params,12);
|
||||
allocation_size = IVAL_TO_SMB_OFF_T(params,12);
|
||||
#ifdef LARGE_SMB_OFF_T
|
||||
allocation_size |= (((SMB_OFF_T)IVAL(params,16)) << 32);
|
||||
allocation_size |= ((IVAL_TO_SMB_OFF_T(params,16)) << 32);
|
||||
#endif
|
||||
if (allocation_size && (allocation_size > file_len)) {
|
||||
fsp->initial_allocation_size = SMB_ROUNDUP(allocation_size,SMB_ROUNDUP_ALLOCATION_SIZE);
|
||||
|
@ -1532,7 +1532,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
|
||||
|
||||
flush_write_cache(fsp, READRAW_FLUSH);
|
||||
|
||||
startpos = IVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
|
||||
if(CVAL(inbuf,smb_wct) == 10) {
|
||||
/*
|
||||
* This is a large offset (64 bit) read.
|
||||
@ -1627,7 +1627,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
|
||||
release_level_2_oplocks_on_change(fsp);
|
||||
|
||||
numtoread = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
|
||||
outsize = set_message(outbuf,5,3,True);
|
||||
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
|
||||
@ -1696,7 +1696,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
CHECK_READ(fsp);
|
||||
|
||||
numtoread = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
|
||||
outsize = set_message(outbuf,5,3,True);
|
||||
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
|
||||
@ -1822,7 +1822,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
|
||||
int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
|
||||
{
|
||||
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
|
||||
SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
|
||||
SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
ssize_t nread = -1;
|
||||
size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
|
||||
#if 0
|
||||
@ -1900,7 +1900,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
CHECK_WRITE(fsp);
|
||||
|
||||
tcount = IVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv3);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
write_through = BITSETW(inbuf+smb_vwv7,0);
|
||||
|
||||
/* We have to deal with slightly different formats depending
|
||||
@ -2030,7 +2030,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
|
||||
CHECK_WRITE(fsp);
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
data = smb_buf(inbuf) + 3;
|
||||
|
||||
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
|
||||
@ -2097,7 +2097,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
|
||||
CHECK_WRITE(fsp);
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
data = smb_buf(inbuf) + 3;
|
||||
|
||||
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
|
||||
@ -2158,7 +2158,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
|
||||
int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
|
||||
{
|
||||
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
|
||||
SMB_OFF_T startpos = IVAL(inbuf,smb_vwv3);
|
||||
SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
size_t numtowrite = SVAL(inbuf,smb_vwv10);
|
||||
BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
|
||||
ssize_t nwritten = -1;
|
||||
@ -2269,7 +2269,8 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
|
||||
flush_write_cache(fsp, SEEK_FLUSH);
|
||||
|
||||
mode = SVAL(inbuf,smb_vwv1) & 3;
|
||||
startpos = IVALS(inbuf,smb_vwv2);
|
||||
/* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
|
||||
startpos = (SMB_OFF_T)IVALS(inbuf,smb_vwv2);
|
||||
|
||||
switch (mode) {
|
||||
case 0: umode = SEEK_SET; break;
|
||||
@ -2478,7 +2479,7 @@ int reply_writeclose(connection_struct *conn,
|
||||
CHECK_WRITE(fsp);
|
||||
|
||||
numtowrite = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
mtime = make_unix_date3(inbuf+smb_vwv4);
|
||||
data = smb_buf(inbuf) + 1;
|
||||
|
||||
@ -4056,7 +4057,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
|
||||
CHECK_FSP(fsp,conn);
|
||||
CHECK_READ(fsp);
|
||||
|
||||
startpos = IVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
|
||||
maxcount = SVAL(inbuf,smb_vwv3);
|
||||
|
||||
data = smb_buf(outbuf);
|
||||
@ -4184,7 +4185,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
||||
CHECK_ERROR(fsp);
|
||||
|
||||
tcount = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv3);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
|
||||
write_through = BITSETW(inbuf+smb_vwv7,0);
|
||||
numtowrite = SVAL(inbuf,smb_vwv10);
|
||||
smb_doff = SVAL(inbuf,smb_vwv11);
|
||||
@ -4284,7 +4285,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
|
||||
CHECK_WRITE(fsp);
|
||||
|
||||
tcount = SVAL(inbuf,smb_vwv1);
|
||||
startpos = IVAL(inbuf,smb_vwv2);
|
||||
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
|
||||
numtowrite = SVAL(inbuf,smb_vwv6);
|
||||
smb_doff = SVAL(inbuf,smb_vwv7);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user