Add samba3.samba3badnameblob test to check regressions in bug #9215.
authorJeremy Allison <jra@samba.org>
Fri, 28 Sep 2012 16:39:15 +0000 (09:39 -0700)
committerJeremy Allison <jra@samba.org>
Mon, 1 Oct 2012 21:29:25 +0000 (23:29 +0200)
Bad name in SMB1 openX can cause a crash in iconv inside glibc.

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Oct  1 23:29:25 CEST 2012 on sn-devel-104

source3/selftest/tests.py
source4/torture/raw/raw.c
source4/torture/raw/samba3misc.c

index b07b69086c6e7127fcc12ce0c57139b0d426215c..7168bfd327c34907f78bb8e241dae741160a25e2 100755 (executable)
@@ -281,7 +281,7 @@ raw = ["raw.acls", "raw.chkpath", "raw.close", "raw.composite", "raw.context", "
        "raw.samba3caseinsensitive", "raw.samba3posixtimedlock",
        "raw.samba3rootdirfid", "raw.sfileinfo.end-of-file",
        "raw.bench-oplock", "raw.bench-lock", "raw.bench-open", "raw.bench-tcon",
-       "raw.samba3checkfsp", "raw.samba3closeerr", "raw.samba3oplocklogoff"]
+       "raw.samba3checkfsp", "raw.samba3closeerr", "raw.samba3oplocklogoff", "raw.samba3badnameblob"]
 
 smb2 = smb4torture_testsuites("smb2.")
 
index 9686efa80cd10dcc0833884333f82c6ca399b547..bda463b8a7239e598b89e073cdd941d493178640 100644 (file)
@@ -69,6 +69,7 @@ NTSTATUS torture_raw_init(void)
                                      torture_samba3_rootdirfid);
        torture_suite_add_1smb_test(suite, "samba3checkfsp", torture_samba3_checkfsp);
        torture_suite_add_1smb_test(suite, "samba3oplocklogoff", torture_samba3_oplock_logoff);
+       torture_suite_add_1smb_test(suite, "samba3badnameblob", torture_samba3_check_openX_badname);
        torture_suite_add_simple_test(suite, "samba3badpath", torture_samba3_badpath);
        torture_suite_add_1smb_test(suite, "samba3caseinsensitive",
                                      torture_samba3_caseinsensitive);
index 200438588e4b4322081674455d0ae9d4772ace90..a818c6bb48413b5fb27337feb153fc88ef32ad68 100644 (file)
 #include "param/param.h"
 #include "torture/raw/proto.h"
 
