CVS update: samba4/source/ntvfs

Stefan Metzmacher metze at metzemix.de
Mon Dec 1 06:51:21 GMT 2003


Jelmer Vernooij wrote:

>On Thu, Nov 27, 2003 at 01:37:44PM +0100, Stefan Metzmacher wrote about 'Re: CVS update: samba4/source/ntvfs':
>  
>
>>Jelmer Vernooij wrote:
>>    
>>
>>>Isn't that what the ntvfs_interface_version function is supposed to
>>>be used for? A backend can check only the sizes of the structs it uses
>>>and ignore the other ones.
>>>      
>>>
>>hmm, should we really let the module decide that?
>>    
>>
>
>  
>
>>I think the module should be able to check the sizes and then decide 
>>which funtions it want to register.
>>But a module can also not check for sizes and just register it's 
>>functions for an old samba version.
>>And then we segfault. (tridge I know that segfaulting is good to find 
>>bugs:-) but I think this is no bug! and we should check this)
>>also we should check the the version in
>>ntvfs_interface_version()
>>    
>>
>Even then, you shouldn't store the interface version in the ops
>struct.
>
then I would also not store the name on the ops struct!

struct ntvfs_ops {
-    const char *name;
    enum ntvfs_type type;
...
static struct {
+     const char *name;
    struct ntvfs_ops *ops;
} *backends = NULL;
static int num_backends;

> Rather, the module should check the interface version itself
>and then decide whether it wants to register.
>
>  
>
hmm...(I still think we shouldn't give up the control to  a  
module:-)..but...

>>because if the module tries to test the sizes and pass the wrong struct 
>>we'll segfault in the ntvfs_interface_version() if the struct has grown!
>>    
>>
>Wasn't the first element of the struct returned by
>  
>

>ntvfs_interface_version() the value of the sizeof() of that struct?
>  
>

The current function (the module is compiled against this version):
int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes)
{
    sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops);
    sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T);
    sizes->sizeof_tcon_context = sizeof(struct tcon_context);
    sizes->sizeof_request_context = sizeof(struct request_context);

    return NTVFS_INTERFACE_VERSION;
}

the new function (the smbd uses this and the size of  struct 
ntvfs_critical_sizes has grown):
int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes)
{
    sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops);
    sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T);
    sizes->sizeof_tcon_context = sizeof(struct tcon_context);
    sizes->sizeof_request_context = sizeof(struct request_context);
/*here smbd will overwrite some memory behind the module's struct 
ntvfs_critical_sizes
or it will segfault */
    sizes->sizeof_other1_context = sizeof(struct other1_context);
    sizes->sizeof_other2_context = sizeof(struct other2_context);

    return NTVFS_INTERFACE_VERSION;
}

so I see two solutions

int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes)
{
    if (sizes) {
        sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops);
        sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T);
        sizes->sizeof_tcon_context = sizeof(struct tcon_context);
        sizes->sizeof_request_context = sizeof(struct request_context);
    }
    return NTVFS_INTERFACE_VERSION;
}

module:
...
if (NTVFS_INTERFACE_VERSION==ntvfs_interface_version(NULL)) {
       ntvfs_interface_version(&sizes);
}
...

int ntvfs_interface_version(int version, struct ntvfs_critical_sizes *sizes)
{
       if (NTVFS_INTERFACE_VERSION!=version) {
           return NTVFS_INTERFACE_VERSION;
        }
        sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops);
        sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T);
        sizes->sizeof_tcon_context = sizeof(struct tcon_context);
        sizes->sizeof_request_context = sizeof(struct request_context);

    return NTVFS_INTERFACE_VERSION;
}

-- 

metze

-------------------------------------------
Stefan (metze) Metzmacher <metze at metzemix.de>





More information about the samba-technical mailing list