Beispiel #1
0
bool talpa_vfsmount_unlock(unsigned* m_seq)
{
#if defined  TALPA_USE_VFSMOUNT_LOCK
#   if defined TALPA_VFSMOUNT_LG_BRLOCK
    br_read_unlock(&vfsmount_lock);
#   elif defined TALPA_VFSMOUNT_LOCK_BRLOCK
    br_read_unlock(vfsmount_lock);
#   else
    spinlock_t* talpa_vfsmount_lock_addr = (spinlock_t *)talpa_get_symbol("vfmount_lock", (void *)TALPA_VFSMOUNT_LOCK_ADDR);


    spin_unlock(talpa_vfsmount_lock_addr);
#   endif
#elif defined TALPA_USE_MOUNT_LOCK
    seqlock_t* mount_lock_addr = (seqlock_t *)talpa_get_symbol("mount_lock", (void *)TALPA_MOUNT_LOCK_ADDR);
    if (need_seqretry(mount_lock_addr, *m_seq)) {
       *m_seq = 1;
       return true;
    }
    done_seqretry(mount_lock_addr, *m_seq);
#else
    // On 2.4 we don't have vfsmount_lock - we use dcache_lock instead
    spin_unlock(&dcache_lock);
#endif
    return false;
}
Beispiel #2
0
static talpa_mount_struct* talpa_lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
{
#ifdef TALPA_HAVE_LOOKUP_MNT_LAST
    TALPA_PTR_FIX lookup_mnt_last_func lookup_mnt_last = (lookup_mnt_last_func)talpa_get_symbol("__lookup_mnt_last", (void *)TALPA__LOOKUP_MNT_LAST);
    return lookup_mnt_last(mnt, dentry);
#endif
#ifdef TALPA_HAVE_LOOKUP_MNT
    TALPA_PTR_FIX lookup_mnt_func lookup_mnt = (lookup_mnt_func)talpa_get_symbol("__lookup_mnt", (void *)TALPA__LOOKUP_MNT);
    return lookup_mnt(mnt, dentry, 0);
#endif
    return NULL;
}
Beispiel #3
0
void talpa_tasklist_unlock(void)
{
    rwlock_t* talpa_tasklist_lock_addr = (rwlock_t *)talpa_get_symbol("tasklist_lock", (void *)TALPA_TASKLIST_LOCK_ADDR);


    read_unlock(talpa_tasklist_lock_addr);
}
Beispiel #4
0
TALPA_FILENAME_T * talpa_getname(const char __user * filename )
{
    /*
     * Uses putname if available, or final_putname - but they come from the same define
     */
    typedef TALPA_FILENAME_T * (*getname_func)(const char __user * filename);
    getname_func getname = (getname_func)talpa_get_symbol("getname", (void *)TALPA_GETNAME_ADDRESS);
    return(getname(filename));
}
Beispiel #5
0
void talpa_putname(TALPA_FILENAME_T* filename)
{
    /*
     * Uses putname if available, or final_putname - but they come from the same define
     */
    typedef void(*putname_func)(TALPA_FILENAME_T *);
    putname_func putname = (putname_func)talpa_get_symbol("putname", (void *)TALPA_PUTNAME_ADDRESS);
    putname(filename);
}
Beispiel #6
0
/*
 * hidden vfsmnt_lock handling
 */
void talpa_vfsmount_lock(unsigned* m_seq)
{
#if defined TALPA_USE_VFSMOUNT_LOCK
#   if defined TALPA_VFSMOUNT_LG_BRLOCK
    br_read_lock(&vfsmount_lock);
#   elif defined TALPA_VFSMOUNT_LOCK_BRLOCK
    br_read_lock(vfsmount_lock);
#   else
    spinlock_t* talpa_vfsmount_lock_addr = (spinlock_t *)talpa_get_symbol("vfmount_lock", (void *)TALPA_VFSMOUNT_LOCK_ADDR);

    spin_lock(talpa_vfsmount_lock_addr);
#   endif
#elif defined TALPA_USE_MOUNT_LOCK
    seqlock_t* mount_lock_addr = (seqlock_t *)talpa_get_symbol("mount_lock", (void *)TALPA_MOUNT_LOCK_ADDR);
    read_seqbegin_or_lock(mount_lock_addr,m_seq);
#else
    // On 2.4 we don't have vfsmount_lock - we use dcache_lock instead
    spin_lock(&dcache_lock);
#endif

}
Beispiel #7
0
char* talpa__d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
            struct dentry *root, struct vfsmount *rootmnt,
            char *buffer, int buflen, bool* nonRootNamespaceOut)
{
    char* path;

    /* Get the function pointer for the real __d_path if we're going to call it. */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH)

#   if defined TALPA_DPATH_SLES11
    typedef char *(*d_path_func)(const struct path *, struct path *, char *, int, int);
#   elif defined TALPA_DPATH_PATH
    typedef char *(*d_path_func)(const struct path *, struct path *, char *, int);