+/*
+ The next 2 functions are stolen from source4/libcli/raw/rawfile.c
+ but allow us to send a raw data blob instead of an OpenX name.
+*/
+
+#define SETUP_REQUEST(cmd, wct, buflen) do { \
+        req = smbcli_request_setup(tree, cmd, wct, buflen); \
+        if (!req) return NULL; \
+} while (0)
+
+static struct smbcli_request *smb_raw_openX_name_blob_send(struct smbcli_tree *tree,
+                                       union smb_open *parms,
+                                       const DATA_BLOB *pname_blob)
+{
+        struct smbcli_request *req = NULL;
+
+       if (parms->generic.level != RAW_OPEN_OPENX) {
+               return NULL;
+       }
+
+       SETUP_REQUEST(SMBopenX, 15, 0);
+       SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+       SSVAL(req->out.vwv, VWV(1), 0);
+       SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
+       SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
+       SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
+       SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
+       raw_push_dos_date3(tree->session->transport,
+                       req->out.vwv, VWV(6), parms->openx.in.write_time);
+       SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
+       SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
+       SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
+       SIVAL(req->out.vwv, VWV(13),0); /* reserved */
+       smbcli_req_append_blob(req, pname_blob);
+
+       if (!smbcli_request_send(req)) {
+               smbcli_request_destroy(req);
+               return NULL;
+       }
+
+       return req;
+}
+
+static NTSTATUS smb_raw_openX_name_blob(struct smbcli_tree *tree,
+                       TALLOC_CTX *mem_ctx,
+                       union smb_open *parms,
+                       const DATA_BLOB *pname_blob)
+{
+       struct smbcli_request *req = smb_raw_openX_name_blob_send(tree, parms, pname_blob);
+       return smb_raw_open_recv(req, mem_ctx, parms);
+}
+
+static NTSTATUS raw_smbcli_openX_name_blob(struct smbcli_tree *tree,
+                               const DATA_BLOB *pname_blob,
+                               int flags,
+                               int share_mode,
+                               int *fnum)
+{
+        union smb_open open_parms;
+        unsigned int openfn=0;
+        unsigned int accessmode=0;
+        TALLOC_CTX *mem_ctx;
+        NTSTATUS status;
+
+        mem_ctx = talloc_init("raw_openX_name_blob");
+        if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+
+        if (flags & O_CREAT) {
+                openfn |= OPENX_OPEN_FUNC_CREATE;
+        }
+        if (!(flags & O_EXCL)) {
+                if (flags & O_TRUNC) {
+                        openfn |= OPENX_OPEN_FUNC_TRUNC;
+                } else {
+                        openfn |= OPENX_OPEN_FUNC_OPEN;
+                }
+        }
+
+        accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
+
+        if ((flags & O_ACCMODE) == O_RDWR) {
+                accessmode |= OPENX_MODE_ACCESS_RDWR;
+        } else if ((flags & O_ACCMODE) == O_WRONLY) {
+                accessmode |= OPENX_MODE_ACCESS_WRITE;
+        } else if ((flags & O_ACCMODE) == O_RDONLY) {
+                accessmode |= OPENX_MODE_ACCESS_READ;
+       }
+
+#if defined(O_SYNC)
+        if ((flags & O_SYNC) == O_SYNC) {
+                accessmode |= OPENX_MODE_WRITE_THRU;
+        }
+#endif
+
+        if (share_mode == DENY_FCB) {
+                accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
+        }
+
+        open_parms.openx.level = RAW_OPEN_OPENX;
+        open_parms.openx.in.flags = 0;
+        open_parms.openx.in.open_mode = accessmode;
+        open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
+        open_parms.openx.in.file_attrs = 0;
+        open_parms.openx.in.write_time = 0;
+        open_parms.openx.in.open_func = openfn;
+        open_parms.openx.in.size = 0;
+        open_parms.openx.in.timeout = 0;
+        open_parms.openx.in.fname = NULL;
+
+        status = smb_raw_openX_name_blob(tree, mem_ctx, &open_parms, pname_blob);
+        talloc_free(mem_ctx);
+
+        if (fnum && NT_STATUS_IS_OK(status)) {
+                *fnum = open_parms.openx.out.file.fnum;
+        }
+
+        return status;
+}
+
+
 #define CHECK_STATUS(torture, status, correct) do {    \
        if (!NT_STATUS_EQUAL(status, correct)) { \
                torture_result(torture, TORTURE_FAIL, "%s: Incorrect status %s - should be %s\n", \
@@ -918,3 +1038,21 @@ bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_st
  done:
        return ret;
 }
+
+bool torture_samba3_check_openX_badname(struct torture_context *tctx, struct smbcli_state *cli)
+{
+       NTSTATUS status;
+       bool ret = false;
+       int fnum = -1;
+       DATA_BLOB name_blob = data_blob_talloc(cli->tree, NULL, 65535);
+
+       if (name_blob.data == NULL) {
+               return false;
+       }
+       memset(name_blob.data, 0xcc, 65535);
+       status = raw_smbcli_openX_name_blob(cli->tree, &name_blob, O_RDWR, DENY_NONE, &fnum);
+       CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_INVALID);
+       ret = true;
+
+       return ret;
+}