diff --git a/prog/mutation.go b/prog/mutation.go index e861725c..8d5fa36a 100644 --- a/prog/mutation.go +++ b/prog/mutation.go @@ -89,16 +89,12 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable) { if r.bin() { arg.Data = mutateData(r, append([]byte{}, arg.Data...), int(0), ^int(0)) } else { - arg.Data = r.randString(s, a.Values) + arg.Data = r.randString(s, a.Values, a.Dir()) } case sys.BufferFilename: arg.Data = []byte(r.filename(s)) case sys.BufferSockaddr: arg.Data = r.sockaddr(s) - case sys.BufferAlgType: - arg.Data = r.algType(s) - case sys.BufferAlgName: - arg.Data = r.algName(s) default: panic("unknown buffer kind") } diff --git a/prog/prio.go b/prog/prio.go index a6919372..59a205a5 100644 --- a/prog/prio.go +++ b/prog/prio.go @@ -80,9 +80,11 @@ func calcStaticPriorities() [][]float32 { } case *sys.BufferType: switch a.Kind { - case sys.BufferBlobRand, sys.BufferBlobRange, sys.BufferAlgType, sys.BufferAlgName: + case sys.BufferBlobRand, sys.BufferBlobRange: case sys.BufferString: - noteUsage(0.2, "str") + if a.SubKind != "" { + noteUsage(0.2, fmt.Sprintf("str-%v", a.SubKind)) + } case sys.BufferSockaddr: noteUsage(1.0, "sockaddr") case sys.BufferFilename: diff --git a/prog/rand.go b/prog/rand.go index 30d0ba4a..eb24dcc4 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -258,7 +258,17 @@ func (r *randGen) sockaddr(s *state) []byte { return data } -func (r *randGen) randString(s *state, vals []string) []byte { +func (r *randGen) randString(s *state, vals []string, dir sys.Dir) []byte { + data := r.randStringImpl(s, vals) + if dir == sys.DirOut { + for i := range data { + data[i] = 0 + } + } + return data +} + +func (r *randGen) randStringImpl(s *state, vals []string) []byte { if len(vals) != 0 { return []byte(vals[r.Intn(len(vals))]) } @@ -291,34 +301,6 @@ func (r *randGen) randString(s *state, vals []string) []byte { return buf.Bytes() } -func (r *randGen) algType(s *state) []byte { - dict := []string{"aead", "hash", "rng", "skcipher"} - res := make([]byte, 14) - copy(res, dict[r.Intn(len(dict))]) - return res -} - -func (r *randGen) algName(s *state) []byte { - dict := []string{"cmac(aes)", "ecb(aes)", "cbc(aes)", "hmac(sha1)", "pcbc(fcrypt)", "ghash", - "jitterentropy_rng", "stdrng", "stdrng", "stdrng", "stdrng", "hmac(sha256)", "stdrng", - "stdrng", "stdrng", "stdrng", "stdrng", "842", "lz4hc", "lz4", "lzo", "crct10dif", "crc32", - "crc32c", "michael_mic", "zlib", "deflate", "poly1305", "chacha20", "salsa20", "seed", - "anubis", "khazad", "xeta", "xtea", "tea", "ecb(arc4)", "arc4", "cast6", "cast5", "camellia", - "aes", "tnepres", "serpent", "twofish", "blowfish", "fcrypt", "des3_ede", "des", "tgr128", - "tgr160", "tgr192", "wp256", "wp384", "wp512", "sha384", "sha512", "sha224", "sha256", - "sha1", "rmd320", "rmd256", "rmd160", "rmd128", "md5", "md4", "digest_null", "compress_null", - "ecb(cipher_null)", "cipher_null", "rsa", "poly1305", "xts(serpent)", "lrw(serpent)", - "ctr(serpent)", "cbc(serpent)", "__ecb-serpent-sse2", "ecb(serpent)", "__xts-serpent-sse2", - "__lrw-serpent-sse2", "__ctr-serpent-sse2", "__cbc-serpent-sse2", "__ecb-serpent-sse2", - "salsa20", "xts(twofish)", "lrw(twofish)", "ctr(twofish)", "cbc(twofish)", "ecb(twofish)", - "twofish", "ctr(blowfish)", "cbc(blowfish)", "ecb(blowfish)", "blowfish", "xts(camellia)", - "lrw(camellia)", "ctr(camellia)", "cbc(camellia)", "ecb(camellia)", "camellia", "ctr(des3_ede)", - "cbc(des3_ede)", "ecb(des3_ede)", "des3_ede", "aes"} - res := make([]byte, 64) - copy(res, dict[r.Intn(len(dict))]) - return res -} - func isSpecialStruct(typ sys.Type) func(r *randGen, s *state) (*Arg, []*Call) { a, ok := typ.(*sys.StructType) if !ok { @@ -707,7 +689,7 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) } return dataArg(a, data), nil case sys.BufferString: - data := r.randString(s, a.Values) + data := r.randString(s, a.Values, a.Dir()) return dataArg(a, data), nil case sys.BufferFilename: filename := r.filename(s) @@ -720,22 +702,6 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) } } return dataArg(a, data), nil - case sys.BufferAlgType: - data := r.algType(s) - if a.Dir() == sys.DirOut { - for i := range data { - data[i] = 0 - } - } - return dataArg(a, data), nil - case sys.BufferAlgName: - data := r.algName(s) - if a.Dir() == sys.DirOut { - for i := range data { - data[i] = 0 - } - } - return dataArg(a, data), nil default: panic("unknown buffer kind") } diff --git a/sys/README.md b/sys/README.md index 161c1e73..8125a7b7 100644 --- a/sys/README.md +++ b/sys/README.md @@ -46,7 +46,8 @@ rest of the type-options are type-specific: direction (in/out/inout) "string": a zero-terminated memory buffer (no pointer indirection implied), type-options: either a string value in quotes for constant strings (e.g. "foo"), - or a reference to string flags + or a reference to string flags, + optionally followed by a buffer size (string values will be padded with \x00 to that size) "filename": a file/link/dir name "fileoff": offset within a file "len": length of another field (for array it is number of elements), type-options: diff --git a/sys/decl.go b/sys/decl.go index 2f86ea87..84c2f8c0 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -105,8 +105,6 @@ const ( BufferString BufferFilename BufferSockaddr - BufferAlgType - BufferAlgName ) type BufferType struct { @@ -120,13 +118,17 @@ type BufferType struct { func (t *BufferType) Size() uintptr { switch t.Kind { - case BufferAlgType: - return 14 - case BufferAlgName: - return 64 case BufferString: - if len(t.Values) == 1 { - return uintptr(len(t.Values[0])) + size := 0 + for _, s := range t.Values { + if size != 0 && size != len(s) { + size = 0 + break + } + size = len(s) + } + if size != 0 { + return uintptr(size) } case BufferBlobRange: if t.RangeBegin == t.RangeEnd { diff --git a/sys/socket.txt b/sys/socket.txt index ca4dfeaf..74728194 100644 --- a/sys/socket.txt +++ b/sys/socket.txt @@ -273,10 +273,10 @@ sendmmsg$alg(fd sock_algconn, mmsg ptr[in, array[msghdr_alg]], vlen len[mmsg], f sockaddr_alg { family const[AF_ALG, int16] - type salg_type + type string[salg_type, 14] feat flags[af_alg_type, int32] mask flags[af_alg_type, int32] - name salg_name + name string[salg_name, 64] } msghdr_alg { @@ -320,6 +320,9 @@ cmsghdr_alg_assoc { af_alg_type = CRYPTO_ALG_TYPE_MASK, CRYPTO_ALG_TYPE_CIPHER, CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_AEAD, CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_ABLKCIPHER, CRYPTO_ALG_TYPE_GIVCIPHER, CRYPTO_ALG_TYPE_DIGEST, CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_SHASH, CRYPTO_ALG_TYPE_AHASH, CRYPTO_ALG_TYPE_RNG, CRYPTO_ALG_TYPE_AKCIPHER, CRYPTO_ALG_TYPE_PCOMPRESS, CRYPTO_ALG_LARVAL, CRYPTO_ALG_DEAD, CRYPTO_ALG_DYING, CRYPTO_ALG_ASYNC, CRYPTO_ALG_NEED_FALLBACK, CRYPTO_ALG_GENIV, CRYPTO_ALG_TESTED, CRYPTO_ALG_INSTANCE, CRYPTO_ALG_KERN_DRIVER_ONLY, CRYPTO_ALG_INTERNAL +salg_type = "aead", "hash", "rng", "skcipher" +salg_name = "cmac(aes)", "ecb(aes)", "cbc(aes)", "hmac(sha1)", "pcbc(fcrypt)", "ghash", "jitterentropy_rng", "stdrng", "stdrng", "stdrng", "stdrng", "hmac(sha256)", "stdrng", "stdrng", "stdrng", "stdrng", "stdrng", "842", "lz4hc", "lz4", "lzo", "crct10dif", "crc32", "crc32c", "michael_mic", "zlib", "deflate", "poly1305", "chacha20", "salsa20", "seed", "anubis", "khazad", "xeta", "xtea", "tea", "ecb(arc4)", "arc4", "cast6", "cast5", "camellia", "aes", "tnepres", "serpent", "twofish", "blowfish", "fcrypt", "des3_ede", "des", "tgr128", "tgr160", "tgr192", "wp256", "wp384", "wp512", "sha384", "sha512", "sha224", "sha256", "sha1", "rmd320", "rmd256", "rmd160", "rmd128", "md5", "md4", "digest_null", "compress_null", "ecb(cipher_null)", "cipher_null", "rsa", "poly1305", "xts(serpent)", "lrw(serpent)", "ctr(serpent)", "cbc(serpent)", "__ecb-serpent-sse2", "ecb(serpent)", "__xts-serpent-sse2", "__lrw-serpent-sse2", "__ctr-serpent-sse2", "__cbc-serpent-sse2", "__ecb-serpent-sse2", "salsa20", "xts(twofish)", "lrw(twofish)", "ctr(twofish)", "cbc(twofish)", "ecb(twofish)", "twofish", "ctr(blowfish)", "cbc(blowfish)", "ecb(blowfish)", "blowfish", "xts(camellia)", "lrw(camellia)", "ctr(camellia)", "cbc(camellia)", "ecb(camellia)", "camellia", "ctr(des3_ede)", "cbc(des3_ede)", "ecb(des3_ede)", "des3_ede", "aes" + diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index 6913b9c8..fda931b1 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -407,24 +407,45 @@ func generateArg( opt = false fmt.Fprintf(out, "&PtrType{%v, Type: &BufferType{%v, Kind: BufferBlobRand}}", ptrCommonHdr, common()) case "string": - if len(a) != 0 && len(a) != 1 { - failf("wrong number of arguments for %v arg %v, want 0 or 1, got %v", typ, name, len(a)) + if len(a) != 0 && len(a) != 1 && len(a) != 2 { + failf("wrong number of arguments for %v arg %v, want 0-2, got %v", typ, name, len(a)) } var vals []string subkind := "" - if len(a) == 1 { + if len(a) >= 1 { if a[0][0] == '"' { vals = append(vals, a[0][1:len(a[0])-1]) } else { - ok := false - vals, ok = desc.StrFlags[a[0]] + vals1, ok := desc.StrFlags[a[0]] if !ok { failf("unknown string flags %v", a[0]) } + vals = append([]string{}, vals1...) subkind = a[0] } + } + for i, s := range vals { + vals[i] = s + "\x00" + } + if len(a) >= 2 { + var size uint64 + if v, ok := consts[a[1]]; ok { + size = v + } else { + v, err := strconv.ParseUint(a[1], 10, 64) + if err != nil { + failf("failed to parse string length for %v", name, a[1]) + } + size = v + } for i, s := range vals { - vals[i] = s + "\x00" + if uint64(len(s)) > size { + failf("string value %q exceeds buffer length %v for arg %v", s, size, name) + } + for uint64(len(s)) < size { + s += "\x00" + } + vals[i] = s } } fmt.Fprintf(out, "&BufferType{%v, Kind: BufferString, SubKind: %q, Values: %#v}", common(), subkind, vals)