#   elif defined TALPA_DPATH_SUSE103
    typedef char *(*d_path_func)(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *buffer, int buflen, int flags);
#   else
    typedef char *(*d_path_func)(struct dentry *, struct vfsmount *, struct dentry *, struct vfsmount *, char *buffer, int buflen);
#   endif


#   if defined TALPA_HAS_DPATH_ADDR
    d_path_func kernel_d_path = (d_path_func)talpa_get_symbol("__d_path", (void *)TALPA_DPATH_ADDR);
#   else
    d_path_func kernel_d_path = &__d_path;
#   endif

#   if defined TALPA_DPATH_SLES11 || defined TALPA_DPATH_PATH
    struct path pathPath;
    struct path rootPath;
#   endif
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH) */

    if (nonRootNamespaceOut != NULL)
    {
        *nonRootNamespaceOut = false;
    }

#if defined HOLD_DCACHE_LOCK_WHILE_CALLING_D_PATH
    spin_lock(&dcache_lock);
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) || (defined TALPA_HAS_DPATH)
    /* Calling the real __d_path */
#   if defined TALPA_DPATH_SLES11 || defined TALPA_DPATH_PATH
    pathPath.dentry = dentry;
    pathPath.mnt = vfsmnt;
    rootPath.dentry = root;
    rootPath.mnt = rootmnt;
#   endif

#   if defined TALPA_D_DNAME_DIRECT_DPATH
    if (dentry->d_op && dentry->d_op->d_dname)
    {
        path = d_path(&pathPath, buffer, buflen);
        if ( unlikely( IS_ERR(path) != 0 ) )
        {
            critical("talpa__d_path: d_path returned an error: %ld",PTR_ERR(path));
            path = NULL;
        }
        if ( NULL != path )
        {
            return path;
        }
    }
#   endif /* TALPA_D_DNAME_DIRECT_DPATH */

#   if defined TALPA_DPATH_SLES11
    path = kernel_d_path(&pathPath, &rootPath, buffer, buflen, 0);
#   elif defined TALPA_DPATH_PATH
    path = kernel_d_path(&pathPath, &rootPath, buffer, buflen);
#   elif defined TALPA_DPATH_SUSE103
    path = kernel_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen, 0);
#   else
    path = kernel_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen);
#   endif
#else
    /* Call our own version */
    path = __talpa_d_path(dentry, vfsmnt, root, rootmnt, buffer, buflen);
#endif

#if defined HOLD_DCACHE_LOCK_WHILE_CALLING_D_PATH
    spin_unlock(&dcache_lock);
#endif

    if ( unlikely( IS_ERR(path) != 0 ) )
    {
        critical("talpa__d_path: kernel__d_path returned an error: %ld",PTR_ERR(path));
        path = NULL;
    }
    else if ( unlikely( NULL == path ) )
    {
#ifdef TALPA_D_DNAME_DIRECT_DPATH
        /* only use this as a fall-back, it will only return the relative path from a chroot
         * Use this in cases where kernel_d_path fails to return a valid path for bind mounts
         * in newer kernel in a systemd environment */
        path = d_path(&pathPath, buffer, buflen);
        if ( unlikely( IS_ERR(path) != 0 ) )
        {
            critical("talpa__d_path: kernel_d_path returned an error: %ld",PTR_ERR(path));
            path = NULL;
        }

        if (dentry->d_op && dentry->d_op->d_dname)
        {
            dbg("    dpath=%s",path);
            err("dpath=%s - dentry has d_op and d_dname=%p",path,dentry->d_op->d_dname);
        }
#endif
        if ( NULL == path )
        {
            if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
                dbg("talpa__d_path: kernel_d_path returned NULL for deleted file");
                dbg("    basename=%s",dentry->d_name.name);
            }
            else
            {
                info("talpa__d_path: kernel_d_path returned NULL for non-deleted file");
                info("    basename=%s",dentry->d_name.name);
            }
        }
        else
        {
            if (!IS_ROOT(dentry) && d_unhashed(dentry))
            {
                dbg("    talpa__d_path: kernel_d_path returned NULL but d_path returned path %s for deleted file",path);
            }
            else
            {
                /* the systemd / containers / bind mount case.
                 *
                 * Now so common that we don't want to even debug log it
                 * dbg("    talpa__d_path: kernel_d_path returned NULL but d_path returned path %s for non-deleted file",path);
                 */
#ifdef TALPA_MNT_NAMESPACE
                if (NULL != getNamespaceInfo(vfsmnt) && (!S_ISDIR(dentry->d_inode->i_mode)))
                {
                    /* we're in a namespace/container */
                    if (nonRootNamespaceOut != NULL)
                    {
                        *nonRootNamespaceOut = true;
                    }
                }

                if (false)
                {
                    debugPathWalk(dentry, vfsmnt, root, rootmnt);
                }
#endif

            }
        }
    }

    return path;
}