NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/51418: Fix incore src/sbin/fsck_lfs/bufcache.c



>Number:         51418
>Category:       bin
>Synopsis:       Fix incore src/sbin/fsck_lfs/bufcache.c
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 17 11:40:00 +0000 2016
>Originator:     Jose Luis Rodriguez Garcia
>Release:        current and previous releases
>Organization:
>Environment:
>Description:
incore function from buffercache.c uses int instead of daddr_t
 it must be: incore(struct uvnode * vp, int lbn)
instead of: incore(struct uvnode * vp, daddr_t lbn)

It produces that daddr_t (that is unint64_t) is casted as int.
In 32 bits platforms (i386 at last), it produces that adress > 1 Tbyte (assuming a 512 DEV_BSIZE), are converted to a negative number. It produces the next problems in 32 bits architectures:

1- Blocks higher than 1 Tbyte aren't cached in the buffer cache. Its buffers aren't found by the incore function, because the real disk adress is compared against a negative number
2- A unique block is cached in several buffers, becuase incore never founds the block. getblock funtion wastes memory adding buffers that won't be found.
3- Potential corruption: A block marked with B_DELWRI (dirty cache) can be contained in different buffers. What buffer will be written first?

I think that the fix must be pulled to previous releases.
>How-To-Repeat:
code review
>Fix:
I have tested the compilation of the fix with a ./build.sh build

Index: bufcache.c
===================================================================
RCS file: /cvsroot/src/sbin/fsck_lfs/bufcache.c,v
retrieving revision 1.16
diff -u -r1.16 bufcache.c
--- bufcache.c  31 Jul 2016 18:27:26 -0000      1.16
+++ bufcache.c  17 Aug 2016 11:26:49 -0000
@@ -194,7 +194,7 @@
 
 /* Return a buffer if it is in the cache, otherwise return NULL. */
 struct ubuf *
-incore(struct uvnode * vp, int lbn)
+incore(struct uvnode * vp, daddr_t lbn)
 {
        struct ubuf *bp;
        int hash, depth;
Index: bufcache.h
===================================================================
RCS file: /cvsroot/src/sbin/fsck_lfs/bufcache.h,v
retrieving revision 1.12
diff -u -r1.12 bufcache.h
--- bufcache.h  29 Mar 2015 19:35:58 -0000      1.12
+++ bufcache.h  17 Aug 2016 11:26:49 -0000
@@ -116,7 +116,7 @@
 void bufstats(void);
 void buf_destroy(struct ubuf *);
 void bremfree(struct ubuf *);
-struct ubuf *incore(struct uvnode *, int);
+struct ubuf *incore(struct uvnode *, daddr_t);
 struct ubuf *getblk(struct uvnode *, daddr_t, int);
 void bwrite(struct ubuf *);
 void brelse(struct ubuf *, int);



Home | Main Index | Thread Index | Old Index