All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shailendra Tripathi <stripathi@agami.com>
To: xfs mailing list <xfs@oss.sgi.com>, xfs-dev@sgi.com
Subject: xfs_bmap_add_extent_delay_real: Uninited r[3] corrupts startoff
Date: Mon, 09 Oct 2006 12:52:16 +0530	[thread overview]
Message-ID: <4529F8A8.6080900@agami.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1789 bytes --]

Hi,
     It appears that uninitialized r[3] in 
xfs_bmap_add_extent_delay_real can potentially corrupt the startoff for 
a particular case.

This sequence is below:

        xfs_bmap_add_extent_delay_real (
        ...
        xfs_bmbt_irec_t         r[3];   /* neighbor extent entries */

case 0:
          /*
           * Filling in the middle part of a previous delayed allocation.
           * Contiguity is impossible here.
           * This case is avoided almost all the time.
           */
temp = new->br_startoff - PREV.br_startoff;
xfs_bmbt_set_blockcount(ep, temp);
r[0] = *new;
r[1].br_startoff = new_endoff;
temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
r[1].br_blockcount = temp2;
xfs_bmap_insert_exlist(ip, idx + 1, 2, &r[0], XFS_DATA_FORK);
ip->i_df.if_lastex = idx + 1;
ip->i_d.di_nextents++;

Look at extent r[1]. It does not set br_startblock. That is, it is any 
random value. Now, look at the xfs_bmbt_set_all. Though, it sets the 
blockcount later, the startoff does not get changed.

#if XFS_BIG_BLKNOS
         ASSERT((s->br_startblock & XFS_MASK64HI(12)) == 0);
         r->l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
                  ((xfs_bmbt_rec_base_t)s->br_startoff << 9) |
                  ((xfs_bmbt_rec_base_t)s->br_startblock >> 43);
Top 21 bits are taken as it is. However, only 9 bit should be taken. So, 
for random values, it corrupts the startoff which from 9-63 bits.

         r->l1 = ((xfs_bmbt_rec_base_t)s->br_startblock << 21) |
                  ((xfs_bmbt_rec_base_t)s->br_blockcount &
                  (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));

I have attached a small program which does the same thing as it is being 
done here. I would appreciate if someone can verify that assertion is 
correct.


Regards,
Shailendra

[-- Attachment #2: del_bmap.c --]
[-- Type: text/plain, Size: 1674 bytes --]

#include <stdio.h>
typedef unsigned long __uint64_t;
typedef struct xfs_bmbt_rec_64
{
        __uint64_t              l0, l1;
} xfs_bmbt_rec_64_t;

typedef __uint64_t      xfs_bmbt_rec_base_t;    
typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;

typedef enum {
       XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
       XFS_EXT_DMAPI_OFFLINE
} xfs_exntst_t;

typedef struct xfs_bmbt_irec
{
	__uint64_t   br_startoff;    /* starting file offset */
	__uint64_t   br_startblock;  /* starting block number */
	__uint64_t   br_blockcount;  /* number of blocks */
	xfs_exntst_t    br_state;       /* extent state */
} xfs_bmbt_irec_t;

#define XFS_MASK64LO(n)         (((__uint64_t)1 << (n)) - 1)
#define XFS_MASK64HI(n)         ((__uint64_t)-1 << (64 - (n)))

int main(void) 
{
	xfs_bmbt_irec_t s;
	xfs_bmbt_rec_t  r;
	int extent_flag;

	s.br_startoff = 0;
	s.br_blockcount = 5;
	s.br_startblock = 0xfffffffffffffff0;
	extent_flag = (s.br_state == XFS_EXT_NORM) ? 0 : 1;

	printf("blockcount = 0x%llx\n", s.br_startblock);
	r.l0 = ((xfs_bmbt_rec_base_t)extent_flag << 63) |
	          ((xfs_bmbt_rec_base_t)s.br_startoff << 9) |
	          ((xfs_bmbt_rec_base_t)s.br_startblock >> 43);
	r.l1 = ((xfs_bmbt_rec_base_t)s.br_startblock << 21) |
	         ((xfs_bmbt_rec_base_t)s.br_blockcount &
	         (xfs_bmbt_rec_base_t)XFS_MASK64LO(21));

	printf("l0 = 0x%llx l1 = 0x%llx\n", r.l0, r.l1);

	r.l0 = (r.l0 & (xfs_bmbt_rec_base_t)XFS_MASK64HI(55)) |
	        (xfs_bmbt_rec_base_t)((__uint64_t)100 >> 43);
	r.l1 = (r.l1 & (xfs_bmbt_rec_base_t)XFS_MASK64LO(21)) |
	        (xfs_bmbt_rec_base_t)((__uint64_t)100 << 21);

	printf("l0 = 0x%llx l1 = 0x%llx\n", r.l0, r.l1);
	return 0;
}

             reply	other threads:[~2006-10-09  7:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-09  7:22 Shailendra Tripathi [this message]
2006-10-11  1:10 ` xfs_bmap_add_extent_delay_real: Uninited r[3] corrupts startoff Vlad Apostolov
2006-11-15  0:00   ` Lachlan McIlroy
2006-11-15  0:32     ` Shailendra Tripathi
2006-11-15  1:21       ` Lachlan McIlroy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4529F8A8.6080900@agami.com \
    --to=stripathi@agami.com \
    --cc=xfs-dev@sgi.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.