Messages in this thread | | | Date | Sat, 28 Aug 2010 09:15:16 -0400 | From | Bob Copeland <> | Subject | Re: [PATCH] VFS: Sanity check mount flags passed to change_mnt_propagation() |
| |
On Sat, Aug 28, 2010 at 04:57:07AM -0600, Matthew Wilcox wrote: > > Didn't read surrounding code, but is that supposed to be '||'? > > > > Otherwise the case where only a single non-propagation flag is > > set no longer returns 0... > > Val's original code returned 0 as failure. So a single non-propagation > flag set shouldn't return 0.
Not to belabor the point -- but her original code did return zero in that case (2nd assertion fails):
#include <linux/fs.h> #include <stdio.h> #include <assert.h>
#define hweight32 dumb_hweight32
int dumb_hweight32(int a) { int i; int weight = 0;
for (i=0; i < 32; i++) weight += !!(a & (1 << i));
return weight; }
static int flags_to_propagation_type(int flags) { int type = flags & ~MS_REC;
/* Fail if any non-propagation flags are set */ if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) return 0; /* Only one propagation flag should be set */ if (((type & (MS_SHARED)) && (type & ~MS_SHARED)) || ((type & (MS_PRIVATE)) && (type & ~MS_PRIVATE)) || ((type & (MS_SLAVE)) && (type & ~MS_SLAVE)) || ((type & (MS_UNBINDABLE)) && (type & ~MS_UNBINDABLE))) return 0; return type; }
static int flags_to_propagation_type_2(int flags) { int type = flags & ~MS_REC;
/* Only one propagation flag should be set, and no others */ if (hweight32(type) != 1 && (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))) return 0;
return type; }
int main(int argc, char *argv[]) { int mytype = MS_RDONLY;
assert(flags_to_propagation_type(mytype) == 0); assert(flags_to_propagation_type_2(mytype) == 0); }
-- Bob Copeland %% www.bobcopeland.com
| |