github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/libsnap-confine-private/snap-test.c (about)

     1  /*
     2   * Copyright (C) 2017 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  #include "snap.h"
    19  #include "snap.c"
    20  
    21  #include <glib.h>
    22  
    23  static void test_verify_security_tag(void)
    24  {
    25  	// First, test the names we know are good
    26  	g_assert_true(verify_security_tag("snap.name.app", "name"));
    27  	g_assert_true(verify_security_tag
    28  		      ("snap.network-manager.NetworkManager",
    29  		       "network-manager"));
    30  	g_assert_true(verify_security_tag("snap.f00.bar-baz1", "f00"));
    31  	g_assert_true(verify_security_tag("snap.foo.hook.bar", "foo"));
    32  	g_assert_true(verify_security_tag("snap.foo.hook.bar-baz", "foo"));
    33  	g_assert_true(verify_security_tag
    34  		      ("snap.foo_instance.bar-baz", "foo_instance"));
    35  	g_assert_true(verify_security_tag
    36  		      ("snap.foo_instance.hook.bar-baz", "foo_instance"));
    37  	g_assert_true(verify_security_tag
    38  		      ("snap.foo_bar.hook.bar-baz", "foo_bar"));
    39  
    40  	// Now, test the names we know are bad
    41  	g_assert_false(verify_security_tag
    42  		       ("pkg-foo.bar.0binary-bar+baz", "bar"));
    43  	g_assert_false(verify_security_tag("pkg-foo_bar_1.1", ""));
    44  	g_assert_false(verify_security_tag("appname/..", ""));
    45  	g_assert_false(verify_security_tag("snap", ""));
    46  	g_assert_false(verify_security_tag("snap.", ""));
    47  	g_assert_false(verify_security_tag("snap.name", "name"));
    48  	g_assert_false(verify_security_tag("snap.name.", "name"));
    49  	g_assert_false(verify_security_tag("snap.name.app.", "name"));
    50  	g_assert_false(verify_security_tag("snap.name.hook.", "name"));
    51  	g_assert_false(verify_security_tag("snap!name.app", "!name"));
    52  	g_assert_false(verify_security_tag("snap.-name.app", "-name"));
    53  	g_assert_false(verify_security_tag("snap.name!app", "name!"));
    54  	g_assert_false(verify_security_tag("snap.name.-app", "name"));
    55  	g_assert_false(verify_security_tag("snap.name.app!hook.foo", "name"));
    56  	g_assert_false(verify_security_tag("snap.name.app.hook!foo", "name"));
    57  	g_assert_false(verify_security_tag("snap.name.app.hook.-foo", "name"));
    58  	g_assert_false(verify_security_tag("snap.name.app.hook.f00", "name"));
    59  	g_assert_false(verify_security_tag("sna.pname.app", "pname"));
    60  	g_assert_false(verify_security_tag("snap.n@me.app", "n@me"));
    61  	g_assert_false(verify_security_tag("SNAP.name.app", "name"));
    62  	g_assert_false(verify_security_tag("snap.Name.app", "Name"));
    63  	// This used to be false but it's now allowed.
    64  	g_assert_true(verify_security_tag("snap.0name.app", "0name"));
    65  	g_assert_false(verify_security_tag("snap.-name.app", "-name"));
    66  	g_assert_false(verify_security_tag("snap.name.@app", "name"));
    67  	g_assert_false(verify_security_tag(".name.app", "name"));
    68  	g_assert_false(verify_security_tag("snap..name.app", ".name"));
    69  	g_assert_false(verify_security_tag("snap.name..app", "name."));
    70  	g_assert_false(verify_security_tag("snap.name.app..", "name"));
    71  	// These contain invalid instance key
    72  	g_assert_false(verify_security_tag("snap.foo_.bar-baz", "foo"));
    73  	g_assert_false(verify_security_tag
    74  		       ("snap.foo_toolonginstance.bar-baz", "foo"));
    75  	g_assert_false(verify_security_tag
    76  		       ("snap.foo_inst@nace.bar-baz", "foo"));
    77  	g_assert_false(verify_security_tag
    78  		       ("snap.foo_in-stan-ce.bar-baz", "foo"));
    79  	g_assert_false(verify_security_tag("snap.foo_in stan.bar-baz", "foo"));
    80  
    81  	// Test names that are both good, but snap name doesn't match security tag
    82  	g_assert_false(verify_security_tag("snap.foo.hook.bar", "fo"));
    83  	g_assert_false(verify_security_tag("snap.foo.hook.bar", "fooo"));
    84  	g_assert_false(verify_security_tag("snap.foo.hook.bar", "snap"));
    85  	g_assert_false(verify_security_tag("snap.foo.hook.bar", "bar"));
    86  	g_assert_false(verify_security_tag("snap.foo_instance.bar", "foo_bar"));
    87  
    88  	// Regression test 12to8
    89  	g_assert_true(verify_security_tag("snap.12to8.128to8", "12to8"));
    90  	g_assert_true(verify_security_tag("snap.123test.123test", "123test"));
    91  	g_assert_true(verify_security_tag
    92  		      ("snap.123test.hook.configure", "123test"));
    93  
    94  	// regression test snap.eon-edg-shb-pulseaudio.hook.connect-plug-i2c
    95  	g_assert_true(verify_security_tag
    96  		      ("snap.foo.hook.connect-plug-i2c", "foo"));
    97  }
    98  
    99  static void test_sc_is_hook_security_tag(void)
   100  {
   101  	// First, test the names we know are good
   102  	g_assert_true(sc_is_hook_security_tag("snap.foo.hook.bar"));
   103  	g_assert_true(sc_is_hook_security_tag("snap.foo.hook.bar-baz"));
   104  	g_assert_true(sc_is_hook_security_tag
   105  		      ("snap.foo_instance.hook.bar-baz"));
   106  	g_assert_true(sc_is_hook_security_tag("snap.foo_bar.hook.bar-baz"));
   107  
   108  	// Now, test the names we know are not valid hook security tags
   109  	g_assert_false(sc_is_hook_security_tag("snap.foo_instance.bar-baz"));
   110  	g_assert_false(sc_is_hook_security_tag("snap.name.app!hook.foo"));
   111  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook!foo"));
   112  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook.-foo"));
   113  	g_assert_false(sc_is_hook_security_tag("snap.name.app.hook.f00"));
   114  }
   115  
   116  static void test_sc_snap_or_instance_name_validate(gconstpointer data)
   117  {
   118  	typedef void (*validate_func_t)(const char *, sc_error **);
   119  
   120  	validate_func_t validate = (validate_func_t) data;
   121  	bool is_instance =
   122  	    (validate == sc_instance_name_validate) ? true : false;
   123  
   124  	sc_error *err = NULL;
   125  
   126  	// Smoke test, a valid snap name
   127  	validate("hello-world", &err);
   128  	g_assert_null(err);
   129  
   130  	// Smoke test: invalid character 
   131  	validate("hello world", &err);
   132  	g_assert_nonnull(err);
   133  	g_assert_true(sc_error_match
   134  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   135  	g_assert_cmpstr(sc_error_msg(err), ==,
   136  			"snap name must use lower case letters, digits or dashes");
   137  	sc_error_free(err);
   138  
   139  	// Smoke test: no letters
   140  	validate("", &err);
   141  	g_assert_nonnull(err);
   142  	g_assert_true(sc_error_match
   143  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   144  	g_assert_cmpstr(sc_error_msg(err), ==,
   145  			"snap name must contain at least one letter");
   146  	sc_error_free(err);
   147  
   148  	// Smoke test: leading dash
   149  	validate("-foo", &err);
   150  	g_assert_nonnull(err);
   151  	g_assert_true(sc_error_match
   152  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   153  	g_assert_cmpstr(sc_error_msg(err), ==,
   154  			"snap name cannot start with a dash");
   155  	sc_error_free(err);
   156  
   157  	// Smoke test: trailing dash
   158  	validate("foo-", &err);
   159  	g_assert_nonnull(err);
   160  	g_assert_true(sc_error_match
   161  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   162  	g_assert_cmpstr(sc_error_msg(err), ==,
   163  			"snap name cannot end with a dash");
   164  	sc_error_free(err);
   165  
   166  	// Smoke test: double dash
   167  	validate("f--oo", &err);
   168  	g_assert_nonnull(err);
   169  	g_assert_true(sc_error_match
   170  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   171  	g_assert_cmpstr(sc_error_msg(err), ==,
   172  			"snap name cannot contain two consecutive dashes");
   173  	sc_error_free(err);
   174  
   175  	// Smoke test: NULL name is not valid
   176  	validate(NULL, &err);
   177  	g_assert_nonnull(err);
   178  	// the only case when instance name validation diverges from snap name
   179  	// validation
   180  	if (!is_instance) {
   181  		g_assert_true(sc_error_match
   182  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   183  		g_assert_cmpstr(sc_error_msg(err), ==,
   184  				"snap name cannot be NULL");
   185  	} else {
   186  		g_assert_true(sc_error_match
   187  			      (err, SC_SNAP_DOMAIN,
   188  			       SC_SNAP_INVALID_INSTANCE_NAME));
   189  		g_assert_cmpstr(sc_error_msg(err), ==,
   190  				"snap instance name cannot be NULL");
   191  	}
   192  	sc_error_free(err);
   193  
   194  	const char *valid_names[] = {
   195  		"aa", "aaa", "aaaa",
   196  		"a-a", "aa-a", "a-aa", "a-b-c",
   197  		"a0", "a-0", "a-0a",
   198  		"01game", "1-or-2"
   199  	};
   200  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   201  		g_test_message("checking valid snap name: %s", valid_names[i]);
   202  		validate(valid_names[i], &err);
   203  		g_assert_null(err);
   204  	}
   205  	const char *invalid_names[] = {
   206  		// name cannot be empty
   207  		"",
   208  		// too short
   209  		"a",
   210  		// names cannot be too long
   211  		"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
   212  		"xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx",
   213  		"1111111111111111111111111111111111111111x",
   214  		"x1111111111111111111111111111111111111111",
   215  		"x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x",
   216  		// dashes alone are not a name
   217  		"-", "--",
   218  		// double dashes in a name are not allowed
   219  		"a--a",
   220  		// name should not end with a dash
   221  		"a-",
   222  		// name cannot have any spaces in it
   223  		"a ", " a", "a a",
   224  		// a number alone is not a name
   225  		"0", "123", "1-2-3",
   226  		// identifier must be plain ASCII
   227  		"日本語", "한글", "ру́сский язы́к",
   228  	};
   229  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   230  	     ++i) {
   231  		g_test_message("checking invalid snap name: >%s<",
   232  			       invalid_names[i]);
   233  		validate(invalid_names[i], &err);
   234  		g_assert_nonnull(err);
   235  		g_assert_true(sc_error_match
   236  			      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   237  		sc_error_free(err);
   238  	}
   239  	// Regression test: 12to8 and 123test
   240  	validate("12to8", &err);
   241  	g_assert_null(err);
   242  	validate("123test", &err);
   243  	g_assert_null(err);
   244  
   245  	// In case we switch to a regex, here's a test that could break things.
   246  	const char good_bad_name[] = "u-94903713687486543234157734673284536758";
   247  	char varname[sizeof good_bad_name] = { 0 };
   248  	for (size_t i = 3; i <= sizeof varname - 1; i++) {
   249  		g_assert_nonnull(memcpy(varname, good_bad_name, i));
   250  		varname[i] = 0;
   251  		g_test_message("checking valid snap name: >%s<", varname);
   252  		validate(varname, &err);
   253  		g_assert_null(err);
   254  		sc_error_free(err);
   255  	}
   256  }
   257  
   258  static void test_sc_snap_name_validate__respects_error_protocol(void)
   259  {
   260  	if (g_test_subprocess()) {
   261  		sc_snap_name_validate("hello world", NULL);
   262  		g_test_message("expected sc_snap_name_validate to return");
   263  		g_test_fail();
   264  		return;
   265  	}
   266  	g_test_trap_subprocess(NULL, 0, 0);
   267  	g_test_trap_assert_failed();
   268  	g_test_trap_assert_stderr
   269  	    ("snap name must use lower case letters, digits or dashes\n");
   270  }
   271  
   272  static void test_sc_instance_name_validate(void)
   273  {
   274  	sc_error *err = NULL;
   275  
   276  	sc_instance_name_validate("hello-world", &err);
   277  	g_assert_null(err);
   278  	sc_instance_name_validate("hello-world_foo", &err);
   279  	g_assert_null(err);
   280  
   281  	// just the separator
   282  	sc_instance_name_validate("_", &err);
   283  	g_assert_nonnull(err);
   284  	g_assert_true(sc_error_match
   285  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   286  	g_assert_cmpstr(sc_error_msg(err), ==,
   287  			"snap name must contain at least one letter");
   288  	sc_error_free(err);
   289  
   290  	// just name, with separator, missing instance key
   291  	sc_instance_name_validate("hello-world_", &err);
   292  	g_assert_nonnull(err);
   293  	g_assert_true(sc_error_match
   294  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_KEY));
   295  	g_assert_cmpstr(sc_error_msg(err), ==,
   296  			"instance key must contain at least one letter or digit");
   297  	sc_error_free(err);
   298  
   299  	// only separator and instance key, missing name
   300  	sc_instance_name_validate("_bar", &err);
   301  	g_assert_nonnull(err);
   302  	g_assert_true(sc_error_match
   303  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   304  	g_assert_cmpstr(sc_error_msg(err), ==,
   305  			"snap name must contain at least one letter");
   306  	sc_error_free(err);
   307  
   308  	sc_instance_name_validate("", &err);
   309  	g_assert_nonnull(err);
   310  	g_assert_true(sc_error_match
   311  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_NAME));
   312  	g_assert_cmpstr(sc_error_msg(err), ==,
   313  			"snap name must contain at least one letter");
   314  	sc_error_free(err);
   315  
   316  	// third separator
   317  	sc_instance_name_validate("foo_bar_baz", &err);
   318  	g_assert_nonnull(err);
   319  	g_assert_true(sc_error_match
   320  		      (err, SC_SNAP_DOMAIN, SC_SNAP_INVALID_INSTANCE_NAME));
   321  	g_assert_cmpstr(sc_error_msg(err), ==,
   322  			"snap instance name can contain only one underscore");
   323  	sc_error_free(err);
   324  
   325  	const char *valid_names[] = {
   326  		"aa", "aaa", "aaaa",
   327  		"aa_a", "aa_1", "aa_123", "aa_0123456789",
   328  	};
   329  	for (size_t i = 0; i < sizeof valid_names / sizeof *valid_names; ++i) {
   330  		g_test_message("checking valid instance name: %s",
   331  			       valid_names[i]);
   332  		sc_instance_name_validate(valid_names[i], &err);
   333  		g_assert_null(err);
   334  	}
   335  	const char *invalid_names[] = {
   336  		// too short
   337  		"a",
   338  		// only letters and digits in the instance key
   339  		"a_--23))", "a_ ", "a_091234#", "a_123_456",
   340  		// up to 10 characters for the instance key
   341  		"a_01234567891", "a_0123456789123",
   342  		// snap name must not be more than 40 characters, regardless of instance
   343  		// key
   344  		"01234567890123456789012345678901234567890_foobar",
   345  		"01234567890123456789-01234567890123456789_foobar",
   346  		// instance key  must be plain ASCII
   347  		"foobar_日本語",
   348  		// way too many underscores
   349  		"foobar_baz_zed_daz",
   350  		"foobar______",
   351  	};
   352  	for (size_t i = 0; i < sizeof invalid_names / sizeof *invalid_names;
   353  	     ++i) {
   354  		g_test_message("checking invalid instance name: >%s<",
   355  			       invalid_names[i]);
   356  		sc_instance_name_validate(invalid_names[i], &err);
   357  		g_assert_nonnull(err);
   358  		sc_error_free(err);
   359  	}
   360  }
   361  
   362  static void test_sc_snap_drop_instance_key_no_dest(void)
   363  {
   364  	if (g_test_subprocess()) {
   365  		sc_snap_drop_instance_key("foo_bar", NULL, 0);
   366  		return;
   367  	}
   368  	g_test_trap_subprocess(NULL, 0, 0);
   369  	g_test_trap_assert_failed();
   370  
   371  }
   372  
   373  static void test_sc_snap_drop_instance_key_short_dest(void)
   374  {
   375  	if (g_test_subprocess()) {
   376  		char dest[10] = { 0 };
   377  		sc_snap_drop_instance_key("foo-foo-foo-foo-foo_bar", dest,
   378  					  sizeof dest);
   379  		return;
   380  	}
   381  	g_test_trap_subprocess(NULL, 0, 0);
   382  	g_test_trap_assert_failed();
   383  }
   384  
   385  static void test_sc_snap_drop_instance_key_short_dest2(void)
   386  {
   387  	if (g_test_subprocess()) {
   388  		char dest[3] = { 0 };	// "foo" sans the nil byte
   389  		sc_snap_drop_instance_key("foo", dest, sizeof dest);
   390  		return;
   391  	}
   392  	g_test_trap_subprocess(NULL, 0, 0);
   393  	g_test_trap_assert_failed();
   394  }
   395  
   396  static void test_sc_snap_drop_instance_key_no_name(void)
   397  {
   398  	if (g_test_subprocess()) {
   399  		char dest[10] = { 0 };
   400  		sc_snap_drop_instance_key(NULL, dest, sizeof dest);
   401  		return;
   402  	}
   403  	g_test_trap_subprocess(NULL, 0, 0);
   404  	g_test_trap_assert_failed();
   405  }
   406  
   407  static void test_sc_snap_drop_instance_key_short_dest_max(void)
   408  {
   409  	if (g_test_subprocess()) {
   410  		char dest[SNAP_NAME_LEN + 1] = { 0 };
   411  		/* 40 chars (max valid length), pretend dest is the same length, no space for terminator */
   412  		sc_snap_drop_instance_key
   413  		    ("01234567890123456789012345678901234567890", dest,
   414  		     sizeof dest - 1);
   415  		return;
   416  	}
   417  	g_test_trap_subprocess(NULL, 0, 0);
   418  	g_test_trap_assert_failed();
   419  }
   420  
   421  static void test_sc_snap_drop_instance_key_basic(void)
   422  {
   423  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   424  
   425  	sc_snap_drop_instance_key("foo_bar", name, sizeof name);
   426  	g_assert_cmpstr(name, ==, "foo");
   427  
   428  	memset(name, 0xff, sizeof name);
   429  	sc_snap_drop_instance_key("foo-bar_bar", name, sizeof name);
   430  	g_assert_cmpstr(name, ==, "foo-bar");
   431  
   432  	memset(name, 0xff, sizeof name);
   433  	sc_snap_drop_instance_key("foo-bar", name, sizeof name);
   434  	g_assert_cmpstr(name, ==, "foo-bar");
   435  
   436  	memset(name, 0xff, sizeof name);
   437  	sc_snap_drop_instance_key("_baz", name, sizeof name);
   438  	g_assert_cmpstr(name, ==, "");
   439  
   440  	memset(name, 0xff, sizeof name);
   441  	sc_snap_drop_instance_key("foo", name, sizeof name);
   442  	g_assert_cmpstr(name, ==, "foo");
   443  
   444  	memset(name, 0xff, sizeof name);
   445  	/* 40 chars - snap name length */
   446  	sc_snap_drop_instance_key("0123456789012345678901234567890123456789",
   447  				  name, sizeof name);
   448  	g_assert_cmpstr(name, ==, "0123456789012345678901234567890123456789");
   449  }
   450  
   451  static void test_sc_snap_split_instance_name_trailing_nil(void)
   452  {
   453  	if (g_test_subprocess()) {
   454  		char dest[3] = { 0 };
   455  		// pretend there is no place for trailing \0
   456  		sc_snap_split_instance_name("_", NULL, 0, dest, 0);
   457  		return;
   458  	}
   459  	g_test_trap_subprocess(NULL, 0, 0);
   460  	g_test_trap_assert_failed();
   461  }
   462  
   463  static void test_sc_snap_split_instance_name_short_instance_dest(void)
   464  {
   465  	if (g_test_subprocess()) {
   466  		char dest[10] = { 0 };
   467  		sc_snap_split_instance_name("foo_barbarbarbar", NULL, 0,
   468  					    dest, sizeof dest);
   469  		return;
   470  	}
   471  	g_test_trap_subprocess(NULL, 0, 0);
   472  	g_test_trap_assert_failed();
   473  }
   474  
   475  static void test_sc_snap_split_instance_name_basic(void)
   476  {
   477  	char name[SNAP_NAME_LEN + 1] = { 0xff };
   478  	char instance[20] = { 0xff };
   479  
   480  	sc_snap_split_instance_name("foo_bar", name, sizeof name, instance,
   481  				    sizeof instance);
   482  	g_assert_cmpstr(name, ==, "foo");
   483  	g_assert_cmpstr(instance, ==, "bar");
   484  
   485  	memset(name, 0xff, sizeof name);
   486  	memset(instance, 0xff, sizeof instance);
   487  	sc_snap_split_instance_name("foo-bar_bar", name, sizeof name, instance,
   488  				    sizeof instance);
   489  	g_assert_cmpstr(name, ==, "foo-bar");
   490  	g_assert_cmpstr(instance, ==, "bar");
   491  
   492  	memset(name, 0xff, sizeof name);
   493  	memset(instance, 0xff, sizeof instance);
   494  	sc_snap_split_instance_name("foo-bar", name, sizeof name, instance,
   495  				    sizeof instance);
   496  	g_assert_cmpstr(name, ==, "foo-bar");
   497  	g_assert_cmpstr(instance, ==, "");
   498  
   499  	memset(name, 0xff, sizeof name);
   500  	memset(instance, 0xff, sizeof instance);
   501  	sc_snap_split_instance_name("_baz", name, sizeof name, instance,
   502  				    sizeof instance);
   503  	g_assert_cmpstr(name, ==, "");
   504  	g_assert_cmpstr(instance, ==, "baz");
   505  
   506  	memset(name, 0xff, sizeof name);
   507  	memset(instance, 0xff, sizeof instance);
   508  	sc_snap_split_instance_name("foo", name, sizeof name, instance,
   509  				    sizeof instance);
   510  	g_assert_cmpstr(name, ==, "foo");
   511  	g_assert_cmpstr(instance, ==, "");
   512  
   513  	memset(name, 0xff, sizeof name);
   514  	sc_snap_split_instance_name("foo_bar", name, sizeof name, NULL, 0);
   515  	g_assert_cmpstr(name, ==, "foo");
   516  
   517  	memset(instance, 0xff, sizeof instance);
   518  	sc_snap_split_instance_name("foo_bar", NULL, 0, instance,
   519  				    sizeof instance);
   520  	g_assert_cmpstr(instance, ==, "bar");
   521  
   522  	memset(name, 0xff, sizeof name);
   523  	memset(instance, 0xff, sizeof instance);
   524  	sc_snap_split_instance_name("hello_world_surprise", name, sizeof name,
   525  				    instance, sizeof instance);
   526  	g_assert_cmpstr(name, ==, "hello");
   527  	g_assert_cmpstr(instance, ==, "world_surprise");
   528  
   529  	memset(name, 0xff, sizeof name);
   530  	memset(instance, 0xff, sizeof instance);
   531  	sc_snap_split_instance_name("", name, sizeof name, instance,
   532  				    sizeof instance);
   533  	g_assert_cmpstr(name, ==, "");
   534  	g_assert_cmpstr(instance, ==, "");
   535  
   536  	memset(name, 0xff, sizeof name);
   537  	memset(instance, 0xff, sizeof instance);
   538  	sc_snap_split_instance_name("_", name, sizeof name, instance,
   539  				    sizeof instance);
   540  	g_assert_cmpstr(name, ==, "");
   541  	g_assert_cmpstr(instance, ==, "");
   542  
   543  	memset(name, 0xff, sizeof name);
   544  	memset(instance, 0xff, sizeof instance);
   545  	sc_snap_split_instance_name("foo_", name, sizeof name, instance,
   546  				    sizeof instance);
   547  	g_assert_cmpstr(name, ==, "foo");
   548  	g_assert_cmpstr(instance, ==, "");
   549  }
   550  
   551  static void __attribute__((constructor)) init(void)
   552  {
   553  	g_test_add_func("/snap/verify_security_tag", test_verify_security_tag);
   554  	g_test_add_func("/snap/sc_is_hook_security_tag",
   555  			test_sc_is_hook_security_tag);
   556  
   557  	g_test_add_data_func("/snap/sc_snap_name_validate",
   558  			     sc_snap_name_validate,
   559  			     test_sc_snap_or_instance_name_validate);
   560  	g_test_add_func("/snap/sc_snap_name_validate/respects_error_protocol",
   561  			test_sc_snap_name_validate__respects_error_protocol);
   562  
   563  	g_test_add_data_func("/snap/sc_instance_name_validate/just_name",
   564  			     sc_instance_name_validate,
   565  			     test_sc_snap_or_instance_name_validate);
   566  	g_test_add_func("/snap/sc_instance_name_validate/full",
   567  			test_sc_instance_name_validate);
   568  
   569  	g_test_add_func("/snap/sc_snap_drop_instance_key/basic",
   570  			test_sc_snap_drop_instance_key_basic);
   571  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_dest",
   572  			test_sc_snap_drop_instance_key_no_dest);
   573  	g_test_add_func("/snap/sc_snap_drop_instance_key/no_name",
   574  			test_sc_snap_drop_instance_key_no_name);
   575  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest",
   576  			test_sc_snap_drop_instance_key_short_dest);
   577  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest2",
   578  			test_sc_snap_drop_instance_key_short_dest2);
   579  	g_test_add_func("/snap/sc_snap_drop_instance_key/short_dest_max",
   580  			test_sc_snap_drop_instance_key_short_dest_max);
   581  
   582  	g_test_add_func("/snap/sc_snap_split_instance_name/basic",
   583  			test_sc_snap_split_instance_name_basic);
   584  	g_test_add_func("/snap/sc_snap_split_instance_name/trailing_nil",
   585  			test_sc_snap_split_instance_name_trailing_nil);
   586  	g_test_add_func("/snap/sc_snap_split_instance_name/short_instance_dest",
   587  			test_sc_snap_split_instance_name_short_instance_dest);
   588  }