0

Intel mpx is a set of processor instructions that allow to check bounds of functions. If an overflow is detected through Intel mpx, a SIGSEV signal is raised even if the program would still be able to run if it was compiled without intel mpx.

While compiling libntfs‑3g, I had this problem which was confirmed at runtime :

attrib.c: In function ‘ntfs_resident_attr_resize_i.chkp’:
attrib.c:3444:8: warning: memory access check always fail [-Wchkp]
   mrec = ni->mrec;
   ~~~~~^~~~~~~~~~
attrib.c:3444:8: warning: memory access check always fail [-Wchkp]

The problem is I’m failing to see how there’s could be a buffer overflow through this simple pointer assignment :

/**
 * struct MFT_RECORD - An MFT record layout (NTFS 3.1+)
 *
 * The mft record header present at the beginning of every record in the mft.
 * This is followed by a sequence of variable length attribute records which
 * is terminated by an attribute of type AT_END which is a truncated attribute
 * in that it only consists of the attribute type code AT_END and none of the
 * other members of the attribute structure are present.
 */
typedef struct {
    NTFS_RECORD_TYPES magic;/* Usually the magic is "FILE". */
    le16 usa_ofs;        /* See NTFS_RECORD definition above. */
    le16 usa_count;        /* See NTFS_RECORD definition above. */
/*  8*/    leLSN lsn;        /* $LogFile sequence number for this record.
                   Changed every time the record is modified. */
/* 16*/    le16 sequence_number;    /* Number of times this mft record has been
                   reused. (See description for MFT_REF
                   above.) NOTE: The increment (skipping zero)
                   is done when the file is deleted. NOTE: If
                   this is zero it is left zero. */
/* 18*/    le16 link_count;        /* Number of hard links, i.e. the number of
                   directory entries referencing this record.
                   NOTE: Only used in mft base records.
                   NOTE: When deleting a directory entry we
                   check the link_count and if it is 1 we
                   delete the file. Otherwise we delete the
                   FILE_NAME_ATTR being referenced by the
                   directory entry from the mft record and
                   decrement the link_count.
/* 20*/    le16 attrs_offset;    /* Byte offset to the first attribute in this
                   mft record from the start of the mft record.
                   NOTE: Must be aligned to 8-byte boundary. */
/* 22*/    MFT_RECORD_FLAGS flags;    /* Bit array of MFT_RECORD_FLAGS. When a file
                   is deleted, the MFT_RECORD_IN_USE flag is
                   set to zero. */
/* 24*/    le32 bytes_in_use;    /* Number of bytes used in this mft record.
                   NOTE: Must be aligned to 8-byte boundary. */
/* 28*/    le32 bytes_allocated;    /* Number of bytes allocated for this mft
                   record. This should be equal to the mft
                   record size. */
/* 32*/    leMFT_REF base_mft_record;
/* 40*/    le16 next_attr_instance; /* The instance number that will be
                   assigned to the next attribute added to this
                   mft record. NOTE: Incremented each time
                   after it is used. NOTE: Every time the mft
                   record is reused this number is set to zero.
                   NOTE: The first instance number is always 0.
                 */
/* The below fields are specific to NTFS 3.1+ (Windows XP and above): */
/* 42*/ le16 reserved;        /* Reserved/alignment. */
/* 44*/ le32 mft_record_number;    /* Number of this mft record. */
/* sizeof() = 48 bytes */
} __attribute__((__packed__)) MFT_RECORD;

struct ntfs_attr_search_ctx {
    MFT_RECORD *mrec;
    ATTR_RECORD *attr;
    BOOL is_first;
    ntfs_inode *ntfs_ino;
    ATTR_LIST_ENTRY *al_entry;
    ntfs_inode *base_ntfs_ino;
    MFT_RECORD *base_mrec;
    ATTR_RECORD *base_attr;
};

/**
 * ntfs_attr_init_search_ctx - initialize an attribute search context
 * @ctx:    attribute search context to initialize
 * @ni:     ntfs inode with which to initialize the search context
 * @mrec:   mft record with which to initialize the search context
 *
 * Initialize the attribute search context @ctx with @ni and @mrec.
 */
static void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
        ntfs_inode *ni, MFT_RECORD *mrec)
{
    if (!mrec)
        mrec = ni->mrec; // attrib.c:3444:8: warning: memory access check always fail [-Wchkp]
    ctx->mrec = mrec;

And when I compile libntfs‑3g with libasan, there’s no warming nor overflow detected at runtime. It only occurs with ntfs‑3g

user2284570
  • 2,891
  • 3
  • 26
  • 74
  • If it's complaining about access to `ni->mrec` the problem must come from outer context in which `ni` is instantiated. – yugr Mar 10 '17 at 16:17
  • @yugr but as you can see it isn t since it is not used changed the current function. That function is only called inside other files. – user2284570 Mar 10 '17 at 16:30
  • "That function is only called inside other files" - hm, it's a static function so it can only be called in the same file... – yugr Mar 10 '17 at 16:40
  • @yugr at least gcc didn t gave any other details. all the warming is here. So if it is, I have no ideas on what the outer context can be. – user2284570 Mar 10 '17 at 16:45
  • "I have no ideas on what the outer context can be" - that's why I suggested to minimize the file. My understanding is that `ntfs_attr_init_search_ctx` gets inlined and then MPX pass figures out that inlined code will always result in segfault. – yugr Mar 10 '17 at 16:52
  • @yugr in that case'it a gcc bug then, mpx is well known to have false postives due to compiler optimizations, but such case are reported on the bugzilla. Is there an alternative that does not consist of disabling optmizations? – user2284570 Mar 10 '17 at 16:55

0 Answers0